<commit_before>#include <algorithm>
#include <vector>

#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>

#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/protozero/field.h"
#include "perfetto/protozero/proto_decoder.h"
#include "perfetto/protozero/proto_utils.h"
#include "third_party/pprof/profile.pb.h"

namespace perfetto {
namespace protoprofile {
namespace {

using protozero::proto_utils::ProtoWireType;
using GLine = ::perftools::profiles::Line;
using GMapping = ::perftools::profiles::Mapping;
using GLocation = ::perftools::profiles::Location;
using GProfile = ::perftools::profiles::Profile;
using GValueType = ::perftools::profiles::ValueType;
using GFunction = ::perftools::profiles::Function;
using GSample = ::perftools::profiles::Sample;
using ::google::protobuf::Descriptor;
using ::google::protobuf::DynamicMessageFactory;
using ::google::protobuf::FieldDescriptor;
using ::google::protobuf::FileDescriptor;
using ::google::protobuf::Message;
using ::google::protobuf::compiler::DiskSourceTree;
using ::google::protobuf::compiler::Importer;
using ::google::protobuf::compiler::MultiFileErrorCollector;

class MultiFileErrorCollectorImpl : public MultiFileErrorCollector {
 public:
  ~MultiFileErrorCollectorImpl() override;
  void AddError(const std::string& filename,
                int line,
                int column,
                const std::string& message) override;

  void AddWarning(const std::string& filename,
                  int line,
                  int column,
                  const std::string& message) override;
};

MultiFileErrorCollectorImpl::~MultiFileErrorCollectorImpl() = default;

void MultiFileErrorCollectorImpl::AddError(const std::string& filename,
                                           int line,
                                           int column,
                                           const std::string& message) {
  PERFETTO_ELOG("Error %s %d:%d: %s", filename.c_str(), line, column,
                message.c_str());
}

void MultiFileErrorCollectorImpl::AddWarning(const std::string& filename,
                                             int line,
                                             int column,
                                             const std::string& message) {
  PERFETTO_ELOG("Error %s %d:%d: %s", filename.c_str(), line, column,
                message.c_str());
}

class SizeProfileComputer {
 public:
  GProfile Compute(const uint8_t* ptr,
                   size_t size,
                   const Descriptor* descriptor);

 private:
  struct StackInfo {
    std::vector<size_t> samples;
    std::vector<int> locations;
  };

  void ComputeInner(const uint8_t* ptr,
                    size_t size,
                    const Descriptor* descriptor);
  void Sample(size_t size);
  int InternString(const std::string& str);
  int InternLocation(const std::string& str);
  size_t GetFieldSize(const protozero::Field& f);

  // Convert the current stack into a string:
  // {"Foo", "#bar", "Bar", "#baz", "int"} -> "Foo$#bar$Bar$#baz$int$"
  std::string StackToKey();

  // The current 'stack' we're considering as we parse the protobuf.
  // For example if we're currently looking at the varint field baz which is
  // nested inside message Bar which is in turn a field named bar on the message
  // Foo. Then the stack would be: Foo, #bar, Bar, #baz, int
  // We keep track of both the field names (#bar, #baz) and the field types
  // (Foo, Bar, int) as sometimes we are intrested in which fields are big
  // and sometimes which types are big.
  std::vector<std::string> stack_;

  // Information about each stack seen. Keyed by a unique string for each stack.
  std::map<std::string, StackInfo> stack_info_;

  // Interned strings:
  std::vector<std::string> strings_;
  std::map<std::string, int> string_to_id_;

  // Interned 'locations', each location is a single frame of the stack.
  std::map<std::string, int> locations_;
};

size_t SizeProfileComputer::GetFieldSize(const protozero::Field& f) {
  uint8_t buf[10];
  switch (f.type()) {
    case protozero::proto_utils::ProtoWireType::kVarInt:
      return static_cast<size_t>(
          protozero::proto_utils::WriteVarInt(f.as_uint64(), buf) - buf);
    case protozero::proto_utils::ProtoWireType::kLengthDelimited:
      return f.size();
    case protozero::proto_utils::ProtoWireType::kFixed32:
      return 4;
    case protozero::proto_utils::ProtoWireType::kFixed64:
      return 8;
  }
}

int SizeProfileComputer::InternString(const std::string& s) {
  if (string_to_id_.count(s)) {
    return string_to_id_[s];
  }
  strings_.push_back(s);
  int id = static_cast<int>(strings_.size() - 1);
  string_to_id_[s] = id;
  return id;
}

int SizeProfileComputer::InternLocation(const std::string& s) {
  if (locations_.count(s)) {
    return locations_[s];
  }
  int id = static_cast<int>(locations_.size()) + 1;
  locations_[s] = id;
  return id;
}

std::string SizeProfileComputer::StackToKey() {
  std::string key;
  for (const std::string& part : stack_) {
    key += part;
    key += "$";
  }
  return key;
}

void SizeProfileComputer::Sample(size_t size) {
  const std::string& key = StackToKey();

  if (!stack_info_.count(key)) {
    StackInfo& info = stack_info_[key];
    info.locations.resize(stack_.size());
    for (size_t i = 0; i < stack_.size(); i++) {
      info.locations[i] = InternLocation(stack_[i]);
    }
  }

  stack_info_[key].samples.push_back(size);
}

GProfile SizeProfileComputer::Compute(const uint8_t* ptr,
                                      size_t size,
                                      const Descriptor* descriptor) {
  PERFETTO_CHECK(InternString("") == 0);
  ComputeInner(ptr, size, descriptor);
  GProfile profile;

  GValueType* sample_type;

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("protos"));
  sample_type->set_unit(InternString("count"));

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("max_size"));
  sample_type->set_unit(InternString("bytes"));

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("min_size"));
  sample_type->set_unit(InternString("bytes"));

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("median"));
  sample_type->set_unit(InternString("bytes"));

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("total_size"));
  sample_type->set_unit(InternString("bytes"));

  // For each unique stack we've seen write out the stats:
  for (auto& id_info : stack_info_) {
    StackInfo& info = id_info.second;

    GSample* sample = profile.add_sample();
    for (auto it = info.locations.rbegin(); it != info.locations.rend(); ++it) {
      sample->add_location_id(static_cast<uint64_t>(*it));
    }

    std::sort(info.samples.begin(), info.samples.end());
    size_t count = info.samples.size();
    size_t total_size = 0;
    size_t max_size = info.samples[count - 1];
    size_t min_size = info.samples[0];
    size_t median_size = info.samples[count / 2];
    for (size_t i = 0; i < count; ++i)
      total_size += info.samples[i];
    // These have to be in the same order as the sample types above:
    sample->add_value(static_cast<int64_t>(count));
    sample->add_value(static_cast<int64_t>(max_size));
    sample->add_value(static_cast<int64_t>(min_size));
    sample->add_value(static_cast<int64_t>(median_size));
    sample->add_value(static_cast<int64_t>(total_size));
  }

  // The proto profile has a two step mapping where samples are associated with
  // locations which in turn are associated to functions. We don't currently
  // distinguish them so we make a 1:1 mapping between the locations and the
  // functions:
  for (const auto& location_id : locations_) {
    GLocation* location = profile.add_location();
    location->set_id(static_cast<uint64_t>(location_id.second));
    GLine* line = location->add_line();
    line->set_function_id(static_cast<uint64_t>(location_id.second));
  }

  for (const auto& location_id : locations_) {
    GFunction* function = profile.add_function();
    function->set_id(static_cast<uint64_t>(location_id.second));
    function->set_name(InternString(location_id.first));
  }

  // Finally the string table. We intern more strings above, so this has to be
  // last.
  for (int i = 0; i < static_cast<int>(strings_.size()); i++) {
    profile.add_string_table(strings_[static_cast<size_t>(i)]);
  }
  return profile;
}

void SizeProfileComputer::ComputeInner(const uint8_t* ptr,
                                       size_t size,
                                       const Descriptor* descriptor) {
  size_t overhead = size;
  size_t unknown = 0;
  protozero::ProtoDecoder decoder(ptr, size);

  stack_.push_back(descriptor->name());

  // Compute the size of each sub-field of this message, subtracting it
  // from overhead and possible adding it to unknown.
  for (;;) {
    if (decoder.bytes_left() == 0)
      break;
    protozero::Field field = decoder.ReadField();
    if (!field.valid()) {
      PERFETTO_ELOG("Field not valid (can mean field id >1000)");
      break;
    }

    int id = field.id();
    ProtoWireType type = field.type();
    size_t field_size = GetFieldSize(field);

    overhead -= field_size;
    const FieldDescriptor* field_descriptor = descriptor->FindFieldByNumber(id);
    if (!field_descriptor) {
      unknown += field_size;
      continue;
    }

    stack_.push_back("#" + field_descriptor->name());
    bool is_message_type =
        field_descriptor->type() == FieldDescriptor::TYPE_MESSAGE;
    if (type == ProtoWireType::kLengthDelimited && is_message_type) {
      ComputeInner(field.data(), field.size(),
                   field_descriptor->message_type());
    } else {
      stack_.push_back(field_descriptor->type_name());
      Sample(field_size);
      stack_.pop_back();
    }
    stack_.pop_back();
  }

  if (unknown) {
    stack_.push_back("#:unknown:");
    Sample(unknown);
    stack_.pop_back();
  }

  // Anything not blamed on a child is overhead for this message.
  Sample(overhead);
  stack_.pop_back();
}

int PrintUsage(int, const char** argv) {
  fprintf(stderr, "Usage: %s INPUT_PATH OUTPUT_PATH\n", argv[0]);
  return 1;
}

int Main(int argc, const char** argv) {
  if (argc != 3)
    return PrintUsage(argc, argv);

  const char* input_path = argv[1];
  const char* output_path = argv[2];

  base::ScopedFile proto_fd = base::OpenFile(input_path, O_RDONLY);
  if (!proto_fd) {
    PERFETTO_ELOG("Could not open input path (%s)", input_path);
    return 1;
  }

  std::string s;
  base::ReadFileDescriptor(proto_fd.get(), &s);

  const Descriptor* descriptor;
  DiskSourceTree dst;
  dst.MapPath("perfetto", "protos/perfetto");
  MultiFileErrorCollectorImpl mfe;
  Importer importer(&dst, &mfe);
  const FileDescriptor* parsed_file =
      importer.Import("perfetto/trace/trace.proto");
  DynamicMessageFactory dmf;
  descriptor = parsed_file->message_type(0);

  const uint8_t* start = reinterpret_cast<const uint8_t*>(s.data());
  size_t size = s.size();

  if (!descriptor) {
    PERFETTO_ELOG("Could not parse trace.proto");
    return 1;
  }

  base::ScopedFile output_fd =
      base::OpenFile(output_path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
  if (!output_fd) {
    PERFETTO_ELOG("Could not open output path (%s)", output_path);
    return 1;
  }
  SizeProfileComputer computer;
  GProfile profile = computer.Compute(start, size, descriptor);
  std::string out;
  profile.SerializeToString(&out);
  base::WriteAll(output_fd.get(), out.data(), out.size());
  base::FlushFile(output_fd.get());

  return 0;
}

}  // namespace
}  // namespace protoprofile
}  // namespace perfetto

int main(int argc, const char** argv) {
  return perfetto::protoprofile::Main(argc, argv);
}
<commit_msg>gcc build fix for protoprofile switch am: da87520b03 am: b5f047a935 am: bc22c10f80 am: 915f4f352a<commit_after>#include <algorithm>
#include <vector>

#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>

#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/protozero/field.h"
#include "perfetto/protozero/proto_decoder.h"
#include "perfetto/protozero/proto_utils.h"
#include "third_party/pprof/profile.pb.h"

namespace perfetto {
namespace protoprofile {
namespace {

using protozero::proto_utils::ProtoWireType;
using GLine = ::perftools::profiles::Line;
using GMapping = ::perftools::profiles::Mapping;
using GLocation = ::perftools::profiles::Location;
using GProfile = ::perftools::profiles::Profile;
using GValueType = ::perftools::profiles::ValueType;
using GFunction = ::perftools::profiles::Function;
using GSample = ::perftools::profiles::Sample;
using ::google::protobuf::Descriptor;
using ::google::protobuf::DynamicMessageFactory;
using ::google::protobuf::FieldDescriptor;
using ::google::protobuf::FileDescriptor;
using ::google::protobuf::Message;
using ::google::protobuf::compiler::DiskSourceTree;
using ::google::protobuf::compiler::Importer;
using ::google::protobuf::compiler::MultiFileErrorCollector;

class MultiFileErrorCollectorImpl : public MultiFileErrorCollector {
 public:
  ~MultiFileErrorCollectorImpl() override;
  void AddError(const std::string& filename,
                int line,
                int column,
                const std::string& message) override;

  void AddWarning(const std::string& filename,
                  int line,
                  int column,
                  const std::string& message) override;
};

MultiFileErrorCollectorImpl::~MultiFileErrorCollectorImpl() = default;

void MultiFileErrorCollectorImpl::AddError(const std::string& filename,
                                           int line,
                                           int column,
                                           const std::string& message) {
  PERFETTO_ELOG("Error %s %d:%d: %s", filename.c_str(), line, column,
                message.c_str());
}

void MultiFileErrorCollectorImpl::AddWarning(const std::string& filename,
                                             int line,
                                             int column,
                                             const std::string& message) {
  PERFETTO_ELOG("Error %s %d:%d: %s", filename.c_str(), line, column,
                message.c_str());
}

class SizeProfileComputer {
 public:
  GProfile Compute(const uint8_t* ptr,
                   size_t size,
                   const Descriptor* descriptor);

 private:
  struct StackInfo {
    std::vector<size_t> samples;
    std::vector<int> locations;
  };

  void ComputeInner(const uint8_t* ptr,
                    size_t size,
                    const Descriptor* descriptor);
  void Sample(size_t size);
  int InternString(const std::string& str);
  int InternLocation(const std::string& str);
  size_t GetFieldSize(const protozero::Field& f);

  // Convert the current stack into a string:
  // {"Foo", "#bar", "Bar", "#baz", "int"} -> "Foo$#bar$Bar$#baz$int$"
  std::string StackToKey();

  // The current 'stack' we're considering as we parse the protobuf.
  // For example if we're currently looking at the varint field baz which is
  // nested inside message Bar which is in turn a field named bar on the message
  // Foo. Then the stack would be: Foo, #bar, Bar, #baz, int
  // We keep track of both the field names (#bar, #baz) and the field types
  // (Foo, Bar, int) as sometimes we are intrested in which fields are big
  // and sometimes which types are big.
  std::vector<std::string> stack_;

  // Information about each stack seen. Keyed by a unique string for each stack.
  std::map<std::string, StackInfo> stack_info_;

  // Interned strings:
  std::vector<std::string> strings_;
  std::map<std::string, int> string_to_id_;

  // Interned 'locations', each location is a single frame of the stack.
  std::map<std::string, int> locations_;
};

size_t SizeProfileComputer::GetFieldSize(const protozero::Field& f) {
  uint8_t buf[10];
  switch (f.type()) {
    case protozero::proto_utils::ProtoWireType::kVarInt:
      return static_cast<size_t>(
          protozero::proto_utils::WriteVarInt(f.as_uint64(), buf) - buf);
    case protozero::proto_utils::ProtoWireType::kLengthDelimited:
      return f.size();
    case protozero::proto_utils::ProtoWireType::kFixed32:
      return 4;
    case protozero::proto_utils::ProtoWireType::kFixed64:
      return 8;
  }
  PERFETTO_FATAL("unexpected field type");  // for gcc
}

int SizeProfileComputer::InternString(const std::string& s) {
  if (string_to_id_.count(s)) {
    return string_to_id_[s];
  }
  strings_.push_back(s);
  int id = static_cast<int>(strings_.size() - 1);
  string_to_id_[s] = id;
  return id;
}

int SizeProfileComputer::InternLocation(const std::string& s) {
  if (locations_.count(s)) {
    return locations_[s];
  }
  int id = static_cast<int>(locations_.size()) + 1;
  locations_[s] = id;
  return id;
}

std::string SizeProfileComputer::StackToKey() {
  std::string key;
  for (const std::string& part : stack_) {
    key += part;
    key += "$";
  }
  return key;
}

void SizeProfileComputer::Sample(size_t size) {
  const std::string& key = StackToKey();

  if (!stack_info_.count(key)) {
    StackInfo& info = stack_info_[key];
    info.locations.resize(stack_.size());
    for (size_t i = 0; i < stack_.size(); i++) {
      info.locations[i] = InternLocation(stack_[i]);
    }
  }

  stack_info_[key].samples.push_back(size);
}

GProfile SizeProfileComputer::Compute(const uint8_t* ptr,
                                      size_t size,
                                      const Descriptor* descriptor) {
  PERFETTO_CHECK(InternString("") == 0);
  ComputeInner(ptr, size, descriptor);
  GProfile profile;

  GValueType* sample_type;

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("protos"));
  sample_type->set_unit(InternString("count"));

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("max_size"));
  sample_type->set_unit(InternString("bytes"));

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("min_size"));
  sample_type->set_unit(InternString("bytes"));

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("median"));
  sample_type->set_unit(InternString("bytes"));

  sample_type = profile.add_sample_type();
  sample_type->set_type(InternString("total_size"));
  sample_type->set_unit(InternString("bytes"));

  // For each unique stack we've seen write out the stats:
  for (auto& id_info : stack_info_) {
    StackInfo& info = id_info.second;

    GSample* sample = profile.add_sample();
    for (auto it = info.locations.rbegin(); it != info.locations.rend(); ++it) {
      sample->add_location_id(static_cast<uint64_t>(*it));
    }

    std::sort(info.samples.begin(), info.samples.end());
    size_t count = info.samples.size();
    size_t total_size = 0;
    size_t max_size = info.samples[count - 1];
    size_t min_size = info.samples[0];
    size_t median_size = info.samples[count / 2];
    for (size_t i = 0; i < count; ++i)
      total_size += info.samples[i];
    // These have to be in the same order as the sample types above:
    sample->add_value(static_cast<int64_t>(count));
    sample->add_value(static_cast<int64_t>(max_size));
    sample->add_value(static_cast<int64_t>(min_size));
    sample->add_value(static_cast<int64_t>(median_size));
    sample->add_value(static_cast<int64_t>(total_size));
  }

  // The proto profile has a two step mapping where samples are associated with
  // locations which in turn are associated to functions. We don't currently
  // distinguish them so we make a 1:1 mapping between the locations and the
  // functions:
  for (const auto& location_id : locations_) {
    GLocation* location = profile.add_location();
    location->set_id(static_cast<uint64_t>(location_id.second));
    GLine* line = location->add_line();
    line->set_function_id(static_cast<uint64_t>(location_id.second));
  }

  for (const auto& location_id : locations_) {
    GFunction* function = profile.add_function();
    function->set_id(static_cast<uint64_t>(location_id.second));
    function->set_name(InternString(location_id.first));
  }

  // Finally the string table. We intern more strings above, so this has to be
  // last.
  for (int i = 0; i < static_cast<int>(strings_.size()); i++) {
    profile.add_string_table(strings_[static_cast<size_t>(i)]);
  }
  return profile;
}

void SizeProfileComputer::ComputeInner(const uint8_t* ptr,
                                       size_t size,
                                       const Descriptor* descriptor) {
  size_t overhead = size;
  size_t unknown = 0;
  protozero::ProtoDecoder decoder(ptr, size);

  stack_.push_back(descriptor->name());

  // Compute the size of each sub-field of this message, subtracting it
  // from overhead and possible adding it to unknown.
  for (;;) {
    if (decoder.bytes_left() == 0)
      break;
    protozero::Field field = decoder.ReadField();
    if (!field.valid()) {
      PERFETTO_ELOG("Field not valid (can mean field id >1000)");
      break;
    }

    int id = field.id();
    ProtoWireType type = field.type();
    size_t field_size = GetFieldSize(field);

    overhead -= field_size;
    const FieldDescriptor* field_descriptor = descriptor->FindFieldByNumber(id);
    if (!field_descriptor) {
      unknown += field_size;
      continue;
    }

    stack_.push_back("#" + field_descriptor->name());
    bool is_message_type =
        field_descriptor->type() == FieldDescriptor::TYPE_MESSAGE;
    if (type == ProtoWireType::kLengthDelimited && is_message_type) {
      ComputeInner(field.data(), field.size(),
                   field_descriptor->message_type());
    } else {
      stack_.push_back(field_descriptor->type_name());
      Sample(field_size);
      stack_.pop_back();
    }
    stack_.pop_back();
  }

  if (unknown) {
    stack_.push_back("#:unknown:");
    Sample(unknown);
    stack_.pop_back();
  }

  // Anything not blamed on a child is overhead for this message.
  Sample(overhead);
  stack_.pop_back();
}

int PrintUsage(int, const char** argv) {
  fprintf(stderr, "Usage: %s INPUT_PATH OUTPUT_PATH\n", argv[0]);
  return 1;
}

int Main(int argc, const char** argv) {
  if (argc != 3)
    return PrintUsage(argc, argv);

  const char* input_path = argv[1];
  const char* output_path = argv[2];

  base::ScopedFile proto_fd = base::OpenFile(input_path, O_RDONLY);
  if (!proto_fd) {
    PERFETTO_ELOG("Could not open input path (%s)", input_path);
    return 1;
  }

  std::string s;
  base::ReadFileDescriptor(proto_fd.get(), &s);

  const Descriptor* descriptor;
  DiskSourceTree dst;
  dst.MapPath("perfetto", "protos/perfetto");
  MultiFileErrorCollectorImpl mfe;
  Importer importer(&dst, &mfe);
  const FileDescriptor* parsed_file =
      importer.Import("perfetto/trace/trace.proto");
  DynamicMessageFactory dmf;
  descriptor = parsed_file->message_type(0);

  const uint8_t* start = reinterpret_cast<const uint8_t*>(s.data());
  size_t size = s.size();

  if (!descriptor) {
    PERFETTO_ELOG("Could not parse trace.proto");
    return 1;
  }

  base::ScopedFile output_fd =
      base::OpenFile(output_path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
  if (!output_fd) {
    PERFETTO_ELOG("Could not open output path (%s)", output_path);
    return 1;
  }
  SizeProfileComputer computer;
  GProfile profile = computer.Compute(start, size, descriptor);
  std::string out;
  profile.SerializeToString(&out);
  base::WriteAll(output_fd.get(), out.data(), out.size());
  base::FlushFile(output_fd.get());

  return 0;
}

}  // namespace
}  // namespace protoprofile
}  // namespace perfetto

int main(int argc, const char** argv) {
  return perfetto::protoprofile::Main(argc, argv);
}
<|endoftext|>


<commit_before>// hello.cc

#include <node.h>
#include "sql/api.h"
#include "string"
#include <unordered_set>

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
using v8::Number;
using v8::Array;

using namespace std;

void Exchange(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  cout<<"Number of args: "<<args.Length()<<endl;

  if (args.Length() != 1) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong number of arguments"));
    return;
  }

  if (!args[0]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param1(args[0]->ToString());
  std::string id = std::string(*param1);

  cout<<"Hello World!"<<endl;

  API *db = new API();
  int retVal = db->connect();
  if(retVal != 0){
    cout<<"db.connect() failed with exit code "<<retVal<<endl;
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Failed to connect to database"));
    return;
  }

  unordered_map<std::string, double> *rows = db->selectExchangeWithID(id);

  int i = 0;

  Local<Array> result = Array::New(isolate);

  for(unordered_map<std::string, double>::iterator itr = rows->begin(); itr != rows->end(); itr++, i++){
    cout<< itr->first << "\t" << itr->second << endl;

    // Creates a new Object on the V8 heap
    Local<Object> obj = Object::New(isolate);

    //Can call a pack function here to be cleaner once more data
    // Transfers the data from result, to obj (see below)
    obj->Set(String::NewFromUtf8(isolate, "id"),
	     String::NewFromUtf8(isolate, itr->first.data()));
    obj->Set(String::NewFromUtf8(isolate, "close"),
	     Number::New(isolate, itr->second));

    result->Set(i, obj);
  }

  args.GetReturnValue().Set(result);
  //args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));

  delete db;
}

void Table(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  cout<<"Number of args: "<<args.Length()<<endl;

  if (args.Length() != 1) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong number of arguments"));
    return;
  }

  if (!args[0]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param1(args[0]->ToString());
  std::string tableName = std::string(*param1);

  //TODO: move this to init
  API *db = new API();
  int retVal = db->connect();
  if(retVal != 0){
    cout<<"db.connect() failed with exit code "<<retVal<<endl;
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Failed to connect to database"));
    return;
  }

  unordered_map<std::string, double> *rows = db->selectAllFromTable(tableName);

  int i = 0;

  Local<Array> result = Array::New(isolate);

  for(unordered_map<std::string, double>::iterator itr = rows->begin(); itr != rows->end(); itr++, i++){
    cout<< itr->first << "\t" << itr->second << endl;

    // Creates a new Object on the V8 heap
    Local<Object> obj = Object::New(isolate);

    //Can call a pack function here to be cleaner once more data
    // Transfers the data from result, to obj (see below)
    obj->Set(String::NewFromUtf8(isolate, "id"),
	     String::NewFromUtf8(isolate, itr->first.data()));
    obj->Set(String::NewFromUtf8(isolate, "close"),
	     Number::New(isolate, itr->second));

    result->Set(i, obj);
  }

  args.GetReturnValue().Set(result);
  //args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));

  delete db;
}

void TickerData(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  cout<<"Number of args: "<<args.Length()<<endl;

  if (args.Length() != 0) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong number of arguments"));
    return;
  }

  //TODO: move this to init
  API *db = new API();
  int retVal = db->connect();
  if(retVal != 0){
    cout<<"db.connect() failed with exit code "<<retVal<<endl;
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Failed to connect to database"));
    return;
  }

  unordered_set<std::string> majorTickers ({
    "USDCAD=X", "EURJPY=X"
    "EURUSD=X", "EURCHF=X",
    "USDCHF=X", "EURGBP=X",
    "GBPUSD=X", "AUDCAD=X",
    "NZDUSD=X", "GBPCHF=X",
    "AUDUSD=X", "GBPJPY=X",
    "USDJPY=X", "CHFJPY=X",
    "EURCAD=X", "AUDJPY=X",
    "EURAUD=X", "AUDNZD=X"
  });

  unordered_map<std::string, double> *rows = db->selectAllTickerData();   //Get data

  int i = 0;

  Local<Array> result = Array::New(isolate);    //JSON results Array

  //Loop through C++ hashmap
  for(unordered_map<std::string, double>::iterator itr = rows->begin(); itr != rows->end(); itr++){
    cout<< itr->first << "\t" << itr->second << endl;

    // Add to return array if it is a major ticker
    if (majorTickers.find(itr->first) != majorTickers.end()){

      // Creates a new JSON Object on the V8 heap
      Local<Object> obj = Object::New(isolate);

      //Can call a pack function here to be cleaner once more data
      // Transfers the data from result, to obj (see below)
      obj->Set(String::NewFromUtf8(isolate, "ticker"),
         String::NewFromUtf8(isolate, itr->first.data()));
      obj->Set(String::NewFromUtf8(isolate, "percentChange"),
         Number::New(isolate, itr->second));

      result->Set(i, obj);

      i++;
    }
  }

  args.GetReturnValue().Set(result);
  //args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));

  delete db;
}

void ChartData(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  cout<<"Number of args: "<<args.Length()<<endl;

  //Make sure 2 arguments.  Cast to string
  if (args.Length() != 2) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong number of arguments"));
    return;
  }

  if (!args[0]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param1(args[0]->ToString());
  std::string ticker = std::string(*param1);

  if (!args[1]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param2(args[1]->ToString());
  std::string timeframe = std::string(*param2);

  //TODO: move this to init
  API *db = new API();
  int retVal = db->connect();
  if(retVal != 0){
    cout<<"db.connect() failed with exit code "<<retVal<<endl;
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Failed to connect to database"));
    return;
  }

  string interval = "day";
  long startDate = 1450000000;
  long endDate = 1490064000;
  vector<API::chart_info> *rows = db->selectHistoricalTickerData(ticker, interval,startDate,endDate);    //Database query
  //unordered_map<std::string, double> *rows = db->selectHistoricalTickerData(ticker, interval);   //Database query
//TODO change data structure to array of struct

  int i = 0;

  Local<Array> result = Array::New(isolate);

  for(vector<API::chart_info>::iterator itr = rows->begin(); itr != rows->end(); itr++, i++){
    cout << itr->timestamp << "\t" << itr->ticker << "\t" << itr->high << "\t" << itr->volume << "\t"
          << itr->open << "\t" << itr->low << "\t" << itr->close << endl;

    // Creates a new Object on the V8 heap
    Local<Object> obj = Object::New(isolate);

    //Can call a pack function here to be cleaner once more data
    // Transfers the data from result, to obj (see below)
    obj->Set(String::NewFromUtf8(isolate, "date"),
       Number::New(isolate, itr->timestamp));
    obj->Set(String::NewFromUtf8(isolate, "ticker"),
       String::NewFromUtf8(isolate, itr->ticker.data()));
    obj->Set(String::NewFromUtf8(isolate, "high"),
       Number::New(isolate, itr->high));
    obj->Set(String::NewFromUtf8(isolate, "volume"),
       Number::New(isolate, itr->volume));
    obj->Set(String::NewFromUtf8(isolate, "open"),
       Number::New(isolate, itr->open));
    obj->Set(String::NewFromUtf8(isolate, "low"),
       Number::New(isolate, itr->low));
    obj->Set(String::NewFromUtf8(isolate, "close"),
       Number::New(isolate, itr->close));

    result->Set(i, obj);
  }

  args.GetReturnValue().Set(result);
  //args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));

  delete db;
}

void init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "exchange", Exchange);
  NODE_SET_METHOD(exports, "table", Table);
  NODE_SET_METHOD(exports, "tickerData", TickerData);
  NODE_SET_METHOD(exports, "chartData", ChartData);
}

NODE_MODULE(addon, init)

}  // namespace demo
<commit_msg>query arb<commit_after>// hello.cc

#include <node.h>
#include "sql/api.h"
#include "string"
#include <unordered_set>

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
using v8::Number;
using v8::Array;

using namespace std;

void Exchange(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  cout<<"Number of args: "<<args.Length()<<endl;

  if (args.Length() != 1) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong number of arguments"));
    return;
  }

  if (!args[0]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param1(args[0]->ToString());
  std::string id = std::string(*param1);

  cout<<"Hello World!"<<endl;

  API *db = new API();
  int retVal = db->connect();
  if(retVal != 0){
    cout<<"db.connect() failed with exit code "<<retVal<<endl;
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Failed to connect to database"));
    return;
  }

  unordered_map<std::string, double> *rows = db->selectExchangeWithID(id);

  int i = 0;

  Local<Array> result = Array::New(isolate);

  for(unordered_map<std::string, double>::iterator itr = rows->begin(); itr != rows->end(); itr++, i++){
    cout<< itr->first << "\t" << itr->second << endl;

    // Creates a new Object on the V8 heap
    Local<Object> obj = Object::New(isolate);

    //Can call a pack function here to be cleaner once more data
    // Transfers the data from result, to obj (see below)
    obj->Set(String::NewFromUtf8(isolate, "id"),
	     String::NewFromUtf8(isolate, itr->first.data()));
    obj->Set(String::NewFromUtf8(isolate, "close"),
	     Number::New(isolate, itr->second));

    result->Set(i, obj);
  }

  args.GetReturnValue().Set(result);
  //args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));

  delete db;
}

void Table(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  cout<<"Number of args: "<<args.Length()<<endl;

  if (args.Length() != 1) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong number of arguments"));
    return;
  }

  if (!args[0]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param1(args[0]->ToString());
  std::string tableName = std::string(*param1);

  //TODO: move this to init
  API *db = new API();
  int retVal = db->connect();
  if(retVal != 0){
    cout<<"db.connect() failed with exit code "<<retVal<<endl;
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Failed to connect to database"));
    return;
  }

  unordered_map<std::string, double> *rows = db->selectAllFromTable(tableName);

  int i = 0;

  Local<Array> result = Array::New(isolate);

  for(unordered_map<std::string, double>::iterator itr = rows->begin(); itr != rows->end(); itr++, i++){
    cout<< itr->first << "\t" << itr->second << endl;

    // Creates a new Object on the V8 heap
    Local<Object> obj = Object::New(isolate);

    //Can call a pack function here to be cleaner once more data
    // Transfers the data from result, to obj (see below)
    obj->Set(String::NewFromUtf8(isolate, "id"),
	     String::NewFromUtf8(isolate, itr->first.data()));
    obj->Set(String::NewFromUtf8(isolate, "close"),
	     Number::New(isolate, itr->second));

    result->Set(i, obj);
  }

  args.GetReturnValue().Set(result);
  //args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));

  delete db;
}

void TickerData(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  cout<<"Number of args: "<<args.Length()<<endl;

  if (args.Length() != 0) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong number of arguments"));
    return;
  }

  //TODO: move this to init
  API *db = new API();
  int retVal = db->connect();
  if(retVal != 0){
    cout<<"db.connect() failed with exit code "<<retVal<<endl;
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Failed to connect to database"));
    return;
  }

  unordered_set<std::string> majorTickers ({
    "USDCAD=X", "EURJPY=X"
    "EURUSD=X", "EURCHF=X",
    "USDCHF=X", "EURGBP=X",
    "GBPUSD=X", "AUDCAD=X",
    "NZDUSD=X", "GBPCHF=X",
    "AUDUSD=X", "GBPJPY=X",
    "USDJPY=X", "CHFJPY=X",
    "EURCAD=X", "AUDJPY=X",
    "EURAUD=X", "AUDNZD=X"
  });

  unordered_map<std::string, double> *rows = db->selectAllTickerData();   //Get data

  int i = 0;

  Local<Array> result = Array::New(isolate);    //JSON results Array

  //Loop through C++ hashmap
  for(unordered_map<std::string, double>::iterator itr = rows->begin(); itr != rows->end(); itr++){
    cout<< itr->first << "\t" << itr->second << endl;

    // Add to return array if it is a major ticker
    if (majorTickers.find(itr->first) != majorTickers.end()){

      // Creates a new JSON Object on the V8 heap
      Local<Object> obj = Object::New(isolate);

      //Can call a pack function here to be cleaner once more data
      // Transfers the data from result, to obj (see below)
      obj->Set(String::NewFromUtf8(isolate, "ticker"),
         String::NewFromUtf8(isolate, itr->first.data()));
      obj->Set(String::NewFromUtf8(isolate, "percentChange"),
         Number::New(isolate, itr->second));

      result->Set(i, obj);

      i++;
    }
  }

  args.GetReturnValue().Set(result);
  //args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));

  delete db;
}

void ChartData(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  cout<<"Number of args: "<<args.Length()<<endl;

  //Make sure 2 arguments.  Cast to string
  if (args.Length() != 2) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong number of arguments"));
    return;
  }

  if (!args[0]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param1(args[0]->ToString());
  std::string ticker = std::string(*param1);

  if (!args[1]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param2(args[1]->ToString());
  std::string timeframe = std::string(*param2);

  //TODO: move this to init
  API *db = new API();
  int retVal = db->connect();
  if(retVal != 0){
    cout<<"db.connect() failed with exit code "<<retVal<<endl;
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Failed to connect to database"));
    return;
  }

  string interval = "day";
  long startDate = 1450000000;
  long endDate = 1490064000;
  vector<API::chart_info> *rows = db->selectHistoricalTickerData(ticker, interval,startDate,endDate);    //Database query
  //unordered_map<std::string, double> *rows = db->selectHistoricalTickerData(ticker, interval);   //Database query
//TODO change data structure to array of struct

  int i = 0;

  Local<Array> result = Array::New(isolate);

  for(vector<API::chart_info>::iterator itr = rows->begin(); itr != rows->end(); itr++, i++){
    cout << itr->timestamp << "\t" << itr->ticker << "\t" << itr->high << "\t" << itr->volume << "\t"
          << itr->open << "\t" << itr->low << "\t" << itr->close << endl;

    // Creates a new Object on the V8 heap
    Local<Object> obj = Object::New(isolate);

    //Can call a pack function here to be cleaner once more data
    // Transfers the data from result, to obj (see below)
    obj->Set(String::NewFromUtf8(isolate, "date"),
       Number::New(isolate, itr->timestamp));
    obj->Set(String::NewFromUtf8(isolate, "ticker"),
       String::NewFromUtf8(isolate, itr->ticker.data()));
    obj->Set(String::NewFromUtf8(isolate, "high"),
       Number::New(isolate, itr->high));
    obj->Set(String::NewFromUtf8(isolate, "volume"),
       Number::New(isolate, itr->volume));
    obj->Set(String::NewFromUtf8(isolate, "open"),
       Number::New(isolate, itr->open));
    obj->Set(String::NewFromUtf8(isolate, "low"),
       Number::New(isolate, itr->low));
    obj->Set(String::NewFromUtf8(isolate, "close"),
       Number::New(isolate, itr->close));

    result->Set(i, obj);
  }

  args.GetReturnValue().Set(result);
  //args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));

  delete db;
}

void ArbitrageData(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  cout<<"Number of args: "<<args.Length()<<endl;

  //Make sure 6 arguments.  Cast to string
  if (args.Length() != 6) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong number of arguments"));
    return;
  }

  if (!args[0]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param1(args[0]->ToString());
  std::string startCurr = std::string(*param1);

  if (!args[1]->IsString()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param2(args[1]->ToString());
  std::string endCurr = std::string(*param2);

  if (!args[2]->IsDouble()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param3(args[2]->ToString());
  std::string startValue = std::string(*param3);

  if (!args[3]->IsDouble()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param4(args[3]->ToString());
  std::string endValue = std::string(*param4);

  if (!args[4]->IsArray()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  std::vector<std:string> currenciesToExclude = new std::vector<std::string>();
  for(int i=0; i<args[4].length(); i++) {
    currenciesToExclude.push_back(args[4][i]->ToString());
  }

  if (!args[5]->IsInteger()) {
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Wrong arguments"));
    return;
  }

  v8::String::Utf8Value param6(args[5]->ToString());
  std::string maxNumberExchanges = std::string(*param6);

  //TODO: move this to init
  API *db = new API();
  int retVal = db->connect();
  if(retVal != 0){
    cout<<"db.connect() failed with exit code "<<retVal<<endl;
    isolate->ThrowException(v8::String::NewFromUtf8(isolate, "Failed to connect to database"));
    return;
  }

  string interval = "day";
  long startDate = 1450000000;
  long endDate = 1490064000;
  vector<API::chart_info> *rows = db->selectHistoricalTickerData(ticker, interval,startDate,endDate);    //Database query
  //unordered_map<std::string, double> *rows = db->selectHistoricalTickerData(ticker, interval);   //Database query
//TODO change data structure to array of struct

  int i = 0;

  Local<Array> result = Array::New(isolate);

  for(vector<API::chart_info>::iterator itr = rows->begin(); itr != rows->end(); itr++, i++){
    cout << itr->timestamp << "\t" << itr->ticker << "\t" << itr->high << "\t" << itr->volume << "\t"
          << itr->open << "\t" << itr->low << "\t" << itr->close << endl;

    // Creates a new Object on the V8 heap
    Local<Object> obj = Object::New(isolate);

    //Can call a pack function here to be cleaner once more data
    // Transfers the data from result, to obj (see below)
    obj->Set(String::NewFromUtf8(isolate, "date"),
       Number::New(isolate, itr->timestamp));
    obj->Set(String::NewFromUtf8(isolate, "ticker"),
       String::NewFromUtf8(isolate, itr->ticker.data()));
    obj->Set(String::NewFromUtf8(isolate, "high"),
       Number::New(isolate, itr->high));
    obj->Set(String::NewFromUtf8(isolate, "volume"),
       Number::New(isolate, itr->volume));
    obj->Set(String::NewFromUtf8(isolate, "open"),
       Number::New(isolate, itr->open));
    obj->Set(String::NewFromUtf8(isolate, "low"),
       Number::New(isolate, itr->low));
    obj->Set(String::NewFromUtf8(isolate, "close"),
       Number::New(isolate, itr->close));

    result->Set(i, obj);
  }

  args.GetReturnValue().Set(result);
  //args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));

  delete db;
}

void init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "exchange", Exchange);
  NODE_SET_METHOD(exports, "table", Table);
  NODE_SET_METHOD(exports, "tickerData", TickerData);
  NODE_SET_METHOD(exports, "chartData", ChartData);
}

NODE_MODULE(addon, init)

}  // namespace demo
<|endoftext|>


<commit_before>#ifndef DUNE_STUFF_FUNCTIONS_HH
#define DUNE_STUFF_FUNCTIONS_HH

#include <string>
#include <vector>

#include <dune/common/parametertree.hh>
#include <dune/common/exceptions.hh>

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

#include "functions/interfaces.hh"
//#include "functions/checkerboard.hh"
#include "functions/expression.hh"
//#include "functions/spe10.hh"
#include "functions/constant.hh"

namespace Dune {
namespace Stuff {

/**
 *  \brief      This is a way to create new functions fulfilling the FunctionInterface using their string identifier.
 *
 *  \attention  This class will not compile for all dimensions. The errors should give you a hint which specializations
 *              are needed below.
 */
template< class E, class D, int d, class R, int rR, int rC = 1 >
class Functions
{
public:
  static std::vector< std::string > available()
  {
    return {
      Function::Constant< E, D, d, R, rR, rC >::static_id()
    , Function::Expression< E, D, d, R, rR, rC >::static_id()
    };
  } // ... available(...)

  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
  {
    if (type == Function::Constant< E, D, d, R, rR, rC >::static_id())
      return Function::Constant< E, D, d, R, rR, rC >::defaultSettings();
    else if (type == Function::Expression< E, D, d, R, rR, rC >::static_id())
      return Function::Expression< E, D, d, R, rR, rC >::defaultSettings();
    else
      DUNE_THROW(Dune::RangeError,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " unknown function '" << type << "' requested!");
  } // ... defaultSettings(...)

  static LocalizableFunctionInterface< E, D, d, R, rR, rC >* create(const std::string type = available()[0],
                                                                    const Dune::ParameterTree settings = defaultSettings())
  {
    if (type == Function::Constant< E, D, d, R, rR, rC >::static_id())
      return Function::Constant< E, D, d, R, rR, rC >::create(settings);
    else if (type == Function::Expression< E, D, d, R, rR, rC >::static_id())
      return Function::Expression< E, D, d, R, rR, rC >::create(settings);
    else
      DUNE_THROW(Dune::RangeError,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " unknown function '" << type << "' requested!");
  } // ... create(...)
}; // class Functions

template< class E, class D, class R >
class Functions< E, D, 1, R, 1, 1 >
{
  static const unsigned int d = 1;
  static const unsigned int rR = 1;
  static const unsigned int rC = 1;
public:
  static std::vector< std::string > available()
  {
    return {
        Function::Constant< E, D, d, R, rR, rC >::static_id()
      , Function::Expression< E, D, d, R, rR, rC >::static_id()
    };
  } // ... available(...)

  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
  {
    if (type == Function::Constant< E, D, d, R, rR, rC >::static_id())
      return Function::Constant< E, D, d, R, rR, rC >::defaultSettings();
    else if (type == Function::Expression< E, D, d, R, rR, rC >::static_id())
      return Function::Expression< E, D, d, R, rR, rC >::defaultSettings();
    else
      DUNE_THROW(Dune::RangeError,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " unknown function '" << type << "' requested!");
  } // ... defaultSettings(...)

  static LocalizableFunctionInterface< E, D, d, R, rR, rC >* create(const std::string type = available()[0],
                                                                  const Dune::ParameterTree settings = defaultSettings())
  {
    if (type == Function::Constant< E, D, d, R, rR, rC >::static_id())
      return Function::Constant< E, D, d, R, rR, rC >::create(settings);
    else if (type == Function::Expression< E, D, d, R, rR, rC >::static_id())
      return Function::Expression< E, D, d, R, rR, rC >::create(settings);
    else
      DUNE_THROW(Dune::RangeError,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " unknown function '" << type << "' requested!");
  } // ... create(...)
}; // class Functions< ..., 1, ..., 1, 1 >

//template< class D, class R >
//class Functions< D, 2, R, 1, 1 >
//{
//public:
//  static std::vector< std::string > available()
//  {
//    return {
//        FunctionExpression< D, 2, R, 1, 1 >::static_id()
//      , FunctionCheckerboard< D, 2, R, 1, 1 >::static_id()
//      , FunctionConstant< D, 2, R, 1, 1 >::static_id()
//    };
//  } // ... available(...)

//  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
//  {
//    if (type == FunctionCheckerboard< D, 2, R, 1, 1 >::static_id())
//      return FunctionCheckerboard< D, 2, R, 1, 1 >::defaultSettings();
//    else if (type == FunctionExpression< D, 2, R, 1, 1 >::static_id())
//      return FunctionExpression< D, 2, R, 1, 1 >::defaultSettings();
//    else if (type == FunctionConstant< D, 2, R, 1, 1 >::static_id())
//      return FunctionConstant< D, 2, R, 1, 1 >::defaultSettings();
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... defaultSettings(...)

//  static FunctionInterface< D, 2, R, 1, 1 >* create(const std::string type = available()[0],
//                                                      const Dune::ParameterTree settings = defaultSettings())
//  {
//    if (type == FunctionCheckerboard< D, 2, R, 1, 1 >::static_id())
//      return FunctionCheckerboard< D, 2, R, 1, 1 >::create(settings);
//    else if (type == FunctionExpression< D, 2, R, 1, 1 >::static_id())
//      return FunctionExpression< D, 2, R, 1, 1 >::create(settings);
//    else if (type == FunctionConstant< D, 2, R, 1, 1 >::static_id())
//      return FunctionConstant< D, 2, R, 1, 1 >::create(settings);
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... create(...)
//}; // class Functions< D, 2, R, 1, 1 >

//template< class D, class R >
//class Functions< D, 3, R, 1, 1 >
//{
//public:
//  static std::vector< std::string > available()
//  {
//    return {
//        FunctionExpression< D, 3, R, 1, 1 >::static_id()
//      , FunctionCheckerboard< D, 3, R, 1, 1 >::static_id()
//      , FunctionConstant< D, 3, R, 1, 1 >::static_id()
//    };
//  } // ... available(...)

//  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
//  {
//    if (type == FunctionCheckerboard< D, 3, R, 1, 1 >::static_id())
//      return FunctionCheckerboard< D, 3, R, 1, 1 >::defaultSettings();
//    else if (type == FunctionExpression< D, 3, R, 1, 1 >::static_id())
//      return FunctionExpression< D, 3, R, 1, 1 >::defaultSettings();
//    else if (type == FunctionConstant< D, 3, R, 1, 1 >::static_id())
//      return FunctionConstant< D, 3, R, 1, 1 >::defaultSettings();
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... defaultSettings(...)

//  static FunctionInterface< D, 3, R, 1, 1 >* create(const std::string type = available()[0],
//                                                      const Dune::ParameterTree settings = defaultSettings())
//  {
//    if (type == FunctionCheckerboard< D, 3, R, 1, 1 >::static_id())
//      return FunctionCheckerboard< D, 3, R, 1, 1 >::create(settings);
//    else if (type == FunctionExpression< D, 3, R, 1, 1 >::static_id())
//      return FunctionExpression< D, 3, R, 1, 1 >::create(settings);
//    else if (type == FunctionConstant< D, 3, R, 1, 1 >::static_id())
//      return FunctionConstant< D, 3, R, 1, 1 >::create(settings);
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... create(...)
//}; // class Functions< D, 3, R, 1, 1 >

//template< class D, int d, class R, int r >
//class Functions< D, d, R, r, 1 >
//{
//public:
//  static std::vector< std::string > available()
//  {
//    return {
//        FunctionExpression< D, d, R, r, 1 >::static_id()
//    };
//  } // ... available(...)

//  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
//  {
//    if (type == FunctionExpression< D, d, R, r, 1 >::static_id())
//      return FunctionExpression< D, d, R, r, 1 >::defaultSettings();
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... defaultSettings(...)

//  static FunctionInterface< D, d, R, r, 1 >* create(const std::string type = available()[0],
//                                                      const Dune::ParameterTree settings = defaultSettings())
//  {
//    if (type == FunctionExpression< D, d, R, r, 1 >::static_id())
//      return FunctionExpression< D, d, R, r, 1 >::create(settings);
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... create(...)
//}; // class Functions< D, d, R, r, 1 >

} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_FUNCTIONS_HH
<commit_msg>[functions] readdded Checkerboard<commit_after>#ifndef DUNE_STUFF_FUNCTIONS_HH
#define DUNE_STUFF_FUNCTIONS_HH

#include <string>
#include <vector>

#include <dune/common/parametertree.hh>
#include <dune/common/exceptions.hh>

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

#include "functions/interfaces.hh"
#include "functions/checkerboard.hh"
#include "functions/expression.hh"
//#include "functions/spe10.hh"
#include "functions/constant.hh"

namespace Dune {
namespace Stuff {

/**
 *  \brief      This is a way to create new functions fulfilling the FunctionInterface using their string identifier.
 *
 *  \attention  This class will not compile for all dimensions. The errors should give you a hint which specializations
 *              are needed below.
 */
template< class E, class D, int d, class R, int rR, int rC = 1 >
class Functions
{
public:
  static std::vector< std::string > available()
  {
    return {
      Function::Constant< E, D, d, R, rR, rC >::static_id()
    , Function::Expression< E, D, d, R, rR, rC >::static_id()
    , Function::Checkerboard< E, D, d, R, rR, rC >::static_id()
    };
  } // ... available(...)

  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
  {
    if (type == Function::Constant< E, D, d, R, rR, rC >::static_id())
      return Function::Constant< E, D, d, R, rR, rC >::defaultSettings();
    else if (type == Function::Expression< E, D, d, R, rR, rC >::static_id())
      return Function::Expression< E, D, d, R, rR, rC >::defaultSettings();
    else if (type == Function::Checkerboard< E, D, d, R, rR, rC >::static_id())
      return Function::Checkerboard< E, D, d, R, rR, rC >::defaultSettings();
    else
      DUNE_THROW(Dune::RangeError,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " unknown function '" << type << "' requested!");
  } // ... defaultSettings(...)

  static LocalizableFunctionInterface< E, D, d, R, rR, rC >* create(const std::string type = available()[0],
                                                                    const Dune::ParameterTree settings = defaultSettings())
  {
    if (type == Function::Constant< E, D, d, R, rR, rC >::static_id())
      return Function::Constant< E, D, d, R, rR, rC >::create(settings);
    else if (type == Function::Expression< E, D, d, R, rR, rC >::static_id())
      return Function::Expression< E, D, d, R, rR, rC >::create(settings);
    else if (type == Function::Checkerboard< E, D, d, R, rR, rC >::static_id())
      return Function::Checkerboard< E, D, d, R, rR, rC >::create(settings);
    else
      DUNE_THROW(Dune::RangeError,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " unknown function '" << type << "' requested!");
  } // ... create(...)
}; // class Functions

template< class E, class D, class R >
class Functions< E, D, 1, R, 1, 1 >
{
  static const unsigned int d = 1;
  static const unsigned int rR = 1;
  static const unsigned int rC = 1;
public:
  static std::vector< std::string > available()
  {
    return {
        Function::Constant< E, D, d, R, rR, rC >::static_id()
      , Function::Expression< E, D, d, R, rR, rC >::static_id()
      , Function::Checkerboard< E, D, d, R, rR, rC >::static_id()
    };
  } // ... available(...)

  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
  {
    if (type == Function::Constant< E, D, d, R, rR, rC >::static_id())
      return Function::Constant< E, D, d, R, rR, rC >::defaultSettings();
    else if (type == Function::Expression< E, D, d, R, rR, rC >::static_id())
      return Function::Expression< E, D, d, R, rR, rC >::defaultSettings();
    else if (type == Function::Checkerboard< E, D, d, R, rR, rC >::static_id())
      return Function::Checkerboard< E, D, d, R, rR, rC >::defaultSettings();
    else
      DUNE_THROW(Dune::RangeError,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " unknown function '" << type << "' requested!");
  } // ... defaultSettings(...)

  static LocalizableFunctionInterface< E, D, d, R, rR, rC >* create(const std::string type = available()[0],
                                                                  const Dune::ParameterTree settings = defaultSettings())
  {
    if (type == Function::Constant< E, D, d, R, rR, rC >::static_id())
      return Function::Constant< E, D, d, R, rR, rC >::create(settings);
    else if (type == Function::Expression< E, D, d, R, rR, rC >::static_id())
      return Function::Expression< E, D, d, R, rR, rC >::create(settings);
    else if (type == Function::Checkerboard< E, D, d, R, rR, rC >::static_id())
      return Function::Checkerboard< E, D, d, R, rR, rC >::create(settings);
    else
      DUNE_THROW(Dune::RangeError,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " unknown function '" << type << "' requested!");
  } // ... create(...)
}; // class Functions< ..., 1, ..., 1, 1 >

//template< class D, class R >
//class Functions< D, 2, R, 1, 1 >
//{
//public:
//  static std::vector< std::string > available()
//  {
//    return {
//        FunctionExpression< D, 2, R, 1, 1 >::static_id()
//      , FunctionCheckerboard< D, 2, R, 1, 1 >::static_id()
//      , FunctionConstant< D, 2, R, 1, 1 >::static_id()
//    };
//  } // ... available(...)

//  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
//  {
//    if (type == FunctionCheckerboard< D, 2, R, 1, 1 >::static_id())
//      return FunctionCheckerboard< D, 2, R, 1, 1 >::defaultSettings();
//    else if (type == FunctionExpression< D, 2, R, 1, 1 >::static_id())
//      return FunctionExpression< D, 2, R, 1, 1 >::defaultSettings();
//    else if (type == FunctionConstant< D, 2, R, 1, 1 >::static_id())
//      return FunctionConstant< D, 2, R, 1, 1 >::defaultSettings();
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... defaultSettings(...)

//  static FunctionInterface< D, 2, R, 1, 1 >* create(const std::string type = available()[0],
//                                                      const Dune::ParameterTree settings = defaultSettings())
//  {
//    if (type == FunctionCheckerboard< D, 2, R, 1, 1 >::static_id())
//      return FunctionCheckerboard< D, 2, R, 1, 1 >::create(settings);
//    else if (type == FunctionExpression< D, 2, R, 1, 1 >::static_id())
//      return FunctionExpression< D, 2, R, 1, 1 >::create(settings);
//    else if (type == FunctionConstant< D, 2, R, 1, 1 >::static_id())
//      return FunctionConstant< D, 2, R, 1, 1 >::create(settings);
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... create(...)
//}; // class Functions< D, 2, R, 1, 1 >

//template< class D, class R >
//class Functions< D, 3, R, 1, 1 >
//{
//public:
//  static std::vector< std::string > available()
//  {
//    return {
//        FunctionExpression< D, 3, R, 1, 1 >::static_id()
//      , FunctionCheckerboard< D, 3, R, 1, 1 >::static_id()
//      , FunctionConstant< D, 3, R, 1, 1 >::static_id()
//    };
//  } // ... available(...)

//  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
//  {
//    if (type == FunctionCheckerboard< D, 3, R, 1, 1 >::static_id())
//      return FunctionCheckerboard< D, 3, R, 1, 1 >::defaultSettings();
//    else if (type == FunctionExpression< D, 3, R, 1, 1 >::static_id())
//      return FunctionExpression< D, 3, R, 1, 1 >::defaultSettings();
//    else if (type == FunctionConstant< D, 3, R, 1, 1 >::static_id())
//      return FunctionConstant< D, 3, R, 1, 1 >::defaultSettings();
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... defaultSettings(...)

//  static FunctionInterface< D, 3, R, 1, 1 >* create(const std::string type = available()[0],
//                                                      const Dune::ParameterTree settings = defaultSettings())
//  {
//    if (type == FunctionCheckerboard< D, 3, R, 1, 1 >::static_id())
//      return FunctionCheckerboard< D, 3, R, 1, 1 >::create(settings);
//    else if (type == FunctionExpression< D, 3, R, 1, 1 >::static_id())
//      return FunctionExpression< D, 3, R, 1, 1 >::create(settings);
//    else if (type == FunctionConstant< D, 3, R, 1, 1 >::static_id())
//      return FunctionConstant< D, 3, R, 1, 1 >::create(settings);
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... create(...)
//}; // class Functions< D, 3, R, 1, 1 >

//template< class D, int d, class R, int r >
//class Functions< D, d, R, r, 1 >
//{
//public:
//  static std::vector< std::string > available()
//  {
//    return {
//        FunctionExpression< D, d, R, r, 1 >::static_id()
//    };
//  } // ... available(...)

//  static Dune::ParameterTree defaultSettings(const std::string type = available()[0])
//  {
//    if (type == FunctionExpression< D, d, R, r, 1 >::static_id())
//      return FunctionExpression< D, d, R, r, 1 >::defaultSettings();
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... defaultSettings(...)

//  static FunctionInterface< D, d, R, r, 1 >* create(const std::string type = available()[0],
//                                                      const Dune::ParameterTree settings = defaultSettings())
//  {
//    if (type == FunctionExpression< D, d, R, r, 1 >::static_id())
//      return FunctionExpression< D, d, R, r, 1 >::create(settings);
//    else
//      DUNE_THROW(Dune::RangeError,
//                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
//                 << " unknown function '" << type << "' requested!");
//  } // ... create(...)
//}; // class Functions< D, d, R, r, 1 >

} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_FUNCTIONS_HH
<|endoftext|>


<commit_before>// ------------------------------------------------------------------------
// eca-curses.cpp: Curses implementation of the console user interface.
// Copyright (C) 1999-2002 Kai Vehmanen (kai.vehmanen@wakkanet.fi)
//
// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
// ------------------------------------------------------------------------

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <map>
#include <string>

#if defined ECA_USE_NCURSES || defined ECA_USE_TERMCAP

#ifdef ECA_HAVE_NCURSES_CURSES_H
#include <ncurses/curses.h>
#include <ncurses/term.h>
#else
#include <curses.h>
#include <term.h>
#endif

#define READLINE_LIBRARY
#include <readline.h>
#include <history.h>

#include <eca-iamode-parser.h>
#include <eca-version.h>
#include <kvu_utils.h> /* kvu_string_search_and_replace() */

#include "eca-curses.h"

#if RL_READLINE_VERSION >= 0x0402
static char** ecasound_completion (const char *text, int start, int end);
static char* ecasound_command_generator (const char* text, int state);
#else
static char** ecasound_completion (char *text, int start, int end);
static char* ecasound_command_generator (char* text, int state);
#endif

using namespace std;

ECA_CURSES::ECA_CURSES(void)
{
  init_readline_support();
}

ECA_CURSES::~ECA_CURSES(void)
{
}

void ECA_CURSES::print(const std::string& msg)
{
  cout << msg << endl;
}

void ECA_CURSES::print_banner(void)
{
  cout << "****************************************************************************\n";
  cout << "*";
  setupterm((char *)0, 1, (int *)0);
  putp(tigetstr("bold"));
  cout << "               ecasound v"
       << ecasound_library_version
       << " (C) 1997-2002 Kai Vehmanen                 ";
  putp(tigetstr("sgr0"));
  cout << "\n";
  cout << "****************************************************************************\n";
}

void ECA_CURSES::read_command(const string& prompt)
{
  last_cmdchar_repp = readline(const_cast<char*>(prompt.c_str()));
  if (last_cmdchar_repp != 0) {
    add_history(last_cmdchar_repp);
    last_cmd_rep = last_cmdchar_repp;
    free(last_cmdchar_repp);
  }
}

const string& ECA_CURSES::last_command(void) const
{
  return(last_cmd_rep);
}

void ECA_CURSES::init_readline_support(void)
{
  /* for conditional parsing of ~/.inputrc file. */
  rl_readline_name = "ecasound";

  /* we want to attempt completion first */
#if RL_READLINE_VERSION >= 0x0402
  rl_attempted_completion_function = (rl_completion_func_t*)ecasound_completion;
#else
  rl_attempted_completion_function = (CPPFunction *)ecasound_completion;
#endif
}

/* **************************************************************** */
/*                                                                  */
/*                  Interface to Readline Completion                */
/*                                                                  */
/* **************************************************************** */

char *command_generator ();
char **fileman_completion ();

/**
 * Attempt to complete on the contents of TEXT.  START and END bound the
 * region of rl_line_buffer that contains the word to complete.  TEXT is
 * the word to complete.  We can use the entire contents of rl_line_buffer
 * in case we want to do some simple parsing.  Return the array of matches,
 * or NULL if there aren't any.
 */
#if RL_READLINE_VERSION >= 0x0402
char** ecasound_completion (const char *text, int start, int end)
#else
char** ecasound_completion (char *text, int start, int end)
#endif
{
  char **matches;
  matches = (char **)NULL;

  /* complete only the first command, otherwise complete files in
   * the current directory */
  if (start == 0) {
#if RL_READLINE_VERSION >= 0x0402
    matches = rl_completion_matches (text, (rl_compentry_func_t *)ecasound_command_generator);
#else
    matches = completion_matches (text, (CPFunction *)ecasound_command_generator);
#endif
  }
  return (matches);
}

/**
 * Generator function for command completion.  STATE lets us know whether
 * to start from scratch; without any state (i.e. STATE == 0), then we
 * start at the top of the list.
 */
#if RL_READLINE_VERSION >= 0x0402
char* ecasound_command_generator (const char* text, int state)
#else
char* ecasound_command_generator (char* text, int state)
#endif
{
  static int list_index, len;
  static const map<string,int>& map_ref = ECA_IAMODE_PARSER::registered_commands();
  static map<string,int>::const_iterator p;
  static string cmd;

  /* If this is a new word to complete, initialize now.  This includes
   * saving the length of TEXT for efficiency, and initializing the index
   * variable to 0
   */
  if (!state) {
      list_index = 0;
      p = map_ref.begin();
      len = strlen (text);
  }

  /* Return the next name which partially matches from the command list */
  while (p != map_ref.end()) {
      cmd = p->first;
      list_index++;
      ++p;
      if (p != map_ref.end()) {
	string hyphenstr = kvu_string_search_and_replace(text, '_', '-');
	if (strncmp(hyphenstr.c_str(), cmd.c_str(), len) == 0) {
	  return(strdup(cmd.c_str()));
	}
      }
  }
  return ((char *)0);
}

#else

void ECA_CURSES::print(const std::string& msg) {}
void ECA_CURSES::print_banner(void) {}
void ECA_CURSES::read_command(const string& promp) {}
const string& ECA_CURSES::last_command(void) const { static std::string empty; return(empty); }
void ECA_CURSES::init_readline_support(void) {}

#endif /* defined ECA_USE_NCURSES || defined ECA_USE_TERMCAP */
<commit_msg>More fixes for Solaris Workshop compiler.<commit_after>// ------------------------------------------------------------------------
// eca-curses.cpp: Curses implementation of the console user interface.
// Copyright (C) 1999-2002 Kai Vehmanen (kai.vehmanen@wakkanet.fi)
//
// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
// ------------------------------------------------------------------------

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <map>
#include <string>

#if defined ECA_USE_NCURSES || defined ECA_USE_TERMCAP

#ifdef ECA_HAVE_NCURSES_CURSES_H
#include <ncurses/curses.h>
#include <ncurses/term.h>
#else
#include <curses.h>
#include <term.h>
#endif

#define READLINE_LIBRARY
#include <readline.h>
#include <history.h>

#include <eca-iamode-parser.h>
#include <eca-version.h>
#include <kvu_utils.h> /* kvu_string_search_and_replace() */

#include "eca-curses.h"

#if RL_READLINE_VERSION >= 0x0402
static char** ecasound_completion (const char *text, int start, int end);
static char* ecasound_command_generator (const char* text, int state);
#else
static char** ecasound_completion (char *text, int start, int end);
static char* ecasound_command_generator (char* text, int state);
#endif

using namespace std;

ECA_CURSES::ECA_CURSES(void)
{
  init_readline_support();
}

ECA_CURSES::~ECA_CURSES(void)
{
}

void ECA_CURSES::print(const std::string& msg)
{
  cout << msg << endl;
}

void ECA_CURSES::print_banner(void)
{
  cout << "****************************************************************************\n";
  cout << "*";
  setupterm((char *)0, 1, (int *)0);
  putp(tigetstr("bold"));
  cout << "               ecasound v"
       << ecasound_library_version
       << " (C) 1997-2002 Kai Vehmanen                 ";
  putp(tigetstr("sgr0"));
  cout << "\n";
  cout << "****************************************************************************\n";
}

void ECA_CURSES::read_command(const string& prompt)
{
  last_cmdchar_repp = readline(const_cast<char*>(prompt.c_str()));
  if (last_cmdchar_repp != 0) {
    add_history(last_cmdchar_repp);
    last_cmd_rep = last_cmdchar_repp;
    free(last_cmdchar_repp);
  }
}

const string& ECA_CURSES::last_command(void) const
{
  return(last_cmd_rep);
}

void ECA_CURSES::init_readline_support(void)
{
  /* for conditional parsing of ~/.inputrc file. */
  rl_readline_name = "ecasound";

  /* we want to attempt completion first */
#if RL_READLINE_VERSION >= 0x0402
  rl_attempted_completion_function = (rl_completion_func_t*)ecasound_completion;
#else
  rl_attempted_completion_function = (CPPFunction *)ecasound_completion;
#endif
}

/* **************************************************************** */
/*                                                                  */
/*                  Interface to Readline Completion                */
/*                                                                  */
/* **************************************************************** */

char *command_generator ();
char **fileman_completion ();

/**
 * Attempt to complete on the contents of TEXT.  START and END bound the
 * region of rl_line_buffer that contains the word to complete.  TEXT is
 * the word to complete.  We can use the entire contents of rl_line_buffer
 * in case we want to do some simple parsing.  Return the array of matches,
 * or NULL if there aren't any.
 */
#if RL_READLINE_VERSION >= 0x0402
char** ecasound_completion (const char *text, int start, int end)
#else
char** ecasound_completion (char *text, int start, int end)
#endif
{
  char **matches;
  matches = (char **)NULL;

  /* complete only the first command, otherwise complete files in
   * the current directory */
  if (start == 0) {
#if RL_READLINE_VERSION >= 0x0402
    matches = rl_completion_matches (text, (rl_compentry_func_t *)ecasound_command_generator);
#else
    matches = completion_matches (text, (CPFunction *)ecasound_command_generator);
#endif
  }
  return (matches);
}

/**
 * Generator function for command completion.  STATE lets us know whether
 * to start from scratch; without any state (i.e. STATE == 0), then we
 * start at the top of the list.
 */
#if RL_READLINE_VERSION >= 0x0402
char* ecasound_command_generator (const char* text, int state)
#else
char* ecasound_command_generator (char* text, int state)
#endif
{
  static int list_index, len;
  static const map<string,int>& map_ref = ECA_IAMODE_PARSER::registered_commands();
  static map<string,int>::const_iterator p;
  static string cmd;

  /* If this is a new word to complete, initialize now.  This includes
   * saving the length of TEXT for efficiency, and initializing the index
   * variable to 0
   */
  if (!state) {
      list_index = 0;
      p = map_ref.begin();
      len = strlen (text);
  }

  /* Return the next name which partially matches from the command list */
  while (p != map_ref.end()) {
      cmd = p->first;
      list_index++;
      ++p;
      if (p != map_ref.end()) {
	string hyphenstr = kvu_string_search_and_replace(text, '_', '-');
	if (strncmp(hyphenstr.c_str(), cmd.c_str(), len) == 0) {
	  return(strdup(cmd.c_str()));
	}
      }
  }
  return ((char *)0);
}

#else

ECA_CURSES::ECA_CURSES(void) {}
ECA_CURSES::~ECA_CURSES(void) {}
void ECA_CURSES::print(const std::string& msg) {}
void ECA_CURSES::print_banner(void) {}
void ECA_CURSES::read_command(const string& promp) {}
const string& ECA_CURSES::last_command(void) const { static std::string empty; return(empty); }
void ECA_CURSES::init_readline_support(void) {}

#endif /* defined ECA_USE_NCURSES || defined ECA_USE_TERMCAP */
<|endoftext|>


<commit_before>// PluginHelpers.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "Toolbars.h"

////////////////////////////////////////////////////////////////////////////////////////////////

#using <system.dll>

using namespace Abstractspoon::Tdl::PluginHelpers;

////////////////////////////////////////////////////////////////////////////////////////////////

void Toolbars::FixupButtonSizes(ToolStrip^ toolbar)
{
	auto imageSize = toolbar->ImageScalingSize;
	int numItems = toolbar->Items->Count;

	for (int i = 0; i < numItems; i++)
	{
		auto button = dynamic_cast<ToolStripButton^>(toolbar->Items[i]);

		if (button != nullptr)
		{
			// From 'Shared\EnToolBar.cpp'
			int xPadding = (imageSize.Width + 7 - button->Size.Width);
			int yPadding = (imageSize.Height + 7 - button->Size.Height);

			System::Diagnostics::Trace::WriteLine(String::Format("Toolbars::FixupButtonSizes({0}, size({1}, {2}), padding({3}, {4}))",
																 i, button->Size.Width, button->Size.Height, xPadding, yPadding));

			button->Padding = Padding(xPadding / 2, yPadding / 2, xPadding - xPadding / 2, yPadding - yPadding / 2);
		}
		else
		{
			auto sep = dynamic_cast<ToolStripSeparator^>(toolbar->Items[i]);

			if (sep != nullptr)
			{
				sep->AutoSize = false;
				sep->Height = (imageSize.Height + 7);
			}
		}
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////

BaseToolbarRenderer::BaseToolbarRenderer() : m_DrawRowDividers(true)
{

}

void BaseToolbarRenderer::EnableDrawRowDividers(bool enable)
{
	m_DrawRowDividers = enable;
}

void BaseToolbarRenderer::OnRenderToolStripBackground(ToolStripRenderEventArgs^ e)
{
	ToolStripRenderer::OnRenderToolStripBackground(e);

	if (m_DrawRowDividers)
	{
		auto toolbar = e->ToolStrip;
		int numItems = toolbar->Items->Count;

		if (numItems > 0)
		{
			auto prevBtnRect = Drawing::Rectangle::Empty;
			int rowTop = toolbar->Top, rowBottom = 0;
			bool firstRow = true;

			for (int i = 0; i < numItems; i++)
			{
				auto button = dynamic_cast<ToolStripButton^>(toolbar->Items[i]);

				if (button != nullptr)
				{
					if (prevBtnRect.IsEmpty)
					{
						prevBtnRect = button->Bounds;
					}
					else
					{
						auto btnRect = button->Bounds;

						if (btnRect.Top > prevBtnRect.Top)
						{
							rowBottom = ((btnRect.Top + prevBtnRect.Bottom) / 2);

							auto rowRect = gcnew Drawing::Rectangle(toolbar->Left, rowTop, toolbar->Width, (rowBottom - rowTop));
							DrawRowBackground(e->Graphics, rowRect, firstRow, false);

							prevBtnRect = btnRect;
							rowTop = rowBottom + 1;
							firstRow = false;
						}
					}
				}
			}

			// Last row
			auto rowRect = gcnew Drawing::Rectangle(toolbar->Left, rowTop, toolbar->Width, (toolbar->Bottom - rowTop));
			DrawRowBackground(e->Graphics, rowRect, firstRow, true);
		}
	}
}

void BaseToolbarRenderer::DrawRowBackground(Drawing::Graphics^ g, Drawing::Rectangle^ rowRect, bool firstRow, bool lastRow)
{
	DrawRowDivider(g, rowRect, firstRow, lastRow);
}

void BaseToolbarRenderer::DrawRowDivider(Drawing::Graphics^ g, Drawing::Rectangle^ rowRect, bool firstRow, bool lastRow)
{
	// Draw highlight line at top if not first row
	if (!firstRow)
		g->DrawLine(SystemPens::ButtonHighlight, rowRect->Left, rowRect->Top, rowRect->Right, rowRect->Top);

	// Draw shadow line at bottom if not last row
	if (!lastRow)
		g->DrawLine(SystemPens::ButtonShadow, rowRect->Left, rowRect->Bottom, rowRect->Right, rowRect->Bottom);
}

////////////////////////////////////////////////////////////////////////////////////////////////
<commit_msg>Comment out debug code<commit_after>// PluginHelpers.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "Toolbars.h"

////////////////////////////////////////////////////////////////////////////////////////////////

#using <system.dll>

using namespace Abstractspoon::Tdl::PluginHelpers;

////////////////////////////////////////////////////////////////////////////////////////////////

void Toolbars::FixupButtonSizes(ToolStrip^ toolbar)
{
	auto imageSize = toolbar->ImageScalingSize;
	int numItems = toolbar->Items->Count;

	for (int i = 0; i < numItems; i++)
	{
		auto button = dynamic_cast<ToolStripButton^>(toolbar->Items[i]);

		if (button != nullptr)
		{
			// From 'Shared\EnToolBar.cpp'
			int xPadding = (imageSize.Width + 7 - button->Size.Width);
			int yPadding = (imageSize.Height + 7 - button->Size.Height);

			//System::Diagnostics::Trace::WriteLine(String::Format("Toolbars::FixupButtonSizes({0}, size({1}, {2}), padding({3}, {4}))",
			//													 i, button->Size.Width, button->Size.Height, xPadding, yPadding));

			button->Padding = Padding(xPadding / 2, yPadding / 2, xPadding - xPadding / 2, yPadding - yPadding / 2);
		}
		else
		{
			auto sep = dynamic_cast<ToolStripSeparator^>(toolbar->Items[i]);

			if (sep != nullptr)
			{
				sep->AutoSize = false;
				sep->Height = (imageSize.Height + 7);
			}
		}
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////

BaseToolbarRenderer::BaseToolbarRenderer() : m_DrawRowDividers(true)
{

}

void BaseToolbarRenderer::EnableDrawRowDividers(bool enable)
{
	m_DrawRowDividers = enable;
}

void BaseToolbarRenderer::OnRenderToolStripBackground(ToolStripRenderEventArgs^ e)
{
	ToolStripRenderer::OnRenderToolStripBackground(e);

	if (m_DrawRowDividers)
	{
		auto toolbar = e->ToolStrip;
		int numItems = toolbar->Items->Count;

		if (numItems > 0)
		{
			auto prevBtnRect = Drawing::Rectangle::Empty;
			int rowTop = toolbar->Top, rowBottom = 0;
			bool firstRow = true;

			for (int i = 0; i < numItems; i++)
			{
				auto button = dynamic_cast<ToolStripButton^>(toolbar->Items[i]);

				if (button != nullptr)
				{
					if (prevBtnRect.IsEmpty)
					{
						prevBtnRect = button->Bounds;
					}
					else
					{
						auto btnRect = button->Bounds;

						if (btnRect.Top > prevBtnRect.Top)
						{
							rowBottom = ((btnRect.Top + prevBtnRect.Bottom) / 2);

							auto rowRect = gcnew Drawing::Rectangle(toolbar->Left, rowTop, toolbar->Width, (rowBottom - rowTop));
							DrawRowBackground(e->Graphics, rowRect, firstRow, false);

							prevBtnRect = btnRect;
							rowTop = rowBottom + 1;
							firstRow = false;
						}
					}
				}
			}

			// Last row
			auto rowRect = gcnew Drawing::Rectangle(toolbar->Left, rowTop, toolbar->Width, (toolbar->Bottom - rowTop));
			DrawRowBackground(e->Graphics, rowRect, firstRow, true);
		}
	}
}

void BaseToolbarRenderer::DrawRowBackground(Drawing::Graphics^ g, Drawing::Rectangle^ rowRect, bool firstRow, bool lastRow)
{
	DrawRowDivider(g, rowRect, firstRow, lastRow);
}

void BaseToolbarRenderer::DrawRowDivider(Drawing::Graphics^ g, Drawing::Rectangle^ rowRect, bool firstRow, bool lastRow)
{
	// Draw highlight line at top if not first row
	if (!firstRow)
		g->DrawLine(SystemPens::ButtonHighlight, rowRect->Left, rowRect->Top, rowRect->Right, rowRect->Top);

	// Draw shadow line at bottom if not last row
	if (!lastRow)
		g->DrawLine(SystemPens::ButtonShadow, rowRect->Left, rowRect->Bottom, rowRect->Right, rowRect->Bottom);
}

////////////////////////////////////////////////////////////////////////////////////////////////
<|endoftext|>