<commit_before>#include "NexStar.h"

NexStar::NexStar(byte txPin, byte rxPin, byte flagPin) {
  _txPin = txPin;
  _rxPin = rxPin;
  _flagPin = flagPin;

  _srcID = 0x0D;

  azimuthMC = new MotorController(this, 0x10);
  elevationMC = new MotorController(this, 0x11);

  _ss = new SoftwareSerial(rxPin, txPin);
  _ss->begin(19200);
  pinMode(_txPin, OUTPUT);
  digitalWrite(_txPin, HIGH);
  pinMode(_rxPin, INPUT_PULLUP);
  pinMode(_flagPin, INPUT_PULLUP);

  return;
}

reply NexStar::_sendCommand(byte destID, byte cmd, byte len, byte *data) {
  // Tristate flag pin, so turn driver on and drive low.  Wait before sending data.
  pinMode(_flagPin, OUTPUT);
  digitalWrite(_flagPin, LOW);
  delay(1);

  // Checksum: ignore prefix byte, sum remainder of packet, take 2s complement of low byte of sum.
  unsigned char sum = 0x03 + len + _srcID + destID + cmd;

  // Packet format: 0x3B len srcID destID cmd data[0]... sum
  // Length covers srcID, destID, and cmd plus data bytes.
  _ss->write(0x3B);
  _ss->write((unsigned char)(0x03 + len));
  _ss->write(_srcID);
  _ss->write(destID);
  _ss->write(cmd);
  for (byte i = 0; i < len; i++) {
    _ss->write(data[i]);
    sum += data[i];
  }
  _ss->write((unsigned char)((~sum)+1));

  // Tristate flag pin, so turn driver off a little bit after data completes.
  delay(1);
  pinMode(_flagPin, INPUT_PULLUP);

  static byte buff[5];
  byte b = 0, i = 0;
  byte exlen = 10;
  sum = 0;

  reply r;
  r.len = 0;
  r.bytes = 0;

  // Now read the reply from the controller.  Return null pointer on error.
  // TODO: Will hang forever if nothing is received.  Add timeout.
  while (1) {
    while (_ss->available() < 1);
    b = _ss->read();
    if ((i != 0) && (i != exlen)) sum += b;

    switch(i) {
      case 0:
        if (b != 0x3B) return r;
        break;
      case 1:
        exlen = b + 2;
        break;
      case 2:
        if (b != destID) return r;
        break;
      case 3:
        if (b != _srcID) return r;
        break;
      case 4:
        if (b != cmd) return r;
        break;
      default:
        if (b < 10) buff[b-5] = b;
        break;
    }

    if (i == exlen) {
      if (b == (byte)((~sum)+1)) {
        if (exlen > 10) {
          r.len = 5;
        } else {
          r.len = exlen - 5;
        }
        r.bytes = buff;
      }

      return r;
    }

    i++;
  }
}

// AVR is little-endian, so for sending as bytes an int has to be reversed.
reply NexStar::_sendCommand(byte destID, byte cmd, int24 data) {
  int24 d = __builtin_bswap32(data);
  return _sendCommand(destID, cmd, 3, (byte*)(&d)+1);
}

NexStar::MotorController::MotorController(NexStar *nexStar, byte destID) {
  _nexStar = nexStar;
  _destID = destID;
}

// Confines values to 24-bit range.
int24 NexStar::MotorController::_clamp_int24(int24 x) {
  static const int32_t POSLIM = 0x007FFFFF;
  static const int32_t NEGLIM = 0xFF800000;

  if (x > POSLIM) return POSLIM;
  if (x < NEGLIM) return NEGLIM;
  return x;
}

// Converts 3 bytes from array into a 32-bit integer with 24-bit range.
int24 NexStar::MotorController::_bytes_to_int24(byte* b) {
  int32_t ret = b[0];
  ret = (ret << 8) + b[1];
  ret = (ret << 8) + b[2];
  ret = ret << 8;
  ret = ret >> 8;

  return ret;
}

int24 NexStar::MotorController::getPosition() {
  reply res = _nexStar->_sendCommand(_destID, 0x01, 0, 0);

  if (res.len != 3) {
    return -1;
  } else {
    return _bytes_to_int24(res.bytes);
  }
}

void NexStar::MotorController::setPosition(int24 pos) {
  _nexStar->_sendCommand(_destID, 0x04, _clamp_int24(pos));
}

// Valid jog rates are 0 to 9.
void NexStar::MotorController::jog(uint8_t rate, direction dir) {
  if (rate > 9) rate = 9;

  switch (dir) {
    case FORWARD:
    default:
      _nexStar->_sendCommand(_destID, 0x24, 1, (byte*)(&rate));
      break;
    case REVERSE:
      _nexStar->_sendCommand(_destID, 0x25, 1, (byte*)(&rate));
      break;
  }
}

void NexStar::MotorController::gotoFast(int24 pos) {
  _nexStar->_sendCommand(_destID, 0x02, _clamp_int24(pos));
}

void NexStar::MotorController::gotoSlow(int24 pos) {
  _nexStar->_sendCommand(_destID, 0x17, _clamp_int24(pos));
}

bool NexStar::MotorController::isSlewing() {
  reply res = _nexStar->_sendCommand(_destID, 0x13, 0, 0);

  if (res.len != 1) {
    return true;
  } else {
    return (res.bytes[0] == 0x00);
  }
}

void NexStar::MotorController::setCordwrapPosition(int24 pos) {
  _nexStar->_sendCommand(_destID, 0x3a, _clamp_int24(pos));
}

void NexStar::MotorController::enableCordwrap(bool enable) {
  if (enable) {
    _nexStar->_sendCommand(_destID, 0x38, 0, 0);
  } else {
    _nexStar->_sendCommand(_destID, 0x39, 0, 0);
  }
}

void NexStar::MotorController::setApproachDirection(direction dir) {
  _nexStar->_sendCommand(_destID, 0xFD, 1, (byte*)&dir);
}

// Valid backlash compensation values are 0-99.
void NexStar::MotorController::setBacklashCompensation(uint8_t backlash, direction dir) {
  if (backlash > 99) backlash = 99;

  switch (dir) {
    case FORWARD:
    default:
      _nexStar->_sendCommand(_destID, 0x10, 1, (byte*)(&backlash));
      break;
    case REVERSE:
      _nexStar->_sendCommand(_destID, 0x11, 1, (byte*)(&backlash));
      break;
  }
}

// Returns two bytes. Example: 0515 = version 05.15.
// Good function to check initial connectivity.
uint16_t NexStar::MotorController::getVersion() {
  reply ret = _nexStar->_sendCommand(_destID, 0xFE, 0, 0);
  if (ret.len != 2) {
    return -1;
  } else {
    return (ret.bytes[0]<<8)+ret.bytes[1];
  }
}

<commit_msg>Fix error in reply read buffer fill.<commit_after>#include "NexStar.h"

NexStar::NexStar(byte txPin, byte rxPin, byte flagPin) {
  _txPin = txPin;
  _rxPin = rxPin;
  _flagPin = flagPin;

  _srcID = 0x0D;

  azimuthMC = new MotorController(this, 0x10);
  elevationMC = new MotorController(this, 0x11);

  _ss = new SoftwareSerial(rxPin, txPin);
  _ss->begin(19200);
  pinMode(_txPin, OUTPUT);
  digitalWrite(_txPin, HIGH);
  pinMode(_rxPin, INPUT_PULLUP);
  pinMode(_flagPin, INPUT_PULLUP);

  return;
}

reply NexStar::_sendCommand(byte destID, byte cmd, byte len, byte *data) {
  // Tristate flag pin, so turn driver on and drive low.  Wait before sending data.
  pinMode(_flagPin, OUTPUT);
  digitalWrite(_flagPin, LOW);
  delay(1);

  // Checksum: ignore prefix byte, sum remainder of packet, take 2s complement of low byte of sum.
  unsigned char sum = 0x03 + len + _srcID + destID + cmd;

  // Packet format: 0x3B len srcID destID cmd data[0]... sum
  // Length covers srcID, destID, and cmd plus data bytes.
  _ss->write(0x3B);
  _ss->write((unsigned char)(0x03 + len));
  _ss->write(_srcID);
  _ss->write(destID);
  _ss->write(cmd);
  for (byte i = 0; i < len; i++) {
    _ss->write(data[i]);
    sum += data[i];
  }
  _ss->write((unsigned char)((~sum)+1));

  // Tristate flag pin, so turn driver off a little bit after data completes.
  delay(1);
  pinMode(_flagPin, INPUT_PULLUP);

  static byte buff[5];
  byte b = 0, i = 0;
  byte exlen = 10;
  sum = 0;

  reply r;
  r.len = 0;
  r.bytes = 0;

  // Now read the reply from the controller.  Return null pointer on error.
  // TODO: Will hang forever if nothing is received.  Add timeout.
  while (1) {
    while (_ss->available() < 1);
    b = _ss->read();
    if ((i != 0) && (i != exlen)) sum += b;

    switch(i) {
      case 0:
        if (b != 0x3B) return r;
        break;
      case 1:
        exlen = b + 2;
        break;
      case 2:
        if (b != destID) return r;
        break;
      case 3:
        if (b != _srcID) return r;
        break;
      case 4:
        if (b != cmd) return r;
        break;
      default:
        if (i < 10) buff[i-5] = b;
        break;
    }

    if (i == exlen) {
      if (b == (byte)((~sum)+1)) {
        if (exlen > 10) {
          r.len = 5;
        } else {
          r.len = exlen - 5;
        }
        r.bytes = buff;
      }

      return r;
    }

    i++;
  }
}

// AVR is little-endian, so for sending as bytes an int has to be reversed.
reply NexStar::_sendCommand(byte destID, byte cmd, int24 data) {
  int24 d = __builtin_bswap32(data);
  return _sendCommand(destID, cmd, 3, (byte*)(&d)+1);
}

NexStar::MotorController::MotorController(NexStar *nexStar, byte destID) {
  _nexStar = nexStar;
  _destID = destID;
}

// Confines values to 24-bit range.
int24 NexStar::MotorController::_clamp_int24(int24 x) {
  static const int32_t POSLIM = 0x007FFFFF;
  static const int32_t NEGLIM = 0xFF800000;

  if (x > POSLIM) return POSLIM;
  if (x < NEGLIM) return NEGLIM;
  return x;
}

// Converts 3 bytes from array into a 32-bit integer with 24-bit range.
int24 NexStar::MotorController::_bytes_to_int24(byte* b) {
  int32_t ret = b[0];
  ret = (ret << 8) + b[1];
  ret = (ret << 8) + b[2];
  ret = ret << 8;
  ret = ret >> 8;

  return ret;
}

int24 NexStar::MotorController::getPosition() {
  reply res = _nexStar->_sendCommand(_destID, 0x01, 0, 0);

  if (res.len != 3) {
    return -1;
  } else {
    return _bytes_to_int24(res.bytes);
  }
}

void NexStar::MotorController::setPosition(int24 pos) {
  _nexStar->_sendCommand(_destID, 0x04, _clamp_int24(pos));
}

// Valid jog rates are 0 to 9.
void NexStar::MotorController::jog(uint8_t rate, direction dir) {
  if (rate > 9) rate = 9;

  switch (dir) {
    case FORWARD:
    default:
      _nexStar->_sendCommand(_destID, 0x24, 1, (byte*)(&rate));
      break;
    case REVERSE:
      _nexStar->_sendCommand(_destID, 0x25, 1, (byte*)(&rate));
      break;
  }
}

void NexStar::MotorController::gotoFast(int24 pos) {
  _nexStar->_sendCommand(_destID, 0x02, _clamp_int24(pos));
}

void NexStar::MotorController::gotoSlow(int24 pos) {
  _nexStar->_sendCommand(_destID, 0x17, _clamp_int24(pos));
}

bool NexStar::MotorController::isSlewing() {
  reply res = _nexStar->_sendCommand(_destID, 0x13, 0, 0);

  if (res.len != 1) {
    return true;
  } else {
    return (res.bytes[0] == 0x00);
  }
}

void NexStar::MotorController::setCordwrapPosition(int24 pos) {
  _nexStar->_sendCommand(_destID, 0x3a, _clamp_int24(pos));
}

void NexStar::MotorController::enableCordwrap(bool enable) {
  if (enable) {
    _nexStar->_sendCommand(_destID, 0x38, 0, 0);
  } else {
    _nexStar->_sendCommand(_destID, 0x39, 0, 0);
  }
}

void NexStar::MotorController::setApproachDirection(direction dir) {
  _nexStar->_sendCommand(_destID, 0xFD, 1, (byte*)&dir);
}

// Valid backlash compensation values are 0-99.
void NexStar::MotorController::setBacklashCompensation(uint8_t backlash, direction dir) {
  if (backlash > 99) backlash = 99;

  switch (dir) {
    case FORWARD:
    default:
      _nexStar->_sendCommand(_destID, 0x10, 1, (byte*)(&backlash));
      break;
    case REVERSE:
      _nexStar->_sendCommand(_destID, 0x11, 1, (byte*)(&backlash));
      break;
  }
}

// Returns two bytes. Example: 0515 = version 05.15.
// Good function to check initial connectivity.
uint16_t NexStar::MotorController::getVersion() {
  reply ret = _nexStar->_sendCommand(_destID, 0xFE, 0, 0);
  if (ret.len != 2) {
    return -1;
  } else {
    return (ret.bytes[0]<<8)+ret.bytes[1];
  }
}

<|endoftext|>


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

#include "google/cloud/internal/absl_str_cat_quiet.h"
#include "google/cloud/internal/absl_str_replace_quiet.h"
#include "google/cloud/internal/getenv.h"
#include "google/cloud/status_or.h"
#include "google/cloud/testing_util/status_matchers.h"
#include "generator/generator.h"
#include "generator/internal/codegen_utils.h"
#include <google/protobuf/compiler/command_line_interface.h>
#include <gmock/gmock.h>
#include <fstream>
#include <iostream>

namespace google {
namespace cloud {
namespace generator_internal {
namespace {

using ::testing::ElementsAreArray;

StatusOr<std::vector<std::string>> ReadFile(std::string const& filepath) {
  std::string line;
  std::vector<std::string> file_contents;
  std::ifstream input_file(filepath);

  if (!input_file)
    return Status(StatusCode::kNotFound, "Cannot open: " + filepath);
  while (std::getline(input_file, line)) {
    file_contents.push_back(line);
  }
  return file_contents;
}

class GeneratorIntegrationTest : public testing::TestWithParam<std::string> {
 protected:
  void SetUp() override {
    auto run_integration_tests =
        google::cloud::internal::GetEnv(
            "GOOGLE_CLOUD_CPP_GENERATOR_RUN_INTEGRATION_TESTS")
            .value_or("");
    if (run_integration_tests != "yes") {
      GTEST_SKIP();
    }

    EXPECT_EQ(run_integration_tests, "yes");
    ASSERT_TRUE(
        google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_GENERATOR_PROTO_PATH")
            .has_value());
    ASSERT_TRUE(google::cloud::internal::GetEnv(
                    "GOOGLE_CLOUD_CPP_GENERATOR_GOOGLEAPIS_PATH")
                    .has_value());

    // Path to find .proto files distributed with protobuf.
    auto proto_path =
        google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_GENERATOR_PROTO_PATH")
            .value();

    // Path to find .proto files distributed with googleapis/googleapis repo.
    auto googleapis_path = google::cloud::internal::GetEnv(
                               "GOOGLE_CLOUD_CPP_GENERATOR_GOOGLEAPIS_PATH")
                               .value();

    // Path to find .proto files defined for these tests.
    auto code_path =
        google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_GENERATOR_CODE_PATH")
            .value_or("/workspace");

    golden_path_ = google::cloud::internal::GetEnv(
                       "GOOGLE_CLOUD_CPP_GENERATOR_GOLDEN_PATH")
                       .value_or("") +
                   "generator/integration_tests/golden/";

    // Path to location where generated code is written.
    output_path_ = google::cloud::internal::GetEnv(
                       "GOOGLE_CLOUD_CPP_GENERATOR_OUTPUT_PATH")
                       .value_or(::testing::TempDir());
    if (!output_path_.empty() && output_path_.back() != '/') {
      output_path_ += '/';
    }

    google::cloud::generator::Generator generator;
    google::protobuf::compiler::CommandLineInterface cli;
    cli.RegisterGenerator("--cpp_codegen_out", "--cpp_codegen_opt", &generator,
                          "Codegen C++ Generator");

    product_path_ = "generator/integration_tests/golden/";
    copyright_year_ = CurrentCopyrightYear();
    omit_rpc1_ = "Omitted1";
    omit_rpc2_ = "GoldenKitchenSink.Omitted2";
    service_endpoint_env_var_ = "GOLDEN_KITCHEN_SINK_ENDPOINT";
    emulator_endpoint_env_var_ = "GOLDEN_KITCHEN_SINK_EMULATOR_HOST";
    gen_async_rpc1_ = "GetDatabase";
    gen_async_rpc2_ = "DropDatabase";
    retry_code1_ = "GoldenKitchenSink.kInternal";
    retry_code2_ = "kUnavailable";
    retry_code3_ = "GoldenThingAdmin.kDeadlineExceeded";

    std::vector<std::string> args;
    // empty arg keeps first real arg from being ignored.
    args.emplace_back("");
    args.emplace_back("--proto_path=" + proto_path);
    args.emplace_back("--proto_path=" + googleapis_path);
    args.emplace_back("--proto_path=" + code_path);
    args.emplace_back("--cpp_codegen_out=" + output_path_);
    args.emplace_back("--cpp_codegen_opt=product_path=" + product_path_);
    args.emplace_back("--cpp_codegen_opt=copyright_year=" + copyright_year_);
    args.emplace_back("--cpp_codegen_opt=omit_rpc=" + omit_rpc1_);
    args.emplace_back("--cpp_codegen_opt=omit_rpc=" + omit_rpc2_);
    args.emplace_back("--cpp_codegen_opt=service_endpoint_env_var=" +
                      service_endpoint_env_var_);
    args.emplace_back("--cpp_codegen_opt=emulator_endpoint_env_var=" +
                      emulator_endpoint_env_var_);
    args.emplace_back("--cpp_codegen_opt=gen_async_rpc=" + gen_async_rpc1_);
    args.emplace_back("--cpp_codegen_opt=gen_async_rpc=" + gen_async_rpc2_);
    args.emplace_back("--cpp_codegen_opt=retry_status_code=" + retry_code1_);
    args.emplace_back("--cpp_codegen_opt=retry_status_code=" + retry_code2_);
    args.emplace_back("--cpp_codegen_opt=retry_status_code=" + retry_code3_);
    args.emplace_back("generator/integration_tests/test.proto");

    std::vector<char const*> c_args;
    c_args.reserve(args.size());
    for (auto const& arg : args) {
      std::cout << "args : " << arg << "\n";
      c_args.push_back(arg.c_str());
    }

    static int const kResult =
        cli.Run(static_cast<int>(c_args.size()), c_args.data());

    EXPECT_EQ(0, kResult);
  }

  std::string product_path_;
  std::string output_path_;
  std::string golden_path_;
  std::string copyright_year_;
  std::string omit_rpc1_;
  std::string omit_rpc2_;
  std::string service_endpoint_env_var_;
  std::string emulator_endpoint_env_var_;
  std::string gen_async_rpc1_;
  std::string gen_async_rpc2_;
  std::string retry_code1_;
  std::string retry_code2_;
  std::string retry_code3_;
};

TEST_P(GeneratorIntegrationTest, CompareGeneratedToGolden) {
  auto golden_file = ReadFile(absl::StrCat(golden_path_, GetParam()));
  ASSERT_STATUS_OK(golden_file);
  auto generated_file =
      ReadFile(absl::StrCat(output_path_, product_path_, GetParam()));
  ASSERT_STATUS_OK(generated_file);

  EXPECT_THAT(*golden_file,
              ElementsAreArray(generated_file->begin(), generated_file->end()));
}

INSTANTIATE_TEST_SUITE_P(
    Generator, GeneratorIntegrationTest,
    testing::Values(
        "golden_thing_admin_client.h", "golden_thing_admin_client.cc",
        "golden_thing_admin_connection.h", "golden_thing_admin_connection.cc",
        "golden_thing_admin_connection_idempotency_policy.h",
        "golden_thing_admin_connection_idempotency_policy.cc",
        "golden_thing_admin_options.h",
        "internal/golden_thing_admin_logging_decorator.h",
        "internal/golden_thing_admin_logging_decorator.cc",
        "internal/golden_thing_admin_metadata_decorator.h",
        "internal/golden_thing_admin_metadata_decorator.cc",
        "internal/golden_thing_admin_option_defaults.h",
        "internal/golden_thing_admin_option_defaults.cc",
        "internal/golden_thing_admin_retry_traits.h",
        "internal/golden_thing_admin_stub_factory.h",
        "internal/golden_thing_admin_stub_factory.cc",
        "internal/golden_thing_admin_stub.h",
        "internal/golden_thing_admin_stub.cc",
        "mocks/mock_golden_thing_admin_connection.h",
        "golden_kitchen_sink_client.h", "golden_kitchen_sink_client.cc",
        "golden_kitchen_sink_connection.h", "golden_kitchen_sink_connection.cc",
        "golden_kitchen_sink_connection_idempotency_policy.h",
        "golden_kitchen_sink_connection_idempotency_policy.cc",
        "golden_kitchen_sink_options.h",
        "internal/golden_kitchen_sink_logging_decorator.h",
        "internal/golden_kitchen_sink_logging_decorator.cc",
        "internal/golden_kitchen_sink_metadata_decorator.h",
        "internal/golden_kitchen_sink_metadata_decorator.cc",
        "internal/golden_kitchen_sink_option_defaults.h",
        "internal/golden_kitchen_sink_option_defaults.cc",
        "internal/golden_kitchen_sink_retry_traits.h",
        "internal/golden_kitchen_sink_stub_factory.h",
        "internal/golden_kitchen_sink_stub_factory.cc",
        "internal/golden_kitchen_sink_stub.h",
        "internal/golden_kitchen_sink_stub.cc",
        "mocks/mock_golden_kitchen_sink_connection.h"),
    [](testing::TestParamInfo<GeneratorIntegrationTest::ParamType> const&
           info) {
      return absl::StrReplaceAll(std::string(info.param),
                                 {{".", "_"}, {"/", "_"}});
    });

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

#include "google/cloud/internal/absl_str_cat_quiet.h"
#include "google/cloud/internal/absl_str_replace_quiet.h"
#include "google/cloud/internal/getenv.h"
#include "google/cloud/status_or.h"
#include "google/cloud/testing_util/status_matchers.h"
#include "generator/generator.h"
#include "generator/internal/codegen_utils.h"
#include <google/protobuf/compiler/command_line_interface.h>
#include <gmock/gmock.h>
#include <fstream>
#include <iostream>

namespace google {
namespace cloud {
namespace generator_internal {
namespace {

using ::testing::ElementsAreArray;

StatusOr<std::vector<std::string>> ReadFile(std::string const& filepath) {
  std::string line;
  std::vector<std::string> file_contents;
  std::ifstream input_file(filepath);

  if (!input_file)
    return Status(StatusCode::kNotFound, "Cannot open: " + filepath);
  while (std::getline(input_file, line)) {
    file_contents.push_back(line);
  }
  return file_contents;
}

class GeneratorIntegrationTest : public testing::TestWithParam<std::string> {
 protected:
  void SetUp() override {
    auto run_integration_tests =
        google::cloud::internal::GetEnv(
            "GOOGLE_CLOUD_CPP_GENERATOR_RUN_INTEGRATION_TESTS")
            .value_or("");
    if (run_integration_tests != "yes") {
      GTEST_SKIP();
    }

    EXPECT_EQ(run_integration_tests, "yes");
    ASSERT_TRUE(
        google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_GENERATOR_PROTO_PATH")
            .has_value());
    ASSERT_TRUE(google::cloud::internal::GetEnv(
                    "GOOGLE_CLOUD_CPP_GENERATOR_GOOGLEAPIS_PATH")
                    .has_value());

    // Path to find .proto files distributed with protobuf.
    auto proto_path =
        google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_GENERATOR_PROTO_PATH")
            .value();

    // Path to find .proto files distributed with googleapis/googleapis repo.
    auto googleapis_path = google::cloud::internal::GetEnv(
                               "GOOGLE_CLOUD_CPP_GENERATOR_GOOGLEAPIS_PATH")
                               .value();

    // Path to find .proto files defined for these tests.
    auto code_path =
        google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_GENERATOR_CODE_PATH")
            .value_or("/workspace");

    golden_path_ = google::cloud::internal::GetEnv(
                       "GOOGLE_CLOUD_CPP_GENERATOR_GOLDEN_PATH")
                       .value_or("") +
                   "generator/integration_tests/golden/";

    // Path to location where generated code is written.
    output_path_ = google::cloud::internal::GetEnv(
                       "GOOGLE_CLOUD_CPP_GENERATOR_OUTPUT_PATH")
                       .value_or(::testing::TempDir());
    if (!output_path_.empty() && output_path_.back() != '/') {
      output_path_ += '/';
    }

    google::cloud::generator::Generator generator;
    google::protobuf::compiler::CommandLineInterface cli;
    cli.RegisterGenerator("--cpp_codegen_out", "--cpp_codegen_opt", &generator,
                          "Codegen C++ Generator");

    product_path_ = "generator/integration_tests/golden/";
    // The golden files were last generated on 2021, update next time you
    // re-generate said files.
    copyright_year_ = "2021";
    omit_rpc1_ = "Omitted1";
    omit_rpc2_ = "GoldenKitchenSink.Omitted2";
    service_endpoint_env_var_ = "GOLDEN_KITCHEN_SINK_ENDPOINT";
    emulator_endpoint_env_var_ = "GOLDEN_KITCHEN_SINK_EMULATOR_HOST";
    gen_async_rpc1_ = "GetDatabase";
    gen_async_rpc2_ = "DropDatabase";
    retry_code1_ = "GoldenKitchenSink.kInternal";
    retry_code2_ = "kUnavailable";
    retry_code3_ = "GoldenThingAdmin.kDeadlineExceeded";

    std::vector<std::string> args;
    // empty arg keeps first real arg from being ignored.
    args.emplace_back("");
    args.emplace_back("--proto_path=" + proto_path);
    args.emplace_back("--proto_path=" + googleapis_path);
    args.emplace_back("--proto_path=" + code_path);
    args.emplace_back("--cpp_codegen_out=" + output_path_);
    args.emplace_back("--cpp_codegen_opt=product_path=" + product_path_);
    args.emplace_back("--cpp_codegen_opt=copyright_year=" + copyright_year_);
    args.emplace_back("--cpp_codegen_opt=omit_rpc=" + omit_rpc1_);
    args.emplace_back("--cpp_codegen_opt=omit_rpc=" + omit_rpc2_);
    args.emplace_back("--cpp_codegen_opt=service_endpoint_env_var=" +
                      service_endpoint_env_var_);
    args.emplace_back("--cpp_codegen_opt=emulator_endpoint_env_var=" +
                      emulator_endpoint_env_var_);
    args.emplace_back("--cpp_codegen_opt=gen_async_rpc=" + gen_async_rpc1_);
    args.emplace_back("--cpp_codegen_opt=gen_async_rpc=" + gen_async_rpc2_);
    args.emplace_back("--cpp_codegen_opt=retry_status_code=" + retry_code1_);
    args.emplace_back("--cpp_codegen_opt=retry_status_code=" + retry_code2_);
    args.emplace_back("--cpp_codegen_opt=retry_status_code=" + retry_code3_);
    args.emplace_back("generator/integration_tests/test.proto");

    std::vector<char const*> c_args;
    c_args.reserve(args.size());
    for (auto const& arg : args) {
      std::cout << "args : " << arg << "\n";
      c_args.push_back(arg.c_str());
    }

    static int const kResult =
        cli.Run(static_cast<int>(c_args.size()), c_args.data());

    EXPECT_EQ(0, kResult);
  }

  std::string product_path_;
  std::string output_path_;
  std::string golden_path_;
  std::string copyright_year_;
  std::string omit_rpc1_;
  std::string omit_rpc2_;
  std::string service_endpoint_env_var_;
  std::string emulator_endpoint_env_var_;
  std::string gen_async_rpc1_;
  std::string gen_async_rpc2_;
  std::string retry_code1_;
  std::string retry_code2_;
  std::string retry_code3_;
};

TEST_P(GeneratorIntegrationTest, CompareGeneratedToGolden) {
  auto golden_file = ReadFile(absl::StrCat(golden_path_, GetParam()));
  ASSERT_STATUS_OK(golden_file);
  auto generated_file =
      ReadFile(absl::StrCat(output_path_, product_path_, GetParam()));
  ASSERT_STATUS_OK(generated_file);

  EXPECT_THAT(*golden_file,
              ElementsAreArray(generated_file->begin(), generated_file->end()));
}

INSTANTIATE_TEST_SUITE_P(
    Generator, GeneratorIntegrationTest,
    testing::Values(
        "golden_thing_admin_client.h", "golden_thing_admin_client.cc",
        "golden_thing_admin_connection.h", "golden_thing_admin_connection.cc",
        "golden_thing_admin_connection_idempotency_policy.h",
        "golden_thing_admin_connection_idempotency_policy.cc",
        "golden_thing_admin_options.h",
        "internal/golden_thing_admin_logging_decorator.h",
        "internal/golden_thing_admin_logging_decorator.cc",
        "internal/golden_thing_admin_metadata_decorator.h",
        "internal/golden_thing_admin_metadata_decorator.cc",
        "internal/golden_thing_admin_option_defaults.h",
        "internal/golden_thing_admin_option_defaults.cc",
        "internal/golden_thing_admin_retry_traits.h",
        "internal/golden_thing_admin_stub_factory.h",
        "internal/golden_thing_admin_stub_factory.cc",
        "internal/golden_thing_admin_stub.h",
        "internal/golden_thing_admin_stub.cc",
        "mocks/mock_golden_thing_admin_connection.h",
        "golden_kitchen_sink_client.h", "golden_kitchen_sink_client.cc",
        "golden_kitchen_sink_connection.h", "golden_kitchen_sink_connection.cc",
        "golden_kitchen_sink_connection_idempotency_policy.h",
        "golden_kitchen_sink_connection_idempotency_policy.cc",
        "golden_kitchen_sink_options.h",
        "internal/golden_kitchen_sink_logging_decorator.h",
        "internal/golden_kitchen_sink_logging_decorator.cc",
        "internal/golden_kitchen_sink_metadata_decorator.h",
        "internal/golden_kitchen_sink_metadata_decorator.cc",
        "internal/golden_kitchen_sink_option_defaults.h",
        "internal/golden_kitchen_sink_option_defaults.cc",
        "internal/golden_kitchen_sink_retry_traits.h",
        "internal/golden_kitchen_sink_stub_factory.h",
        "internal/golden_kitchen_sink_stub_factory.cc",
        "internal/golden_kitchen_sink_stub.h",
        "internal/golden_kitchen_sink_stub.cc",
        "mocks/mock_golden_kitchen_sink_connection.h"),
    [](testing::TestParamInfo<GeneratorIntegrationTest::ParamType> const&
           info) {
      return absl::StrReplaceAll(std::string(info.param),
                                 {{".", "_"}, {"/", "_"}});
    });

}  // namespace
}  // namespace generator_internal
}  // namespace cloud
}  // namespace google
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/
/* $Id$ */

/* History of cvs commits:
 *
 * $Log$
 */

#include <TClonesArray.h>

#include <AliLog.h>
#include "AliPHOSTracker.h"
#include "AliPHOSEmcRecPoint.h"
#include "AliESDEvent.h"

//-------------------------------------------------------------------------
//                          PHOS tracker.
// Matches ESD tracks with the PHOS and makes the PID.
//
//-------------------------------------------------------------------------

ClassImp(AliPHOSTracker)

Bool_t AliPHOSTracker::fgDebug = kFALSE ;

// ***** Some geometrical constants (used in PropagateBack)

const Double_t kR=460.+ 9;  // Radial coord. of the centre of EMC module (cm)

const Double_t kAlpha=20.*TMath::Pi()/180.;     // Segmentation angle (rad)
const Double_t kYmax=kR*TMath::Tan(0.5*kAlpha); // Maximal possible y-coord.(cm)
const Double_t kZmax=65.; // Approximately: the maximal possible z-coord.(cm)

AliPHOSTracker::AliPHOSTracker(): AliTracker(), fRunLoader(0) {
  //--------------------------------------------------------------------
  // The default constructor
  //--------------------------------------------------------------------
  for (Int_t i=0; i<5; i++)
      fModules[i]=new TClonesArray("AliPHOSEmcRecPoint",777);
}

AliPHOSTracker::~AliPHOSTracker() {
  //--------------------------------------------------------------------
  // The destructor
  //--------------------------------------------------------------------
  for (Int_t i=0; i<5; i++) {
      (fModules[i])->Delete();
      delete fModules[i];
  }
}

Int_t AliPHOSTracker::LoadClusters(TTree *cTree) {
  //--------------------------------------------------------------------
  // This function loads the PHOS clusters
  //--------------------------------------------------------------------
  TObjArray *arr=NULL;
  TBranch *branch=cTree->GetBranch("PHOSEmcRP");
  if (branch==0) {
    AliError("No branch with the EMC clusters found !");
    return 1;
  }
  branch->SetAddress(&arr);

  Int_t nclusters=0;
  Int_t nentr=(Int_t)branch->GetEntries();
  for (Int_t i=0; i<nentr; i++) {
    if (!branch->GetEvent(i)) continue;
    Int_t ncl=arr->GetEntriesFast();
    while (ncl--) {
      AliPHOSEmcRecPoint *cl=(AliPHOSEmcRecPoint*)arr->UncheckedAt(ncl);

      Int_t m=cl->GetPHOSMod();
      if ((m<1)||(m>5)) {
         AliError("Wrong module index !");
         return 1;
      }

      // Here is how the alignment is treated
      if (!cl->Misalign()) AliWarning("Can't misalign this cluster !");

      cl->SetBit(14,kFALSE); // The clusters are not yet attached to any track

      TClonesArray &module=*fModules[m-1];
      Int_t idx=module.GetEntriesFast();
      new (module[idx]) AliPHOSEmcRecPoint(*cl);

      nclusters++;

    }
  }

  Info("LoadClusters","Number of loaded clusters: %d",nclusters);

  return 0;
}

Int_t AliPHOSTracker::PropagateBack(AliESDEvent *esd) {
  //--------------------------------------------------------------------
  // Called by AliReconstruction
  // Performs the track matching with the PHOS modules
  // Makes the PID
  //--------------------------------------------------------------------

  // The following old function is a bad function: it uses RunLoader ;(
  PropagateBackOld(esd);

  Int_t nt=esd->GetNumberOfTracks();

  // *** Select and sort the ESD track in accordance with their quality
  Double_t *quality=new Double_t[nt];
  Int_t *index=new Int_t[nt];
  for (Int_t i=0; i<nt; i++) {
     AliESDtrack *esdTrack=esd->GetTrack(i);
     quality[i] = esdTrack->GetSigmaY2() + esdTrack->GetSigmaZ2();
  }
  TMath::Sort(nt,quality,index,kFALSE);

  // *** Start the matching
  Double_t bz=GetBz();
  Int_t matched=0;
  for (Int_t i=0; i<nt; i++) {
     AliESDtrack *esdTrack=esd->GetTrack(index[i]);

     // Skip the tracks having "wrong" status (has to be checked/tuned)
     ULong_t status = esdTrack->GetStatus();
     if ((status & AliESDtrack::kTRDout)   == 0) continue;
     if ((status & AliESDtrack::kTRDrefit) == 1) continue;

     AliExternalTrackParam t(*esdTrack);

     Int_t isec=Int_t(t.GetAlpha()/kAlpha);
     Int_t imod=-isec-2; // PHOS module

     Double_t y;                       // Some tracks do not reach the PHOS
     if (!t.GetYAt(kR,bz,y)) continue; //    because of the bending

     Double_t z; t.GetZAt(kR,bz,z);
     if (TMath::Abs(z) > kZmax) continue; // Some tracks miss the PHOS in Z

     Bool_t ok=kTRUE;
     while (TMath::Abs(y) > kYmax) {   // Find the matching module
        Double_t alp=t.GetAlpha();
        if (y > kYmax) {
	  if (!t.Rotate(alp+kAlpha)) {ok=kFALSE; break;}
          imod--;
        } else if (y < -kYmax) {
	  if (!t.Rotate(alp-kAlpha)) {ok=kFALSE; break;}
          imod++;
        }
        if (!t.GetYAt(kR,bz,y)) {ok=kFALSE; break;}
     }
     if (!ok) continue; // Track rotation failed

     if ((imod<0)||(imod>4)) continue; // Some tracks miss the PHOS in azimuth

     //t.CorrectForMaterial(...); // Correct for the TOF material, if needed
     t.PropagateTo(kR,bz);        // Propagate to the matching module

    // *** Search for the "best" cluster (can be improved)
     TClonesArray &cArray=*fModules[imod];
     Int_t ncl=cArray.GetEntriesFast();
     AliPHOSEmcRecPoint *bestCluster=0;            // The "best" cluster
     Double_t maxd2=400; // (cm^2)
     for (Int_t i=0; i<ncl; i++) {
       AliPHOSEmcRecPoint *c=(AliPHOSEmcRecPoint *)cArray.UncheckedAt(i);

       if (c->TestBit(14)) continue; // This clusters is "used"

       Double_t dy = t.GetY() - c->GetY(), dz = t.GetZ() - c->GetZ();
       Double_t d2 = dy*dy + dz*dz;
       if (d2 < maxd2) {
	  maxd2=d2;
          bestCluster=c;
       }
     }

     if (!bestCluster) continue;   // No reasonable matching found

     bestCluster->SetBit(14,kTRUE); // This clusters is now attached to a track

     matched++;

     // *** Now, do the PID with the "bestCluster"
     // and add the corresponding info to the ESD track pointed by "esdTrack"

     /*
     printf("%e %e %e %e\n",t.GetSign(), t.GetX() - bestCluster->GetX(),
	                                 t.GetY() - bestCluster->GetY(),
	                                 t.GetZ() - bestCluster->GetZ());
     */
  }

  Info("PropagateBack","Number of matched tracks: %d",matched);

  delete[] quality;
  delete[] index;

  return 0;
}

AliCluster *AliPHOSTracker::GetCluster(Int_t index) const {
  //--------------------------------------------------------------------
  // Returns the pointer to a given cluster
  //--------------------------------------------------------------------
  Int_t m=(index & 0xf0000000) >> 28;  // Module number
  Int_t i=(index & 0x0fffffff) >> 00;  // Index within the module

  return (AliCluster*)(fModules[m])->UncheckedAt(i);
}

void AliPHOSTracker::UnloadClusters() {
  //--------------------------------------------------------------------
  // This function unloads the PHOS clusters
  //--------------------------------------------------------------------
  for (Int_t i=0; i<5; i++) (fModules[i])->Delete();
}

// **** The following are bad functions:  they use RunLoader ;(
// **** To be rewritten.

#include "AliPHOSTrackSegmentMakerv1.h"
#include "AliPHOSTrackSegmentMakerv2.h"
#include "AliPHOSPIDv1.h"
#include "AliRunLoader.h"

Int_t AliPHOSTracker::PropagateBackOld(AliESDEvent *esd) {
  // Bad function: it uses RunLoader ;(
  // Creates the tracksegments and Recparticles
  // Makes the PID

  Int_t eventNumber = fRunLoader->GetEventNumber() ;

  TString headerFile(fRunLoader->GetFileName()) ;
  TString branchName(fRunLoader->GetEventFolder()->GetName()) ;

  AliPHOSTrackSegmentMakerv1 tsm(headerFile, branchName);
//  AliPHOSTrackSegmentMakerv2 tsm(headerFile, branchName);
  tsm.SetESD(esd) ;
  AliPHOSPIDv1 pid(headerFile, branchName);
  pid.SetESD(esd) ;

  //PH  SetDebug() ;

  // do current event; the loop over events is done by AliReconstruction::Run()
  tsm.SetEventRange(eventNumber, eventNumber) ;
  pid.SetEventRange(eventNumber, eventNumber) ;
  if ( Debug() ) {
   tsm.ExecuteTask("deb all") ;
   pid.ExecuteTask("deb all") ;
  }
  else {
    tsm.ExecuteTask("") ;
    pid.ExecuteTask("") ;
  }

  return 0;
}

AliPHOSTracker::AliPHOSTracker(AliRunLoader *l): AliTracker(), fRunLoader(l) {
  //--------------------------------------------------------------------
  // Bad constructor:  uses RunLoader ;(
  //--------------------------------------------------------------------
  for (Int_t i=0; i<5; i++)
      fModules[i]=new TClonesArray("AliPHOSEmcRecPoint",777);
}

<commit_msg>Missing header files<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/
/* $Id$ */

/* History of cvs commits:
 *
 * $Log$
 * Revision 1.5  2007/08/03 13:52:16  kharlov
 * Working skeleton of matching the ESD tracks and ESD clusters (Iouri Belikov)
 *
 */

#include <TClonesArray.h>
#include <TMath.h>

#include <AliLog.h>
#include "AliPHOSTracker.h"
#include "AliPHOSEmcRecPoint.h"
#include "AliESDEvent.h"
#include "AliESDtrack.h"

//-------------------------------------------------------------------------
//                          PHOS tracker.
// Matches ESD tracks with the PHOS and makes the PID.
//
//-------------------------------------------------------------------------

ClassImp(AliPHOSTracker)

Bool_t AliPHOSTracker::fgDebug = kFALSE ;

// ***** Some geometrical constants (used in PropagateBack)

const Double_t kR=460.+ 9;  // Radial coord. of the centre of EMC module (cm)

const Double_t kAlpha=20.*TMath::Pi()/180.;     // Segmentation angle (rad)
const Double_t kYmax=kR*TMath::Tan(0.5*kAlpha); // Maximal possible y-coord.(cm)
const Double_t kZmax=65.; // Approximately: the maximal possible z-coord.(cm)

AliPHOSTracker::AliPHOSTracker(): AliTracker(), fRunLoader(0) {
  //--------------------------------------------------------------------
  // The default constructor
  //--------------------------------------------------------------------
  for (Int_t i=0; i<5; i++)
      fModules[i]=new TClonesArray("AliPHOSEmcRecPoint",777);
}

AliPHOSTracker::~AliPHOSTracker() {
  //--------------------------------------------------------------------
  // The destructor
  //--------------------------------------------------------------------
  for (Int_t i=0; i<5; i++) {
      (fModules[i])->Delete();
      delete fModules[i];
  }
}

Int_t AliPHOSTracker::LoadClusters(TTree *cTree) {
  //--------------------------------------------------------------------
  // This function loads the PHOS clusters
  //--------------------------------------------------------------------
  TObjArray *arr=NULL;
  TBranch *branch=cTree->GetBranch("PHOSEmcRP");
  if (branch==0) {
    AliError("No branch with the EMC clusters found !");
    return 1;
  }
  branch->SetAddress(&arr);

  Int_t nclusters=0;
  Int_t nentr=(Int_t)branch->GetEntries();
  for (Int_t i=0; i<nentr; i++) {
    if (!branch->GetEvent(i)) continue;
    Int_t ncl=arr->GetEntriesFast();
    while (ncl--) {
      AliPHOSEmcRecPoint *cl=(AliPHOSEmcRecPoint*)arr->UncheckedAt(ncl);

      Int_t m=cl->GetPHOSMod();
      if ((m<1)||(m>5)) {
         AliError("Wrong module index !");
         return 1;
      }

      // Here is how the alignment is treated
      if (!cl->Misalign()) AliWarning("Can't misalign this cluster !");

      cl->SetBit(14,kFALSE); // The clusters are not yet attached to any track

      TClonesArray &module=*fModules[m-1];
      Int_t idx=module.GetEntriesFast();
      new (module[idx]) AliPHOSEmcRecPoint(*cl);

      nclusters++;

    }
  }

  Info("LoadClusters","Number of loaded clusters: %d",nclusters);

  return 0;
}

Int_t AliPHOSTracker::PropagateBack(AliESDEvent *esd) {
  //--------------------------------------------------------------------
  // Called by AliReconstruction
  // Performs the track matching with the PHOS modules
  // Makes the PID
  //--------------------------------------------------------------------

  // The following old function is a bad function: it uses RunLoader ;(
  PropagateBackOld(esd);

  Int_t nt=esd->GetNumberOfTracks();

  // *** Select and sort the ESD track in accordance with their quality
  Double_t *quality=new Double_t[nt];
  Int_t *index=new Int_t[nt];
  for (Int_t i=0; i<nt; i++) {
     AliESDtrack *esdTrack=esd->GetTrack(i);
     quality[i] = esdTrack->GetSigmaY2() + esdTrack->GetSigmaZ2();
  }
  TMath::Sort(nt,quality,index,kFALSE);

  // *** Start the matching
  Double_t bz=GetBz();
  Int_t matched=0;
  for (Int_t i=0; i<nt; i++) {
     AliESDtrack *esdTrack=esd->GetTrack(index[i]);

     // Skip the tracks having "wrong" status (has to be checked/tuned)
     ULong_t status = esdTrack->GetStatus();
     if ((status & AliESDtrack::kTRDout)   == 0) continue;
     if ((status & AliESDtrack::kTRDrefit) == 1) continue;

     AliExternalTrackParam t(*esdTrack);

     Int_t isec=Int_t(t.GetAlpha()/kAlpha);
     Int_t imod=-isec-2; // PHOS module

     Double_t y;                       // Some tracks do not reach the PHOS
     if (!t.GetYAt(kR,bz,y)) continue; //    because of the bending

     Double_t z; t.GetZAt(kR,bz,z);
     if (TMath::Abs(z) > kZmax) continue; // Some tracks miss the PHOS in Z

     Bool_t ok=kTRUE;
     while (TMath::Abs(y) > kYmax) {   // Find the matching module
        Double_t alp=t.GetAlpha();
        if (y > kYmax) {
	  if (!t.Rotate(alp+kAlpha)) {ok=kFALSE; break;}
          imod--;
        } else if (y < -kYmax) {
	  if (!t.Rotate(alp-kAlpha)) {ok=kFALSE; break;}
          imod++;
        }
        if (!t.GetYAt(kR,bz,y)) {ok=kFALSE; break;}
     }
     if (!ok) continue; // Track rotation failed

     if ((imod<0)||(imod>4)) continue; // Some tracks miss the PHOS in azimuth

     //t.CorrectForMaterial(...); // Correct for the TOF material, if needed
     t.PropagateTo(kR,bz);        // Propagate to the matching module

    // *** Search for the "best" cluster (can be improved)
     TClonesArray &cArray=*fModules[imod];
     Int_t ncl=cArray.GetEntriesFast();
     AliPHOSEmcRecPoint *bestCluster=0;            // The "best" cluster
     Double_t maxd2=400; // (cm^2)
     for (Int_t i=0; i<ncl; i++) {
       AliPHOSEmcRecPoint *c=(AliPHOSEmcRecPoint *)cArray.UncheckedAt(i);

       if (c->TestBit(14)) continue; // This clusters is "used"

       Double_t dy = t.GetY() - c->GetY(), dz = t.GetZ() - c->GetZ();
       Double_t d2 = dy*dy + dz*dz;
       if (d2 < maxd2) {
	  maxd2=d2;
          bestCluster=c;
       }
     }

     if (!bestCluster) continue;   // No reasonable matching found

     bestCluster->SetBit(14,kTRUE); // This clusters is now attached to a track

     matched++;

     // *** Now, do the PID with the "bestCluster"
     // and add the corresponding info to the ESD track pointed by "esdTrack"

     /*
     printf("%e %e %e %e\n",t.GetSign(), t.GetX() - bestCluster->GetX(),
	                                 t.GetY() - bestCluster->GetY(),
	                                 t.GetZ() - bestCluster->GetZ());
     */
  }

  Info("PropagateBack","Number of matched tracks: %d",matched);

  delete[] quality;
  delete[] index;

  return 0;
}

AliCluster *AliPHOSTracker::GetCluster(Int_t index) const {
  //--------------------------------------------------------------------
  // Returns the pointer to a given cluster
  //--------------------------------------------------------------------
  Int_t m=(index & 0xf0000000) >> 28;  // Module number
  Int_t i=(index & 0x0fffffff) >> 00;  // Index within the module

  return (AliCluster*)(fModules[m])->UncheckedAt(i);
}

void AliPHOSTracker::UnloadClusters() {
  //--------------------------------------------------------------------
  // This function unloads the PHOS clusters
  //--------------------------------------------------------------------
  for (Int_t i=0; i<5; i++) (fModules[i])->Delete();
}

// **** The following are bad functions:  they use RunLoader ;(
// **** To be rewritten.

#include "AliPHOSTrackSegmentMakerv1.h"
#include "AliPHOSTrackSegmentMakerv2.h"
#include "AliPHOSPIDv1.h"
#include "AliRunLoader.h"

Int_t AliPHOSTracker::PropagateBackOld(AliESDEvent *esd) {
  // Bad function: it uses RunLoader ;(
  // Creates the tracksegments and Recparticles
  // Makes the PID

  Int_t eventNumber = fRunLoader->GetEventNumber() ;

  TString headerFile(fRunLoader->GetFileName()) ;
  TString branchName(fRunLoader->GetEventFolder()->GetName()) ;

  AliPHOSTrackSegmentMakerv1 tsm(headerFile, branchName);
//  AliPHOSTrackSegmentMakerv2 tsm(headerFile, branchName);
  tsm.SetESD(esd) ;
  AliPHOSPIDv1 pid(headerFile, branchName);
  pid.SetESD(esd) ;

  //PH  SetDebug() ;

  // do current event; the loop over events is done by AliReconstruction::Run()
  tsm.SetEventRange(eventNumber, eventNumber) ;
  pid.SetEventRange(eventNumber, eventNumber) ;
  if ( Debug() ) {
   tsm.ExecuteTask("deb all") ;
   pid.ExecuteTask("deb all") ;
  }
  else {
    tsm.ExecuteTask("") ;
    pid.ExecuteTask("") ;
  }

  return 0;
}

AliPHOSTracker::AliPHOSTracker(AliRunLoader *l): AliTracker(), fRunLoader(l) {
  //--------------------------------------------------------------------
  // Bad constructor:  uses RunLoader ;(
  //--------------------------------------------------------------------
  for (Int_t i=0; i<5; i++)
      fModules[i]=new TClonesArray("AliPHOSEmcRecPoint",777);
}

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#ifndef _Stroika_Foundation_IO_Network_SocketAddress_inl_
#define _Stroika_Foundation_IO_Network_SocketAddress_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
namespace Stroika::Foundation::IO::Network {

    /*
     ********************************************************************************
     *********************** IO::Network::SocketAddress *****************************
     ********************************************************************************
     */
    inline SocketAddress::SocketAddress ()
        : fSocketAddress_{}
    {
    }
    inline SocketAddress::SocketAddress (const sockaddr& iaddr)
    {
        fSocketAddress_ = iaddr;
    }
    inline SocketAddress::SocketAddress (const sockaddr_in& iaddr)
    {
        fSocketAddress_V4_ = iaddr;
    }
    inline SocketAddress::SocketAddress (const sockaddr_in6& iaddr)
    {
        fSocketAddress_V6_ = iaddr;
    }
    inline SocketAddress::SocketAddress (const sockaddr_storage& iaddr)
        : fSocketAddress_ ()
    {
        fSocketAddressStorage_ = iaddr;
    }
    inline SocketAddress::SocketAddress (const InternetAddress& iaddr, uint16_t portNumber)
    {
        switch (iaddr.GetAddressFamily ()) {
            case InternetAddress::AddressFamily::V4: {
                fSocketAddress_V4_.sin_family = AF_INET;
                DISABLE_COMPILER_CLANG_WARNING_START ("clang diagnostic ignored \"-Wdeprecated\""); // macro uses 'register' - htons not deprecated
                fSocketAddress_V4_.sin_port = htons (portNumber);                                   //NB no '::' cuz some systems use macro
                DISABLE_COMPILER_CLANG_WARNING_END ("clang diagnostic ignored \"-Wdeprecated\"");
                fSocketAddress_V4_.sin_addr = iaddr.As<in_addr> ();
            } break;
            case InternetAddress::AddressFamily::V6: {
                Assert (sizeof (sockaddr_in) == sizeof (sockaddr));
                fSocketAddress_V6_.sin6_family = AF_INET6;
                DISABLE_COMPILER_CLANG_WARNING_START ("clang diagnostic ignored \"-Wdeprecated\""); // macro uses 'register' - htons not deprecated
                fSocketAddress_V6_.sin6_port = htons (portNumber);                                  //NB no ':' cuz some systems use macro
                DISABLE_COMPILER_CLANG_WARNING_END ("clang diagnostic ignored \"-Wdeprecated\"");
                fSocketAddress_V6_.sin6_addr = iaddr.As<in6_addr> ();
            } break;
            default: {
                // just leave blank - no assert?
                fSocketAddress_ = sockaddr{};
            } break;
        }
    }
    inline bool SocketAddress::empty () const
    {
        return fSocketAddress_.sa_family == AF_UNSPEC;
        //constexpr sockaddr kZero_ = { 0 };
        //return ::memcmp (&fSocketAddress_, &kZero_, sizeof (kZero_)) == 0;
    }
    inline void SocketAddress::clear ()
    {
        fSocketAddress_ = sockaddr{};
        Assert (fSocketAddress_.sa_family == AF_UNSPEC);
    }
    inline SocketAddress::FamilyType SocketAddress::GetAddressFamily () const
    {
        return static_cast<FamilyType> (fSocketAddress_.sa_family);
    }
    inline size_t SocketAddress::GetRequiredSize () const
    {
        switch (fSocketAddress_.sa_family) {
            case AF_INET: {
                return sizeof (fSocketAddress_V4_);
            }
            case AF_INET6: {
                return sizeof (fSocketAddress_V6_);
            }
            default: {
                return sizeof (fSocketAddressStorage_);
            }
        }
    }
    inline bool SocketAddress::IsInternetAddress () const
    {
        return fSocketAddress_.sa_family == AF_INET or fSocketAddress_.sa_family == AF_INET6;
    }
    inline InternetAddress SocketAddress::GetInternetAddress () const
    {
        Require (IsInternetAddress ());
        switch (fSocketAddress_.sa_family) {
            case AF_INET: {
                return InternetAddress (fSocketAddress_V4_.sin_addr);
            }
            case AF_INET6: {
                return InternetAddress (fSocketAddress_V6_.sin6_addr);
            }
            default: {
                AssertNotReached ();
                return InternetAddress{};
            }
        }
    }
    inline uint16_t SocketAddress::GetPort () const
    {
        Require (IsInternetAddress ());
        switch (fSocketAddress_.sa_family) {
            case AF_INET: {
                DISABLE_COMPILER_CLANG_WARNING_START ("clang diagnostic ignored \"-Wdeprecated\""); // macro uses 'register' - htons not deprecated
                return ntohs (fSocketAddress_V4_.sin_port);                                         //NB no ':' cuz some systems use macro
                DISABLE_COMPILER_CLANG_WARNING_END ("clang diagnostic ignored \"-Wdeprecated\"");   // macro uses 'register' - htons not deprecated
            }
            case AF_INET6: {
                DISABLE_COMPILER_CLANG_WARNING_START ("clang diagnostic ignored \"-Wdeprecated\""); // macro uses 'register' - htons not deprecated
                return ntohs (fSocketAddress_V6_.sin6_port);                                        //NB no ':' cuz some systems use macro
                DISABLE_COMPILER_CLANG_WARNING_END ("clang diagnostic ignored \"-Wdeprecated\"");   // macro uses 'register' - htons not deprecated
            }
            default: {
                AssertNotReached ();
                return 0;
            }
        }
    }
    template <>
    inline sockaddr SocketAddress::As<sockaddr> () const
    {
        Require (fSocketAddress_.sa_family == AF_INET or fSocketAddress_.sa_family == AF_UNSPEC); // You probably meant to use sockaddr_storage (to support IPv6)
        return fSocketAddress_;
    }
    template <>
    inline sockaddr_storage SocketAddress::As<sockaddr_storage> () const
    {
        return fSocketAddressStorage_;
    }
    template <>
    inline sockaddr_in SocketAddress::As<sockaddr_in> () const
    {
        Require (fSocketAddress_.sa_family == AF_INET or fSocketAddress_.sa_family == AF_UNSPEC);
        return fSocketAddress_V4_;
    }
    template <>
    inline sockaddr_in6 SocketAddress::As<sockaddr_in6> () const
    {
        Require (fSocketAddress_.sa_family == AF_INET6 or fSocketAddress_.sa_family == AF_UNSPEC);
        return fSocketAddress_V6_;
    }

}

#endif /*_Stroika_Foundation_IO_Network_SocketAddress_inl_*/
<commit_msg>fixed serious bug with SocketAddress (regression) - must clear out (zero) unused fields for socketaddress_v6<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#ifndef _Stroika_Foundation_IO_Network_SocketAddress_inl_
#define _Stroika_Foundation_IO_Network_SocketAddress_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
namespace Stroika::Foundation::IO::Network {

    /*
     ********************************************************************************
     *********************** IO::Network::SocketAddress *****************************
     ********************************************************************************
     */
    inline SocketAddress::SocketAddress ()
        : fSocketAddress_{}
    {
    }
    inline SocketAddress::SocketAddress (const sockaddr& iaddr)
    {
        fSocketAddress_ = iaddr;
    }
    inline SocketAddress::SocketAddress (const sockaddr_in& iaddr)
    {
        fSocketAddress_V4_ = iaddr;
    }
    inline SocketAddress::SocketAddress (const sockaddr_in6& iaddr)
    {
        fSocketAddress_V6_ = iaddr;
    }
    inline SocketAddress::SocketAddress (const sockaddr_storage& iaddr)
        : fSocketAddress_ ()
    {
        fSocketAddressStorage_ = iaddr;
    }
    inline SocketAddress::SocketAddress (const InternetAddress& iaddr, uint16_t portNumber)
    {
        switch (iaddr.GetAddressFamily ()) {
            case InternetAddress::AddressFamily::V4: {
                fSocketAddress_V4_            = sockaddr_in{};
                fSocketAddress_V4_.sin_family = AF_INET;
                DISABLE_COMPILER_CLANG_WARNING_START ("clang diagnostic ignored \"-Wdeprecated\""); // macro uses 'register' - htons not deprecated
                fSocketAddress_V4_.sin_port = htons (portNumber);                                   //NB no '::' cuz some systems use macro
                DISABLE_COMPILER_CLANG_WARNING_END ("clang diagnostic ignored \"-Wdeprecated\"");
                fSocketAddress_V4_.sin_addr = iaddr.As<in_addr> ();
            } break;
            case InternetAddress::AddressFamily::V6: {
                fSocketAddress_V6_             = sockaddr_in6{};
                fSocketAddress_V6_.sin6_family = AF_INET6;
                DISABLE_COMPILER_CLANG_WARNING_START ("clang diagnostic ignored \"-Wdeprecated\""); // macro uses 'register' - htons not deprecated
                fSocketAddress_V6_.sin6_port = htons (portNumber);                                  //NB no ':' cuz some systems use macro
                DISABLE_COMPILER_CLANG_WARNING_END ("clang diagnostic ignored \"-Wdeprecated\"");
                fSocketAddress_V6_.sin6_addr = iaddr.As<in6_addr> ();
            } break;
            default: {
                // just leave blank - no assert?
                fSocketAddress_ = sockaddr{};
            } break;
        }
    }
    inline bool SocketAddress::empty () const
    {
        return fSocketAddress_.sa_family == AF_UNSPEC;
        //constexpr sockaddr kZero_ = { 0 };
        //return ::memcmp (&fSocketAddress_, &kZero_, sizeof (kZero_)) == 0;
    }
    inline void SocketAddress::clear ()
    {
        fSocketAddress_ = sockaddr{};
        Assert (fSocketAddress_.sa_family == AF_UNSPEC);
    }
    inline SocketAddress::FamilyType SocketAddress::GetAddressFamily () const
    {
        return static_cast<FamilyType> (fSocketAddress_.sa_family);
    }
    inline size_t SocketAddress::GetRequiredSize () const
    {
        switch (fSocketAddress_.sa_family) {
            case AF_INET: {
                return sizeof (fSocketAddress_V4_);
            }
            case AF_INET6: {
                return sizeof (fSocketAddress_V6_);
            }
            default: {
                return sizeof (fSocketAddressStorage_);
            }
        }
    }
    inline bool SocketAddress::IsInternetAddress () const
    {
        return fSocketAddress_.sa_family == AF_INET or fSocketAddress_.sa_family == AF_INET6;
    }
    inline InternetAddress SocketAddress::GetInternetAddress () const
    {
        Require (IsInternetAddress ());
        switch (fSocketAddress_.sa_family) {
            case AF_INET: {
                return InternetAddress (fSocketAddress_V4_.sin_addr);
            }
            case AF_INET6: {
                return InternetAddress (fSocketAddress_V6_.sin6_addr);
            }
            default: {
                AssertNotReached ();
                return InternetAddress{};
            }
        }
    }
    inline uint16_t SocketAddress::GetPort () const
    {
        Require (IsInternetAddress ());
        switch (fSocketAddress_.sa_family) {
            case AF_INET: {
                DISABLE_COMPILER_CLANG_WARNING_START ("clang diagnostic ignored \"-Wdeprecated\""); // macro uses 'register' - htons not deprecated
                return ntohs (fSocketAddress_V4_.sin_port);                                         //NB no ':' cuz some systems use macro
                DISABLE_COMPILER_CLANG_WARNING_END ("clang diagnostic ignored \"-Wdeprecated\"");   // macro uses 'register' - htons not deprecated
            }
            case AF_INET6: {
                DISABLE_COMPILER_CLANG_WARNING_START ("clang diagnostic ignored \"-Wdeprecated\""); // macro uses 'register' - htons not deprecated
                return ntohs (fSocketAddress_V6_.sin6_port);                                        //NB no ':' cuz some systems use macro
                DISABLE_COMPILER_CLANG_WARNING_END ("clang diagnostic ignored \"-Wdeprecated\"");   // macro uses 'register' - htons not deprecated
            }
            default: {
                AssertNotReached ();
                return 0;
            }
        }
    }
    template <>
    inline sockaddr SocketAddress::As<sockaddr> () const
    {
        Require (fSocketAddress_.sa_family == AF_INET or fSocketAddress_.sa_family == AF_UNSPEC); // You probably meant to use sockaddr_storage (to support IPv6)
        return fSocketAddress_;
    }
    template <>
    inline sockaddr_storage SocketAddress::As<sockaddr_storage> () const
    {
        return fSocketAddressStorage_;
    }
    template <>
    inline sockaddr_in SocketAddress::As<sockaddr_in> () const
    {
        Require (fSocketAddress_.sa_family == AF_INET or fSocketAddress_.sa_family == AF_UNSPEC);
        return fSocketAddress_V4_;
    }
    template <>
    inline sockaddr_in6 SocketAddress::As<sockaddr_in6> () const
    {
        Require (fSocketAddress_.sa_family == AF_INET6 or fSocketAddress_.sa_family == AF_UNSPEC);
        return fSocketAddress_V6_;
    }

}

#endif /*_Stroika_Foundation_IO_Network_SocketAddress_inl_*/
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "cling/MetaProcessor/MetaProcessor.h"

#include "InputValidator.h"
#include "cling/Interpreter/Interpreter.h"

#include "clang/Basic/FileManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/Support/Path.h"

using namespace clang;

namespace cling {

  MetaProcessor::MetaProcessor(Interpreter& interp) : m_Interp(interp) {
    m_InputValidator.reset(new InputValidator());
  }

  MetaProcessor::~MetaProcessor() {}

  int MetaProcessor::process(const char* input_text, Value* result /*=0*/) {
    if (!input_text) { // null pointer, nothing to do.
      return 0;
    }
    if (!input_text[0]) { // empty string, nothing to do.
      return m_InputValidator->getExpectedIndent();
    }
    std::string input_line(input_text);
    if (input_line == "\n") { // just a blank line, nothing to do.
      return 0;
    }
    //  Check for and handle any '.' commands.
    bool was_meta = false;
    if ((input_line[0] == '.') && (input_line.size() > 1)) {
      was_meta = ProcessMeta(input_line, result);
    }
    if (was_meta) {
      return 0;
    }

    // Check if the current statement is now complete. If not, return to
    // prompt for more.
    if (m_InputValidator->Validate(input_line, m_Interp.getCI()->getLangOpts())
        == InputValidator::kIncomplete) {
      return m_InputValidator->getExpectedIndent();
    }

    //  We have a complete statement, compile and execute it.
    std::string input = m_InputValidator->TakeInput();
    m_InputValidator->Reset();
    m_Interp.processLine(input, m_Options.RawInput, result);

    return 0;
  }

  MetaProcessorOpts& MetaProcessor::getMetaProcessorOpts() {
    // Take interpreter's state
    m_Options.PrintingAST = m_Interp.isPrintingAST();
    return m_Options;
  }

  bool MetaProcessor::ProcessMeta(const std::string& input_line, Value* result){

   llvm::MemoryBuffer* MB = llvm::MemoryBuffer::getMemBuffer(input_line);
   LangOptions LO;
   LO.C99 = 1;
   // necessary for the @ symbol
   LO.ObjC1 = 1;
   Lexer RawLexer(SourceLocation(), LO, MB->getBufferStart(),
                  MB->getBufferStart(), MB->getBufferEnd());
   Token Tok;

   RawLexer.LexFromRawLexer(Tok);
   if (Tok.isNot(tok::period))
     return false;

   // Read the command
   RawLexer.LexFromRawLexer(Tok);
   if (!Tok.isAnyIdentifier() && Tok.isNot(tok::at))
     return false;

   const std::string Command = GetRawTokenName(Tok);
   std::string Param;

   //  .q //Quits
   if (Command == "q") {
      m_Options.Quitting = true;
      return true;
   }
   //  .L <filename>   //  Load code fragment.
   else if (Command == "L") {
     // TODO: Additional checks on params
     bool success
       = m_Interp.loadFile(SanitizeArg(ReadToEndOfBuffer(RawLexer, MB)));
     if (!success) {
       llvm::errs() << "Load file failed.\n";
     }
     return true;
   }
   //  .(x|X) <filename> //  Execute function from file, function name is
   //                    //  filename without extension.
   else if ((Command == "x") || (Command == "X")) {
     // TODO: Additional checks on params
     llvm::sys::Path path(SanitizeArg(ReadToEndOfBuffer(RawLexer, MB)));

     if (!path.isValid())
       return false;

     bool success = executeFile(path.c_str(), result);
      if (!success) {
        llvm::errs()<< "Execute file failed.\n";
      }
      return true;
   }
   //  .printAST [0|1]  // Toggle the printing of the AST or if 1 or 0 is given
   //                   // enable or disable it.
   else if (Command == "printAST") {
     // Check for params
     RawLexer.LexFromRawLexer(Tok);
     if (Tok.isNot(tok::numeric_constant) && Tok.isNot(tok::eof))
       return false;

     if (Tok.is(tok::eof)) {
       // toggle:
       bool print = !m_Interp.isPrintingAST();
       m_Interp.enablePrintAST(print);
       llvm::errs()<< (print?"P":"Not p") << "rinting AST\n";
     } else {
       Param = GetRawTokenName(Tok);

       if (Param == "0")
         m_Interp.enablePrintAST(false);
       else
         m_Interp.enablePrintAST(true);
     }

     m_Options.PrintingAST = m_Interp.isPrintingAST();
     return true;
   }
   //  .rawInput [0|1]  // Toggle the raw input or if 1 or 0 is given enable
   //                   // or disable it.
   else if (Command == "rawInput") {
     // Check for params
     RawLexer.LexFromRawLexer(Tok);
     if (Tok.isNot(tok::numeric_constant) && Tok.isNot(tok::eof))
       return false;

     if (Tok.is(tok::eof)) {
       // toggle:
       m_Options.RawInput = !m_Options.RawInput;
       llvm::errs() << (m_Options.RawInput?"U":"Not u") << "sing raw input\n";
     } else {
       Param = GetRawTokenName(Tok);

       if (Param == "0")
         m_Options.RawInput = false;
       else
         m_Options.RawInput = true;
     }
     return true;
   }
   //
   //  .U <filename>
   //
   //  Unload code fragment.
   //
   //if (cmd_char == 'U') {
   //   llvm::sys::Path path(param);
   //   if (path.isDynamicLibrary()) {
   //      std::cerr << "[i] Failure: cannot unload shared libraries yet!"
   //                << std::endl;
   //   }
   //   bool success = m_Interp.unloadFile(param);
   //   if (!success) {
   //      //fprintf(stderr, "Unload file failed.\n");
   //   }
   //   return true;
   //}
   //
   //  Unrecognized command.
   //
   //fprintf(stderr, "Unrecognized command.\n");
   else if (Command == "I") {

     // Check for params
     llvm::sys::Path path(SanitizeArg(ReadToEndOfBuffer(RawLexer, MB)));

     if (path.isEmpty())
       m_Interp.DumpIncludePath();
     else {
       // TODO: Additional checks on params

       if (path.isValid())
         m_Interp.AddIncludePath(path.c_str());
       else
         return false;
     }
     return true;
   }
  // Cancel the multiline input that has been requested
   else if (Command == "@") {
     m_InputValidator->Reset();
     return true;
   }
   // Enable/Disable DynamicExprTransformer
   else if (Command == "dynamicExtensions") {
     // Check for params
     RawLexer.LexFromRawLexer(Tok);
     if (Tok.isNot(tok::numeric_constant) && Tok.isNot(tok::eof))
       return false;

     if (Tok.is(tok::eof)) {
       // toggle:
       bool dynlookup = !m_Interp.isDynamicLookupEnabled();
       m_Interp.enableDynamicLookup(dynlookup);
       llvm::errs() << (dynlookup?"U":"Not u") <<"sing dynamic extensions\n";
     } else {
       Param = GetRawTokenName(Tok);

       if (Param == "0")
         m_Interp.enableDynamicLookup(false);
       else
         m_Interp.enableDynamicLookup(true);
     }

     return true;
   }
   // Print Help
   else if (Command == "help") {
     PrintCommandHelp();
     return true;
   }
   // Print the loaded files
   else if (Command == "file") {
     PrintFileStats();
     return true;
   }

   return false;
  }

  std::string MetaProcessor::GetRawTokenName(const Token& Tok) {

    assert(!Tok.needsCleaning() && "Not implemented yet");

    switch (Tok.getKind()) {
    default:
      assert("Unknown token");
      return "";
    case tok::at:
      return "@";
    case tok::l_paren:
      return "(";
    case tok::r_paren:
      return ")";
    case tok::period:
      return ".";
    case tok::slash:
      return "/";
    case tok::numeric_constant:
      return StringRef(Tok.getLiteralData(), Tok.getLength()).str();
    case tok::raw_identifier:
      return StringRef(Tok.getRawIdentifierData(), Tok.getLength()).str();
    }
  }

  llvm::StringRef MetaProcessor::ReadToEndOfBuffer(Lexer& RawLexer,
                                                   llvm::MemoryBuffer* MB) {
    const char* CurPtr = RawLexer.getBufferLocation();
    if (CurPtr == MB->getBufferEnd()) {
      // Already at end of the buffer, return just the zero byte at the end.
      return StringRef(CurPtr, 0);
    }
    Token TmpTok;
    RawLexer.getAndAdvanceChar(CurPtr, TmpTok);
    return StringRef(CurPtr, MB->getBufferSize()-(CurPtr-MB->getBufferStart()));
  }

  llvm::StringRef MetaProcessor::SanitizeArg(const std::string& Str) {
    if(Str.empty())
      return Str;

    size_t begins = Str.find_first_not_of(" \t\n");
    size_t ends = Str.find_last_not_of(" \t\n") + 1;

    if (begins == std::string::npos)
      ends = begins + 1;

    return llvm::StringRef(Str.c_str(), ends - begins);
  }

  void MetaProcessor::PrintCommandHelp() {
    llvm::outs() << "Cling meta commands usage\n";
    llvm::outs() << "Syntax: .Command [arg0 arg1 ... argN]\n";
    llvm::outs() << "\n";
    llvm::outs() << ".q\t\t\t\t - Exit the program\n";
    llvm::outs() << ".L <filename>\t\t\t - Load file or library\n";
    llvm::outs() << ".(x|X) <filename>[args]\t\t - Same as .L and runs a ";
    llvm::outs() << "function with signature ret_type filename(args)\n";
    llvm::outs() << ".I [path]\t\t\t - Shows the include path. If a path is ";
    llvm::outs() << "given - adds the path to the list with the include paths\n";
    llvm::outs() << ".@ \t\t\t\t - Cancels and ignores the multiline input\n";
    llvm::outs() << ".rawInput [0|1]\t\t\t - Toggles the wrapping and printing ";
    llvm::outs() << "the execution results of the input\n";
    llvm::outs() << ".dynamicExtensions [0|1]\t - Toggles the use of the ";
    llvm::outs() << "dynamic scopes and the late binding\n";
    llvm::outs() << ".printAST [0|1]\t\t\t - Toggles the printing of input's ";
    llvm::outs() << "corresponding AST nodes\n";
    llvm::outs() << ".help\t\t\t\t - Shows this information\n";
  }

  void MetaProcessor::PrintFileStats() {
    const SourceManager& SM = m_Interp.getCI()->getSourceManager();
    SM.getFileManager().PrintStats();

    llvm::outs() << "\n***\n\n";

    for (SourceManager::fileinfo_iterator I = SM.fileinfo_begin(),
           E = SM.fileinfo_end(); I != E; ++I) {
      llvm::outs() << (*I).first->getName();
      llvm::outs() << "\n";
    }

  }

  // Run a file: .x file[(args)]
  bool MetaProcessor::executeFile(const std::string& fileWithArgs,
                                  Value* result) {
    // Look for start of parameters:

    typedef std::pair<llvm::StringRef,llvm::StringRef> StringRefPair;

    StringRefPair pairFileArgs = llvm::StringRef(fileWithArgs).split('(');
    if (pairFileArgs.second.empty()) {
      pairFileArgs.second = ")";
    }
    StringRefPair pairPathFile = pairFileArgs.first.rsplit('/');
    if (pairPathFile.second.empty()) {
       pairPathFile.second = pairPathFile.first;
    }
    StringRefPair pairFuncExt = pairPathFile.second.rsplit('.');

    //fprintf(stderr, "funcname: %s\n", pairFuncExt.first.data());

    Interpreter::CompilationResult interpRes
       = m_Interp.processLine(std::string("#include \"")
                              + pairFileArgs.first.str()
                              + std::string("\""), true /*raw*/);

    if (interpRes != Interpreter::kFailure) {
       std::string expression = pairFuncExt.first.str()
          + "(" + pairFileArgs.second.str();
       interpRes = m_Interp.processLine(expression, false /*not raw*/, result);
    }

    return (interpRes != Interpreter::kFailure);
  }
} // end namespace cling

<commit_msg>Use evaluate and declare where possible.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "cling/MetaProcessor/MetaProcessor.h"

#include "InputValidator.h"
#include "cling/Interpreter/Interpreter.h"

#include "clang/Basic/FileManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/Support/Path.h"

using namespace clang;

namespace cling {

  MetaProcessor::MetaProcessor(Interpreter& interp) : m_Interp(interp) {
    m_InputValidator.reset(new InputValidator());
  }

  MetaProcessor::~MetaProcessor() {}

  int MetaProcessor::process(const char* input_text, Value* result /*=0*/) {
    if (!input_text) { // null pointer, nothing to do.
      return 0;
    }
    if (!input_text[0]) { // empty string, nothing to do.
      return m_InputValidator->getExpectedIndent();
    }
    std::string input_line(input_text);
    if (input_line == "\n") { // just a blank line, nothing to do.
      return 0;
    }
    //  Check for and handle any '.' commands.
    bool was_meta = false;
    if ((input_line[0] == '.') && (input_line.size() > 1)) {
      was_meta = ProcessMeta(input_line, result);
    }
    if (was_meta) {
      return 0;
    }

    // Check if the current statement is now complete. If not, return to
    // prompt for more.
    if (m_InputValidator->Validate(input_line, m_Interp.getCI()->getLangOpts())
        == InputValidator::kIncomplete) {
      return m_InputValidator->getExpectedIndent();
    }

    //  We have a complete statement, compile and execute it.
    std::string input = m_InputValidator->TakeInput();
    m_InputValidator->Reset();
    m_Interp.processLine(input, m_Options.RawInput, result);

    return 0;
  }

  MetaProcessorOpts& MetaProcessor::getMetaProcessorOpts() {
    // Take interpreter's state
    m_Options.PrintingAST = m_Interp.isPrintingAST();
    return m_Options;
  }

  bool MetaProcessor::ProcessMeta(const std::string& input_line, Value* result){

   llvm::MemoryBuffer* MB = llvm::MemoryBuffer::getMemBuffer(input_line);
   LangOptions LO;
   LO.C99 = 1;
   // necessary for the @ symbol
   LO.ObjC1 = 1;
   Lexer RawLexer(SourceLocation(), LO, MB->getBufferStart(),
                  MB->getBufferStart(), MB->getBufferEnd());
   Token Tok;

   RawLexer.LexFromRawLexer(Tok);
   if (Tok.isNot(tok::period))
     return false;

   // Read the command
   RawLexer.LexFromRawLexer(Tok);
   if (!Tok.isAnyIdentifier() && Tok.isNot(tok::at))
     return false;

   const std::string Command = GetRawTokenName(Tok);
   std::string Param;

   //  .q //Quits
   if (Command == "q") {
      m_Options.Quitting = true;
      return true;
   }
   //  .L <filename>   //  Load code fragment.
   else if (Command == "L") {
     // TODO: Additional checks on params
     bool success
       = m_Interp.loadFile(SanitizeArg(ReadToEndOfBuffer(RawLexer, MB)));
     if (!success) {
       llvm::errs() << "Load file failed.\n";
     }
     return true;
   }
   //  .(x|X) <filename> //  Execute function from file, function name is
   //                    //  filename without extension.
   else if ((Command == "x") || (Command == "X")) {
     // TODO: Additional checks on params
     llvm::sys::Path path(SanitizeArg(ReadToEndOfBuffer(RawLexer, MB)));

     if (!path.isValid())
       return false;

     bool success = executeFile(path.c_str(), result);
      if (!success) {
        llvm::errs()<< "Execute file failed.\n";
      }
      return true;
   }
   //  .printAST [0|1]  // Toggle the printing of the AST or if 1 or 0 is given
   //                   // enable or disable it.
   else if (Command == "printAST") {
     // Check for params
     RawLexer.LexFromRawLexer(Tok);
     if (Tok.isNot(tok::numeric_constant) && Tok.isNot(tok::eof))
       return false;

     if (Tok.is(tok::eof)) {
       // toggle:
       bool print = !m_Interp.isPrintingAST();
       m_Interp.enablePrintAST(print);
       llvm::errs()<< (print?"P":"Not p") << "rinting AST\n";
     } else {
       Param = GetRawTokenName(Tok);

       if (Param == "0")
         m_Interp.enablePrintAST(false);
       else
         m_Interp.enablePrintAST(true);
     }

     m_Options.PrintingAST = m_Interp.isPrintingAST();
     return true;
   }
   //  .rawInput [0|1]  // Toggle the raw input or if 1 or 0 is given enable
   //                   // or disable it.
   else if (Command == "rawInput") {
     // Check for params
     RawLexer.LexFromRawLexer(Tok);
     if (Tok.isNot(tok::numeric_constant) && Tok.isNot(tok::eof))
       return false;

     if (Tok.is(tok::eof)) {
       // toggle:
       m_Options.RawInput = !m_Options.RawInput;
       llvm::errs() << (m_Options.RawInput?"U":"Not u") << "sing raw input\n";
     } else {
       Param = GetRawTokenName(Tok);

       if (Param == "0")
         m_Options.RawInput = false;
       else
         m_Options.RawInput = true;
     }
     return true;
   }
   //
   //  .U <filename>
   //
   //  Unload code fragment.
   //
   //if (cmd_char == 'U') {
   //   llvm::sys::Path path(param);
   //   if (path.isDynamicLibrary()) {
   //      std::cerr << "[i] Failure: cannot unload shared libraries yet!"
   //                << std::endl;
   //   }
   //   bool success = m_Interp.unloadFile(param);
   //   if (!success) {
   //      //fprintf(stderr, "Unload file failed.\n");
   //   }
   //   return true;
   //}
   //
   //  Unrecognized command.
   //
   //fprintf(stderr, "Unrecognized command.\n");
   else if (Command == "I") {

     // Check for params
     llvm::sys::Path path(SanitizeArg(ReadToEndOfBuffer(RawLexer, MB)));

     if (path.isEmpty())
       m_Interp.DumpIncludePath();
     else {
       // TODO: Additional checks on params

       if (path.isValid())
         m_Interp.AddIncludePath(path.c_str());
       else
         return false;
     }
     return true;
   }
  // Cancel the multiline input that has been requested
   else if (Command == "@") {
     m_InputValidator->Reset();
     return true;
   }
   // Enable/Disable DynamicExprTransformer
   else if (Command == "dynamicExtensions") {
     // Check for params
     RawLexer.LexFromRawLexer(Tok);
     if (Tok.isNot(tok::numeric_constant) && Tok.isNot(tok::eof))
       return false;

     if (Tok.is(tok::eof)) {
       // toggle:
       bool dynlookup = !m_Interp.isDynamicLookupEnabled();
       m_Interp.enableDynamicLookup(dynlookup);
       llvm::errs() << (dynlookup?"U":"Not u") <<"sing dynamic extensions\n";
     } else {
       Param = GetRawTokenName(Tok);

       if (Param == "0")
         m_Interp.enableDynamicLookup(false);
       else
         m_Interp.enableDynamicLookup(true);
     }

     return true;
   }
   // Print Help
   else if (Command == "help") {
     PrintCommandHelp();
     return true;
   }
   // Print the loaded files
   else if (Command == "file") {
     PrintFileStats();
     return true;
   }

   return false;
  }

  std::string MetaProcessor::GetRawTokenName(const Token& Tok) {

    assert(!Tok.needsCleaning() && "Not implemented yet");

    switch (Tok.getKind()) {
    default:
      assert("Unknown token");
      return "";
    case tok::at:
      return "@";
    case tok::l_paren:
      return "(";
    case tok::r_paren:
      return ")";
    case tok::period:
      return ".";
    case tok::slash:
      return "/";
    case tok::numeric_constant:
      return StringRef(Tok.getLiteralData(), Tok.getLength()).str();
    case tok::raw_identifier:
      return StringRef(Tok.getRawIdentifierData(), Tok.getLength()).str();
    }
  }

  llvm::StringRef MetaProcessor::ReadToEndOfBuffer(Lexer& RawLexer,
                                                   llvm::MemoryBuffer* MB) {
    const char* CurPtr = RawLexer.getBufferLocation();
    if (CurPtr == MB->getBufferEnd()) {
      // Already at end of the buffer, return just the zero byte at the end.
      return StringRef(CurPtr, 0);
    }
    Token TmpTok;
    RawLexer.getAndAdvanceChar(CurPtr, TmpTok);
    return StringRef(CurPtr, MB->getBufferSize()-(CurPtr-MB->getBufferStart()));
  }

  llvm::StringRef MetaProcessor::SanitizeArg(const std::string& Str) {
    if(Str.empty())
      return Str;

    size_t begins = Str.find_first_not_of(" \t\n");
    size_t ends = Str.find_last_not_of(" \t\n") + 1;

    if (begins == std::string::npos)
      ends = begins + 1;

    return llvm::StringRef(Str.c_str(), ends - begins);
  }

  void MetaProcessor::PrintCommandHelp() {
    llvm::outs() << "Cling meta commands usage\n";
    llvm::outs() << "Syntax: .Command [arg0 arg1 ... argN]\n";
    llvm::outs() << "\n";
    llvm::outs() << ".q\t\t\t\t - Exit the program\n";
    llvm::outs() << ".L <filename>\t\t\t - Load file or library\n";
    llvm::outs() << ".(x|X) <filename>[args]\t\t - Same as .L and runs a ";
    llvm::outs() << "function with signature ret_type filename(args)\n";
    llvm::outs() << ".I [path]\t\t\t - Shows the include path. If a path is ";
    llvm::outs() << "given - adds the path to the list with the include paths\n";
    llvm::outs() << ".@ \t\t\t\t - Cancels and ignores the multiline input\n";
    llvm::outs() << ".rawInput [0|1]\t\t\t - Toggles the wrapping and printing ";
    llvm::outs() << "the execution results of the input\n";
    llvm::outs() << ".dynamicExtensions [0|1]\t - Toggles the use of the ";
    llvm::outs() << "dynamic scopes and the late binding\n";
    llvm::outs() << ".printAST [0|1]\t\t\t - Toggles the printing of input's ";
    llvm::outs() << "corresponding AST nodes\n";
    llvm::outs() << ".help\t\t\t\t - Shows this information\n";
  }

  void MetaProcessor::PrintFileStats() {
    const SourceManager& SM = m_Interp.getCI()->getSourceManager();
    SM.getFileManager().PrintStats();

    llvm::outs() << "\n***\n\n";

    for (SourceManager::fileinfo_iterator I = SM.fileinfo_begin(),
           E = SM.fileinfo_end(); I != E; ++I) {
      llvm::outs() << (*I).first->getName();
      llvm::outs() << "\n";
    }

  }

  // Run a file: .x file[(args)]
  bool MetaProcessor::executeFile(const std::string& fileWithArgs,
                                  Value* result) {
    // Look for start of parameters:

    typedef std::pair<llvm::StringRef,llvm::StringRef> StringRefPair;

    StringRefPair pairFileArgs = llvm::StringRef(fileWithArgs).split('(');
    if (pairFileArgs.second.empty()) {
      pairFileArgs.second = ")";
    }
    StringRefPair pairPathFile = pairFileArgs.first.rsplit('/');
    if (pairPathFile.second.empty()) {
       pairPathFile.second = pairPathFile.first;
    }
    StringRefPair pairFuncExt = pairPathFile.second.rsplit('.');

    //fprintf(stderr, "funcname: %s\n", pairFuncExt.first.data());

    Interpreter::CompilationResult interpRes
       = m_Interp.processLine(std::string("#include \"")
                              + pairFileArgs.first.str()
                              + std::string("\""), true /*raw*/);

    if (interpRes != Interpreter::kFailure) {
       std::string expression = pairFuncExt.first.str()
          + "(" + pairFileArgs.second.str();
       interpRes = m_Interp.evaluate(expression, result);
    }

    return (interpRes != Interpreter::kFailure);
  }
} // end namespace cling

<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $
Version:   $Revision: 17179 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#ifndef DiffusionImageMapper_txx_HEADER_INCLUDED
#define DiffusionImageMapper_txx_HEADER_INCLUDED

#include "mitkProperties.h"
#include "mitkDiffusionImage.h"

template<class TPixelType>
mitk::DiffusionImageMapper<TPixelType>::DiffusionImageMapper()
{
}

template<class TPixelType>
mitk::DiffusionImageMapper<TPixelType>::~DiffusionImageMapper()
{
}

template<class TPixelType>
void
mitk::DiffusionImageMapper<TPixelType>::GenerateData( mitk::BaseRenderer *renderer )
{
  int displayIndex(0);
  this->GetDataNode()->GetIntProperty( "DisplayChannel", displayIndex, renderer );
  InputImageType *input = const_cast< InputImageType* >(
    this->GetInput()
    );
  mitk::DiffusionImage<TPixelType> *input2 = dynamic_cast< mitk::DiffusionImage<TPixelType>* >(
    input
    );
  input2->SetDisplayIndexForRendering(displayIndex);
  Superclass::GenerateData(renderer);
}

template<class TPixelType>
void mitk::DiffusionImageMapper<TPixelType>::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
  node->AddProperty( "DisplayChannel", mitk::IntProperty::New( true ), renderer, overwrite );
  Superclass::SetDefaultProperties(node, renderer, overwrite);
}

#endif<commit_msg>FIX (#5582): init at 0, not at undefined<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $
Version:   $Revision: 17179 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#ifndef DiffusionImageMapper_txx_HEADER_INCLUDED
#define DiffusionImageMapper_txx_HEADER_INCLUDED

#include "mitkProperties.h"
#include "mitkDiffusionImage.h"

template<class TPixelType>
mitk::DiffusionImageMapper<TPixelType>::DiffusionImageMapper()
{
}

template<class TPixelType>
mitk::DiffusionImageMapper<TPixelType>::~DiffusionImageMapper()
{
}

template<class TPixelType>
void
mitk::DiffusionImageMapper<TPixelType>::GenerateData( mitk::BaseRenderer *renderer )
{
  int displayIndex(0);
  this->GetDataNode()->GetIntProperty( "DisplayChannel", displayIndex, renderer );
  InputImageType *input = const_cast< InputImageType* >(
    this->GetInput()
    );
  mitk::DiffusionImage<TPixelType> *input2 = dynamic_cast< mitk::DiffusionImage<TPixelType>* >(
    input
    );
  input2->SetDisplayIndexForRendering(displayIndex);
  Superclass::GenerateData(renderer);
}

template<class TPixelType>
void mitk::DiffusionImageMapper<TPixelType>::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
  node->AddProperty( "DisplayChannel", mitk::IntProperty::New( 0 ), renderer, overwrite );
  Superclass::SetDefaultProperties(node, renderer, overwrite);
}

#endif
<|endoftext|>