<commit_before>// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// 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
//
//     http://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 <gtest/gtest.h>

#include "rcl/rcl.h"

#include "./failing_allocator_functions.hpp"
#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp"
#include "osrf_testing_tools_cpp/scope_exit.hpp"
#include "rcl/error_handling.h"
#include "rcutils/format_string.h"
#include "rcutils/snprintf.h"

#include "../src/rcl/init_options_impl.h"

#ifdef RMW_IMPLEMENTATION
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
#else
# define CLASSNAME(NAME, SUFFIX) NAME
#endif

using osrf_testing_tools_cpp::memory_tools::on_unexpected_malloc;
using osrf_testing_tools_cpp::memory_tools::on_unexpected_realloc;
using osrf_testing_tools_cpp::memory_tools::on_unexpected_calloc;
using osrf_testing_tools_cpp::memory_tools::on_unexpected_free;

class CLASSNAME (TestRCLFixture, RMW_IMPLEMENTATION) : public ::testing::Test
{
public:
  void SetUp()
  {
    osrf_testing_tools_cpp::memory_tools::initialize();
    on_unexpected_malloc([]() {ADD_FAILURE() << "UNEXPECTED MALLOC";});
    on_unexpected_realloc([]() {ADD_FAILURE() << "UNEXPECTED REALLOC";});
    on_unexpected_free([]() {ADD_FAILURE() << "UNEXPECTED FREE";});
  }

  void TearDown()
  {
    osrf_testing_tools_cpp::memory_tools::uninitialize();
  }
};

struct FakeTestArgv
{
  FakeTestArgv()
  : allocator(rcutils_get_default_allocator()), argc(2)
  {
    this->argv =
      static_cast<char **>(allocator.allocate(2 * sizeof(char *), allocator.state));
    if (!this->argv) {
      throw std::bad_alloc();
    }
    this->argv[0] = rcutils_format_string(allocator, "%s", "foo");
    if (!this->argv[0]) {
      allocator.deallocate(this->argv, allocator.state);
      throw std::bad_alloc();
    }
    this->argv[1] = rcutils_format_string(allocator, "%s", "bar");
    if (!this->argv[1]) {
      allocator.deallocate(this->argv[0], allocator.state);
      allocator.deallocate(this->argv, allocator.state);
      throw std::bad_alloc();
    }
  }

  ~FakeTestArgv()
  {
    if (this->argv) {
      if (this->argc > 0) {
        size_t unsigned_argc = this->argc;
        for (size_t i = 0; i < unsigned_argc; --i) {
          allocator.deallocate(this->argv[i], allocator.state);
        }
      }
    }
    allocator.deallocate(this->argv, allocator.state);
  }

  rcutils_allocator_t allocator;
  int argc;
  char ** argv;

private:
  FakeTestArgv(const FakeTestArgv &) = delete;
};

/* Tests the rcl_init(), rcl_ok(), and rcl_shutdown() functions.
 */
TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_and_ok_and_shutdown) {
  rcl_ret_t ret;
  rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
  ret = rcl_init_options_init(&init_options, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
  rcl_context_t context = rcl_get_zero_initialized_context();
  // A shutdown before any init has been called should fail.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // If argc is not 0, but argv is, it should be an invalid argument.
  ret = rcl_init(42, nullptr, &init_options, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // If argc is not 0, argv is not null but contains one, it should be an invalid argument.
  const char * invalid_args[] = {"some-arg", nullptr};
  ret = rcl_init(2, invalid_args, &init_options, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // If either the allocate or deallocate function pointers are not set, it should be invalid arg.
  init_options.impl->allocator.allocate = nullptr;
  ret = rcl_init(0, nullptr, &init_options, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  init_options.impl->allocator.allocate = rcl_get_default_allocator().allocate;
  init_options.impl->allocator.deallocate = nullptr;
  ret = rcl_init(0, nullptr, &init_options, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // If the malloc call fails (with some valid arguments to copy), it should be a bad alloc.
  {
    FakeTestArgv test_args;
    rcl_allocator_t failing_allocator = rcl_get_default_allocator();
    failing_allocator.allocate = failing_malloc;
    failing_allocator.reallocate = failing_realloc;
    failing_allocator.zero_allocate = failing_calloc;
    init_options.impl->allocator = failing_allocator;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_BAD_ALLOC, ret);
    rcl_reset_error();
    ASSERT_FALSE(rcl_context_is_valid(&context));
  }
  init_options.impl->allocator = rcl_get_default_allocator();
  // If argc is 0 and argv is nullptr and the allocator is valid, it should succeed.
  ret = rcl_init(0, nullptr, &init_options, &context);
  EXPECT_EQ(RCL_RET_OK, ret);
  ASSERT_TRUE(rcl_context_is_valid(&context));
  // Then shutdown should work.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  ASSERT_FALSE(rcl_context_is_valid(&context));
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  context = rcl_get_zero_initialized_context();
  // Valid argc/argv values and a valid allocator should succeed.
  {
    FakeTestArgv test_args;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_OK, ret);
    ASSERT_TRUE(rcl_context_is_valid(&context));
  }
  // Then shutdown should work.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // Then a repeated shutdown should fail.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_ALREADY_SHUTDOWN);
  ASSERT_FALSE(rcl_context_is_valid(&context));
  rcl_reset_error();
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  context = rcl_get_zero_initialized_context();
  // A repeat call to shutdown should not work.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // Repeat, but valid, calls to rcl_init() should fail.
  {
    FakeTestArgv test_args;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_OK, ret);
    ASSERT_TRUE(rcl_context_is_valid(&context));
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_ALREADY_INIT, ret);
    rcl_reset_error();
    ASSERT_TRUE(rcl_context_is_valid(&context));
  }
  // But shutdown should still work.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  ASSERT_FALSE(rcl_context_is_valid(&context));
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  context = rcl_get_zero_initialized_context();
}

/* Tests the rcl_get_instance_id() and rcl_ok() functions.
 */
TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_get_instance_id_and_ok) {
  rcl_ret_t ret;
  rcl_context_t context = rcl_get_zero_initialized_context();
  // Instance id should be 0 before rcl_init().
  EXPECT_EQ(0u, rcl_context_get_instance_id(&context));
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // It should still return 0 after an invalid init.
  ret = rcl_init(1, nullptr, nullptr, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  EXPECT_EQ(0u, rcl_context_get_instance_id(&context));
  ASSERT_FALSE(rcl_context_is_valid(&context));
  rcl_reset_error();
  // A non-zero instance id should be returned after a valid init.
  rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
  ret = rcl_init_options_init(&init_options, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
  OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({
    EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options)) << rcl_get_error_string().str;
  });
  {
    FakeTestArgv test_args;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_OK, ret);
    ASSERT_TRUE(rcl_context_is_valid(&context));
  }
  // And it should be allocation free.
  uint64_t first_instance_id;
  EXPECT_NO_MEMORY_OPERATIONS({
    first_instance_id = rcl_context_get_instance_id(&context);
  });
  EXPECT_NE(0u, first_instance_id);
  // Repeat calls should return the same.
  EXPECT_EQ(first_instance_id, rcl_context_get_instance_id(&context));
  EXPECT_EQ(true, rcl_context_is_valid(&context));
  // Calling after a shutdown should return 0.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  EXPECT_EQ(0u, rcl_context_get_instance_id(&context));
  ASSERT_FALSE(rcl_context_is_valid(&context));
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  context = rcl_get_zero_initialized_context();
  // It should return a different value after another valid init.
  {
    FakeTestArgv test_args;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_OK, ret);
    ASSERT_TRUE(rcl_context_is_valid(&context));
  }
  EXPECT_NE(0u, rcl_context_get_instance_id(&context));
  EXPECT_NE(first_instance_id, rcl_context_get_instance_id(&context));
  ASSERT_TRUE(rcl_context_is_valid(&context));
  // Shutting down a second time should result in 0 again.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  EXPECT_EQ(0u, rcl_context_get_instance_id(&context));
  ASSERT_FALSE(rcl_context_is_valid(&context));
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
}
<commit_msg>fix leak in test_init (#440)<commit_after>// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// 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
//
//     http://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 <gtest/gtest.h>

#include "rcl/rcl.h"

#include "./failing_allocator_functions.hpp"
#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp"
#include "osrf_testing_tools_cpp/scope_exit.hpp"
#include "rcl/error_handling.h"
#include "rcutils/format_string.h"
#include "rcutils/snprintf.h"

#include "../src/rcl/init_options_impl.h"

#ifdef RMW_IMPLEMENTATION
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
#else
# define CLASSNAME(NAME, SUFFIX) NAME
#endif

using osrf_testing_tools_cpp::memory_tools::on_unexpected_malloc;
using osrf_testing_tools_cpp::memory_tools::on_unexpected_realloc;
using osrf_testing_tools_cpp::memory_tools::on_unexpected_calloc;
using osrf_testing_tools_cpp::memory_tools::on_unexpected_free;

class CLASSNAME (TestRCLFixture, RMW_IMPLEMENTATION) : public ::testing::Test
{
public:
  void SetUp()
  {
    osrf_testing_tools_cpp::memory_tools::initialize();
    on_unexpected_malloc([]() {ADD_FAILURE() << "UNEXPECTED MALLOC";});
    on_unexpected_realloc([]() {ADD_FAILURE() << "UNEXPECTED REALLOC";});
    on_unexpected_free([]() {ADD_FAILURE() << "UNEXPECTED FREE";});
  }

  void TearDown()
  {
    osrf_testing_tools_cpp::memory_tools::uninitialize();
  }
};

struct FakeTestArgv
{
  FakeTestArgv()
  : allocator(rcl_get_default_allocator()), argc(2)
  {
    this->argv =
      static_cast<char **>(allocator.allocate(2 * sizeof(char *), allocator.state));
    if (!this->argv) {
      throw std::bad_alloc();
    }
    this->argv[0] = rcutils_format_string(allocator, "%s", "foo");
    if (!this->argv[0]) {
      allocator.deallocate(this->argv, allocator.state);
      throw std::bad_alloc();
    }
    this->argv[1] = rcutils_format_string(allocator, "%s", "bar");
    if (!this->argv[1]) {
      allocator.deallocate(this->argv[0], allocator.state);
      allocator.deallocate(this->argv, allocator.state);
      throw std::bad_alloc();
    }
  }

  ~FakeTestArgv()
  {
    if (this->argv) {
      if (this->argc > 0) {
        size_t unsigned_argc = this->argc;
        for (size_t i = 0; i < unsigned_argc; ++i) {
          allocator.deallocate(this->argv[i], allocator.state);
        }
      }
    }
    allocator.deallocate(this->argv, allocator.state);
  }

  rcl_allocator_t allocator;
  int argc;
  char ** argv;

private:
  FakeTestArgv(const FakeTestArgv &) = delete;
};

/* Tests the rcl_init(), rcl_ok(), and rcl_shutdown() functions.
 */
TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_and_ok_and_shutdown) {
  rcl_ret_t ret;
  rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
  ret = rcl_init_options_init(&init_options, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
  rcl_context_t context = rcl_get_zero_initialized_context();
  // A shutdown before any init has been called should fail.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // If argc is not 0, but argv is, it should be an invalid argument.
  ret = rcl_init(42, nullptr, &init_options, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // If argc is not 0, argv is not null but contains one, it should be an invalid argument.
  const char * invalid_args[] = {"some-arg", nullptr};
  ret = rcl_init(2, invalid_args, &init_options, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // If either the allocate or deallocate function pointers are not set, it should be invalid arg.
  init_options.impl->allocator.allocate = nullptr;
  ret = rcl_init(0, nullptr, &init_options, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  init_options.impl->allocator.allocate = rcl_get_default_allocator().allocate;
  init_options.impl->allocator.deallocate = nullptr;
  ret = rcl_init(0, nullptr, &init_options, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // If the malloc call fails (with some valid arguments to copy), it should be a bad alloc.
  {
    FakeTestArgv test_args;
    rcl_allocator_t failing_allocator = rcl_get_default_allocator();
    failing_allocator.allocate = failing_malloc;
    failing_allocator.reallocate = failing_realloc;
    failing_allocator.zero_allocate = failing_calloc;
    init_options.impl->allocator = failing_allocator;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_BAD_ALLOC, ret);
    rcl_reset_error();
    ASSERT_FALSE(rcl_context_is_valid(&context));
  }
  init_options.impl->allocator = rcl_get_default_allocator();
  // If argc is 0 and argv is nullptr and the allocator is valid, it should succeed.
  ret = rcl_init(0, nullptr, &init_options, &context);
  EXPECT_EQ(RCL_RET_OK, ret);
  ASSERT_TRUE(rcl_context_is_valid(&context));
  // Then shutdown should work.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  ASSERT_FALSE(rcl_context_is_valid(&context));
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  context = rcl_get_zero_initialized_context();
  // Valid argc/argv values and a valid allocator should succeed.
  {
    FakeTestArgv test_args;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_OK, ret);
    ASSERT_TRUE(rcl_context_is_valid(&context));
  }
  // Then shutdown should work.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // Then a repeated shutdown should fail.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_ALREADY_SHUTDOWN);
  ASSERT_FALSE(rcl_context_is_valid(&context));
  rcl_reset_error();
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  context = rcl_get_zero_initialized_context();
  // A repeat call to shutdown should not work.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  rcl_reset_error();
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // Repeat, but valid, calls to rcl_init() should fail.
  {
    FakeTestArgv test_args;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_OK, ret);
    ASSERT_TRUE(rcl_context_is_valid(&context));
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_ALREADY_INIT, ret);
    rcl_reset_error();
    ASSERT_TRUE(rcl_context_is_valid(&context));
  }
  // But shutdown should still work.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  ASSERT_FALSE(rcl_context_is_valid(&context));
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  context = rcl_get_zero_initialized_context();
  OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({
    EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options)) << rcl_get_error_string().str;
  });
}

/* Tests the rcl_get_instance_id() and rcl_ok() functions.
 */
TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_get_instance_id_and_ok) {
  rcl_ret_t ret;
  rcl_context_t context = rcl_get_zero_initialized_context();
  // Instance id should be 0 before rcl_init().
  EXPECT_EQ(0u, rcl_context_get_instance_id(&context));
  ASSERT_FALSE(rcl_context_is_valid(&context));
  // It should still return 0 after an invalid init.
  ret = rcl_init(1, nullptr, nullptr, &context);
  EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
  EXPECT_EQ(0u, rcl_context_get_instance_id(&context));
  ASSERT_FALSE(rcl_context_is_valid(&context));
  rcl_reset_error();
  // A non-zero instance id should be returned after a valid init.
  rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
  ret = rcl_init_options_init(&init_options, rcl_get_default_allocator());
  ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
  OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({
    EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options)) << rcl_get_error_string().str;
  });
  {
    FakeTestArgv test_args;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_OK, ret);
    ASSERT_TRUE(rcl_context_is_valid(&context));
  }
  // And it should be allocation free.
  uint64_t first_instance_id;
  EXPECT_NO_MEMORY_OPERATIONS({
    first_instance_id = rcl_context_get_instance_id(&context);
  });
  EXPECT_NE(0u, first_instance_id);
  // Repeat calls should return the same.
  EXPECT_EQ(first_instance_id, rcl_context_get_instance_id(&context));
  EXPECT_EQ(true, rcl_context_is_valid(&context));
  // Calling after a shutdown should return 0.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  EXPECT_EQ(0u, rcl_context_get_instance_id(&context));
  ASSERT_FALSE(rcl_context_is_valid(&context));
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  context = rcl_get_zero_initialized_context();
  // It should return a different value after another valid init.
  {
    FakeTestArgv test_args;
    ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
    EXPECT_EQ(RCL_RET_OK, ret);
    ASSERT_TRUE(rcl_context_is_valid(&context));
  }
  EXPECT_NE(0u, rcl_context_get_instance_id(&context));
  EXPECT_NE(first_instance_id, rcl_context_get_instance_id(&context));
  ASSERT_TRUE(rcl_context_is_valid(&context));
  // Shutting down a second time should result in 0 again.
  ret = rcl_shutdown(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
  EXPECT_EQ(0u, rcl_context_get_instance_id(&context));
  ASSERT_FALSE(rcl_context_is_valid(&context));
  ret = rcl_context_fini(&context);
  EXPECT_EQ(ret, RCL_RET_OK);
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "executefilter.h"

#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/variablemanager.h>

#include <QMessageBox>

using namespace Core;
using namespace Locator;
using namespace Locator::Internal;

ExecuteFilter::ExecuteFilter()
{
    setId("Execute custom commands");
    setDisplayName(tr("Execute Custom Commands"));
    setShortcutString(QString(QLatin1Char('!')));
    setIncludedByDefault(false);

    m_process = new Utils::QtcProcess(this);
    m_process->setEnvironment(Utils::Environment::systemEnvironment());
    connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this,
            SLOT(finished(int,QProcess::ExitStatus)));
    connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput()));
    connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(readStandardError()));

    m_runTimer.setSingleShot(true);
    connect(&m_runTimer, SIGNAL(timeout()), this, SLOT(runHeadCommand()));
}

QList<FilterEntry> ExecuteFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future,
                                             const QString &entry)
{
    QList<FilterEntry> value;
    if (!entry.isEmpty()) // avoid empty entry
        value.append(FilterEntry(this, entry, QVariant()));
    QList<FilterEntry> others;
    const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
    foreach (const QString &i, m_commandHistory) {
        if (future.isCanceled())
            break;
        if (i == entry) // avoid repeated entry
            continue;
        if (i.startsWith(entry, caseSensitivityForPrefix))
            value.append(FilterEntry(this, i, QVariant()));
        else
            others.append(FilterEntry(this, i, QVariant()));
    }
    value.append(others);
    return value;
}

void ExecuteFilter::accept(FilterEntry selection) const
{
    ExecuteFilter *p = const_cast<ExecuteFilter *>(this);

    const QString value = selection.displayName.trimmed();
    const int index = m_commandHistory.indexOf(value);
    if (index != -1 && index != 0)
        p->m_commandHistory.removeAt(index);
    if (index != 0)
        p->m_commandHistory.prepend(value);

    bool found;
    QString workingDirectory = Core::VariableManager::value("CurrentDocument:Path", &found);
    if (!found || workingDirectory.isEmpty())
        workingDirectory = Core::VariableManager::value("CurrentProject:Path", &found);

    ExecuteData d;
    d.workingDirectory = workingDirectory;
    const int pos = value.indexOf(QLatin1Char(' '));
    if (pos == -1) {
        d.executable = value;
    } else {
        d.executable = value.left(pos);
        d.arguments = value.right(value.length() - pos - 1);
    }

    if (m_process->state() != QProcess::NotRunning) {
        const QString info(tr("Previous command is still running ('%1').\nDo you want to kill it?")
                           .arg(p->headCommand()));
        int r = QMessageBox::question(0, tr("Kill Previous Process?"), info,
                                      QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
                                      QMessageBox::Yes);
        if (r == QMessageBox::Yes)
            m_process->kill();
        if (r != QMessageBox::Cancel)
            p->m_taskQueue.enqueue(d);
        return;
    }

    p->m_taskQueue.enqueue(d);
    p->runHeadCommand();
}

void ExecuteFilter::finished(int exitCode, QProcess::ExitStatus status)
{
    const QString commandName = headCommand();
    QString message;
    if (status == QProcess::NormalExit && exitCode == 0)
        message = tr("Command '%1' finished.").arg(commandName);
    else
        message = tr("Command '%1' failed.").arg(commandName);
    MessageManager::write(message);

    m_taskQueue.dequeue();
    if (!m_taskQueue.isEmpty())
        m_runTimer.start(500);
}

void ExecuteFilter::readStandardOutput()
{
    QByteArray data = m_process->readAllStandardOutput();
    MessageManager::write(QTextCodec::codecForLocale()->toUnicode(data.constData(), data.size(),
                                                                  &m_stdoutState));
}

void ExecuteFilter::readStandardError()
{
    static QTextCodec::ConverterState state;
    QByteArray data = m_process->readAllStandardError();
    MessageManager::write(QTextCodec::codecForLocale()->toUnicode(data.constData(), data.size(),
                                                                  &m_stderrState));
}

void ExecuteFilter::runHeadCommand()
{
    if (!m_taskQueue.isEmpty()) {
        const ExecuteData &d = m_taskQueue.head();
        const QString fullPath = Utils::Environment::systemEnvironment().searchInPath(d.executable);
        if (fullPath.isEmpty()) {
            MessageManager::write(tr("Could not find executable for '%1'").arg(d.executable));
            m_taskQueue.dequeue();
            runHeadCommand();
            return;
        }
        MessageManager::write(tr("Starting command '%1'").arg(headCommand()));
        m_process->setWorkingDirectory(d.workingDirectory);
        m_process->setCommand(fullPath, d.arguments);
        m_process->start();
        m_process->closeWriteChannel();
    }
}

QString ExecuteFilter::headCommand() const
{
    if (m_taskQueue.isEmpty())
        return QString();
    const ExecuteData &data = m_taskQueue.head();
    if (data.arguments.isEmpty())
        return data.executable;
    else
        return data.executable + QLatin1Char(' ') + data.arguments;
}
<commit_msg>Locator: Wait for the process to start in execute filter<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "executefilter.h"

#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/variablemanager.h>

#include <QMessageBox>

using namespace Core;
using namespace Locator;
using namespace Locator::Internal;

ExecuteFilter::ExecuteFilter()
{
    setId("Execute custom commands");
    setDisplayName(tr("Execute Custom Commands"));
    setShortcutString(QString(QLatin1Char('!')));
    setIncludedByDefault(false);

    m_process = new Utils::QtcProcess(this);
    m_process->setEnvironment(Utils::Environment::systemEnvironment());
    connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this,
            SLOT(finished(int,QProcess::ExitStatus)));
    connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput()));
    connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(readStandardError()));

    m_runTimer.setSingleShot(true);
    connect(&m_runTimer, SIGNAL(timeout()), this, SLOT(runHeadCommand()));
}

QList<FilterEntry> ExecuteFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future,
                                             const QString &entry)
{
    QList<FilterEntry> value;
    if (!entry.isEmpty()) // avoid empty entry
        value.append(FilterEntry(this, entry, QVariant()));
    QList<FilterEntry> others;
    const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
    foreach (const QString &i, m_commandHistory) {
        if (future.isCanceled())
            break;
        if (i == entry) // avoid repeated entry
            continue;
        if (i.startsWith(entry, caseSensitivityForPrefix))
            value.append(FilterEntry(this, i, QVariant()));
        else
            others.append(FilterEntry(this, i, QVariant()));
    }
    value.append(others);
    return value;
}

void ExecuteFilter::accept(FilterEntry selection) const
{
    ExecuteFilter *p = const_cast<ExecuteFilter *>(this);

    const QString value = selection.displayName.trimmed();
    const int index = m_commandHistory.indexOf(value);
    if (index != -1 && index != 0)
        p->m_commandHistory.removeAt(index);
    if (index != 0)
        p->m_commandHistory.prepend(value);

    bool found;
    QString workingDirectory = Core::VariableManager::value("CurrentDocument:Path", &found);
    if (!found || workingDirectory.isEmpty())
        workingDirectory = Core::VariableManager::value("CurrentProject:Path", &found);

    ExecuteData d;
    d.workingDirectory = workingDirectory;
    const int pos = value.indexOf(QLatin1Char(' '));
    if (pos == -1) {
        d.executable = value;
    } else {
        d.executable = value.left(pos);
        d.arguments = value.right(value.length() - pos - 1);
    }

    if (m_process->state() != QProcess::NotRunning) {
        const QString info(tr("Previous command is still running ('%1').\nDo you want to kill it?")
                           .arg(p->headCommand()));
        int r = QMessageBox::question(0, tr("Kill Previous Process?"), info,
                                      QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
                                      QMessageBox::Yes);
        if (r == QMessageBox::Yes)
            m_process->kill();
        if (r != QMessageBox::Cancel)
            p->m_taskQueue.enqueue(d);
        return;
    }

    p->m_taskQueue.enqueue(d);
    p->runHeadCommand();
}

void ExecuteFilter::finished(int exitCode, QProcess::ExitStatus status)
{
    const QString commandName = headCommand();
    QString message;
    if (status == QProcess::NormalExit && exitCode == 0)
        message = tr("Command '%1' finished.").arg(commandName);
    else
        message = tr("Command '%1' failed.").arg(commandName);
    MessageManager::write(message);

    m_taskQueue.dequeue();
    if (!m_taskQueue.isEmpty())
        m_runTimer.start(500);
}

void ExecuteFilter::readStandardOutput()
{
    QByteArray data = m_process->readAllStandardOutput();
    MessageManager::write(QTextCodec::codecForLocale()->toUnicode(data.constData(), data.size(),
                                                                  &m_stdoutState));
}

void ExecuteFilter::readStandardError()
{
    static QTextCodec::ConverterState state;
    QByteArray data = m_process->readAllStandardError();
    MessageManager::write(QTextCodec::codecForLocale()->toUnicode(data.constData(), data.size(),
                                                                  &m_stderrState));
}

void ExecuteFilter::runHeadCommand()
{
    if (!m_taskQueue.isEmpty()) {
        const ExecuteData &d = m_taskQueue.head();
        const QString fullPath = Utils::Environment::systemEnvironment().searchInPath(d.executable);
        if (fullPath.isEmpty()) {
            MessageManager::write(tr("Could not find executable for '%1'").arg(d.executable));
            m_taskQueue.dequeue();
            runHeadCommand();
            return;
        }
        MessageManager::write(tr("Starting command '%1'").arg(headCommand()));
        m_process->setWorkingDirectory(d.workingDirectory);
        m_process->setCommand(fullPath, d.arguments);
        m_process->start();
        m_process->closeWriteChannel();
        if (!m_process->waitForStarted(1000)) {
             MessageManager::write(tr("Could not start process: %1").arg(m_process->errorString()));
             m_taskQueue.dequeue();
             runHeadCommand();
        }
    }
}

QString ExecuteFilter::headCommand() const
{
    if (m_taskQueue.isEmpty())
        return QString();
    const ExecuteData &data = m_taskQueue.head();
    if (data.arguments.isEmpty())
        return data.executable;
    else
        return data.executable + QLatin1Char(' ') + data.arguments;
}
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/dim4.hpp>
#include <af/defines.h>
#include <af/features.h>
#include <ArrayInfo.hpp>
#include <Array.hpp>
#include <err_opencl.hpp>
#include <handle.hpp>
#include <kernel/fast.hpp>

using af::dim4;
using af::features;

namespace opencl
{

template<typename T>
features fast(const Array<T> &in, const float thr, const unsigned arc_length,
              const bool nonmax, const float feature_ratio)
{
    unsigned nfeat;

    Param x;
    Param y;
    Param score;

    if (!nonmax) {
        switch (arc_length) {
        case 9:
            kernel::fast<T,  9, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 10:
            kernel::fast<T, 10, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 11:
            kernel::fast<T, 11, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 12:
            kernel::fast<T, 12, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 13:
            kernel::fast<T, 13, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 14:
            kernel::fast<T, 14, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 15:
            kernel::fast<T, 15, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 16:
            kernel::fast<T, 16, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        }
    } else {
        switch (arc_length) {
        case 9:
            kernel::fast<T,  9, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 10:
            kernel::fast<T, 10, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 11:
            kernel::fast<T, 11, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 12:
            kernel::fast<T, 12, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 13:
            kernel::fast<T, 13, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 14:
            kernel::fast<T, 14, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 15:
            kernel::fast<T, 15, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 16:
            kernel::fast<T, 16, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        }
    }

    const dim4 out_dims(nfeat);

    features feat;
    feat.setNumFeatures(nfeat);
    feat.setX(getHandle<float>(*createParamArray<float>(x)));
    feat.setY(getHandle<float>(*createParamArray<float>(y)));
    feat.setScore(getHandle<float>(*createParamArray<float>(score)));
    feat.setOrientation(getHandle<float>(*createValueArray<float>(out_dims, 0.0f)));
    feat.setSize(getHandle<float>(*createValueArray<float>(out_dims, 1.0f)));

    return feat;
}

#define INSTANTIATE(T)\
    template features fast<T>(const Array<T> &in, const float thr, const unsigned arc_length, \
                              const bool non_max, const float feature_ratio);

INSTANTIATE(float )
INSTANTIATE(double)
INSTANTIATE(char  )
INSTANTIATE(int   )
INSTANTIATE(uint  )
INSTANTIATE(uchar )

}
<commit_msg>Fixed FAST memory leaks on OpenCL backend<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/dim4.hpp>
#include <af/defines.h>
#include <af/features.h>
#include <ArrayInfo.hpp>
#include <Array.hpp>
#include <err_opencl.hpp>
#include <handle.hpp>
#include <kernel/fast.hpp>

using af::dim4;
using af::features;

namespace opencl
{

template<typename T>
features fast(const Array<T> &in, const float thr, const unsigned arc_length,
              const bool nonmax, const float feature_ratio)
{
    unsigned nfeat;

    Param x;
    Param y;
    Param score;

    if (!nonmax) {
        switch (arc_length) {
        case 9:
            kernel::fast<T,  9, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 10:
            kernel::fast<T, 10, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 11:
            kernel::fast<T, 11, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 12:
            kernel::fast<T, 12, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 13:
            kernel::fast<T, 13, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 14:
            kernel::fast<T, 14, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 15:
            kernel::fast<T, 15, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 16:
            kernel::fast<T, 16, 0>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        }
    } else {
        switch (arc_length) {
        case 9:
            kernel::fast<T,  9, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 10:
            kernel::fast<T, 10, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 11:
            kernel::fast<T, 11, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 12:
            kernel::fast<T, 12, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 13:
            kernel::fast<T, 13, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 14:
            kernel::fast<T, 14, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 15:
            kernel::fast<T, 15, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        case 16:
            kernel::fast<T, 16, 1>(&nfeat, x, y, score, in,
                                   thr, feature_ratio);
            break;
        }
    }

    features feat;

    if (nfeat == 0) {
        feat.setNumFeatures(0);
        feat.setX(getHandle<float>(*createEmptyArray<float>(af::dim4())));
        feat.setY(getHandle<float>(*createEmptyArray<float>(af::dim4())));
        feat.setScore(getHandle<float>(*createEmptyArray<float>(af::dim4())));
        feat.setOrientation(getHandle<float>(*createEmptyArray<float>(af::dim4())));
        feat.setSize(getHandle<float>(*createEmptyArray<float>(af::dim4())));
        return feat;
    }

    const dim4 out_dims(nfeat);

    feat.setNumFeatures(nfeat);
    feat.setX(getHandle<float>(*createParamArray<float>(x)));
    feat.setY(getHandle<float>(*createParamArray<float>(y)));
    feat.setScore(getHandle<float>(*createParamArray<float>(score)));
    feat.setOrientation(getHandle<float>(*createValueArray<float>(out_dims, 0.0f)));
    feat.setSize(getHandle<float>(*createValueArray<float>(out_dims, 1.0f)));

    bufferFree(x.data);
    bufferFree(y.data);
    bufferFree(score.data);

    return feat;
}

#define INSTANTIATE(T)\
    template features fast<T>(const Array<T> &in, const float thr, const unsigned arc_length, \
                              const bool non_max, const float feature_ratio);

INSTANTIATE(float )
INSTANTIATE(double)
INSTANTIATE(char  )
INSTANTIATE(int   )
INSTANTIATE(uint  )
INSTANTIATE(uchar )

}
<|endoftext|>


<commit_before>
// Copyright (c) 2012, 2013 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef OPENMVG_SFM_PLY_HELPER_H
#define OPENMVG_SFM_PLY_HELPER_H

#include "openMVG/numeric/numeric.h"

#include <fstream>
#include <string>
#include <vector>

namespace openMVG{
namespace plyHelper{

/// Export 3D point vector to PLY format
static bool exportToPly(const std::vector<Vec3> & vec_points,
  const std::string & sFileName)
{
  std::ofstream outfile;
  outfile.open(sFileName.c_str(), std::ios_base::out);

  outfile << "ply"
    << std::endl << "format ascii 1.0"
    << std::endl << "element vertex " << vec_points.size()
    << std::endl << "property float x"
    << std::endl << "property float y"
    << std::endl << "property float z"
    << std::endl << "property uchar red"
    << std::endl << "property uchar green"
    << std::endl << "property uchar blue"
    << std::endl << "end_header" << std::endl;

  for (size_t i=0; i < vec_points.size(); ++i)
  {
    outfile << vec_points[i].transpose()
      << " 255 255 255" << "\n";
  }
  bool bOk = outfile.good();
  outfile.close();
  return bOk;
}

/// Export 3D point vector and camera position to PLY format
static bool exportToPly(const std::vector<Vec3> & vec_points,
  const std::vector<Vec3> & vec_camPos,
  const std::string & sFileName,
  const std::vector<Vec3> * vec_coloredPoints = NULL)
{
  std::ofstream outfile;
  outfile.open(sFileName.c_str(), std::ios_base::out);

  outfile << "ply"
    << '\n' << "format ascii 1.0"
    << '\n' << "element vertex " << vec_points.size()+vec_camPos.size()
    << '\n' << "property float x"
    << '\n' << "property float y"
    << '\n' << "property float z"
    << '\n' << "property uchar red"
    << '\n' << "property uchar green"
    << '\n' << "property uchar blue"
    << '\n' << "end_header" << std::endl;

  for (size_t i=0; i < vec_points.size(); ++i)  {
    if (vec_coloredPoints == NULL)
      outfile << vec_points[i].transpose()
        << " 255 255 255" << "\n";
    else
      outfile << vec_points[i].transpose()
        << " " << (*vec_coloredPoints)[i].transpose() << "\n";
  }

  for (size_t i=0; i < vec_camPos.size(); ++i)  {
    outfile << vec_camPos[i].transpose()
      << " 0 255 0" << "\n";
  }
  outfile.flush();
  bool bOk = outfile.good();
  outfile.close();
  return bOk;
}

} // namespace plyHelper
} // namespace openMVG

#endif // OPENMVG_SFM_PLY_HELPER_H

<commit_msg>[software] throwing when file is not open<commit_after>
// Copyright (c) 2012, 2013 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef OPENMVG_SFM_PLY_HELPER_H
#define OPENMVG_SFM_PLY_HELPER_H

#include "openMVG/numeric/numeric.h"

#include <fstream>
#include <string>
#include <vector>

namespace openMVG{
namespace plyHelper{

/// Export 3D point vector to PLY format
static bool exportToPly(const std::vector<Vec3> & vec_points,
  const std::string & sFileName)
{
  std::ofstream outfile;
  outfile.open(sFileName, std::ios_base::out);

  if(!outfile.is_open())
    throw std::runtime_error("Unable to create file "+sFileName);

  outfile << "ply"
    << std::endl << "format ascii 1.0"
    << std::endl << "element vertex " << vec_points.size()
    << std::endl << "property float x"
    << std::endl << "property float y"
    << std::endl << "property float z"
    << std::endl << "property uchar red"
    << std::endl << "property uchar green"
    << std::endl << "property uchar blue"
    << std::endl << "end_header" << std::endl;

  for (size_t i=0; i < vec_points.size(); ++i)
  {
    outfile << vec_points[i].transpose()
      << " 255 255 255" << "\n";
  }
  bool bOk = outfile.good();
  outfile.close();
  return bOk;
}

/// Export 3D point vector and camera position to PLY format
static bool exportToPly(const std::vector<Vec3> & vec_points,
  const std::vector<Vec3> & vec_camPos,
  const std::string & sFileName,
  const std::vector<Vec3> * vec_coloredPoints = NULL)
{
  std::ofstream outfile;
  outfile.open(sFileName, std::ios_base::out);

  if(!outfile.is_open())
    throw std::runtime_error("Unable to create file "+sFileName);

  outfile << "ply"
    << '\n' << "format ascii 1.0"
    << '\n' << "element vertex " << vec_points.size()+vec_camPos.size()
    << '\n' << "property float x"
    << '\n' << "property float y"
    << '\n' << "property float z"
    << '\n' << "property uchar red"
    << '\n' << "property uchar green"
    << '\n' << "property uchar blue"
    << '\n' << "end_header" << std::endl;

  for (size_t i=0; i < vec_points.size(); ++i)  {
    if (vec_coloredPoints == NULL)
      outfile << vec_points[i].transpose()
        << " 255 255 255" << "\n";
    else
      outfile << vec_points[i].transpose()
        << " " << (*vec_coloredPoints)[i].transpose() << "\n";
  }

  for (size_t i=0; i < vec_camPos.size(); ++i)  {
    outfile << vec_camPos[i].transpose()
      << " 0 255 0" << "\n";
  }
  outfile.flush();
  bool bOk = outfile.good();
  outfile.close();
  return bOk;
}

} // namespace plyHelper
} // namespace openMVG

#endif // OPENMVG_SFM_PLY_HELPER_H

<|endoftext|>


<commit_before>#include "command.hh"
#include "shared.hh"
#include "store-api.hh"

#include <atomic>

using namespace nix;

struct CmdOptimiseStore : StoreCommand
{
    CmdOptimiseStore()
    {
    }

    std::string name() override
    {
        return "optimise-store";
    }

    std::string description() override
    {
        return "replace identical files in the store by hard links";
    }

    Examples examples() override
    {
        return {
            Example{
                "To optimise the Nix store:",
                "nix optimise-store"
            },
        };
    }

    void run(ref<Store> store) override
    {
        store->optimiseStore();
    }
};

static RegisterCommand r1(make_ref<CmdOptimiseStore>());
<commit_msg>nix: recognize 'nix optimize-store' but don't document<commit_after>#include "command.hh"
#include "shared.hh"
#include "store-api.hh"

#include <atomic>

using namespace nix;

struct CmdOptimiseStore : StoreCommand
{
    CmdOptimiseStore()
    {
    }

    std::string name() override
    {
        return "optimise-store";
    }

    std::string description() override
    {
        return "replace identical files in the store by hard links";
    }

    Examples examples() override
    {
        return {
            Example{
                "To optimise the Nix store:",
                "nix optimise-store"
            },
        };
    }

    void run(ref<Store> store) override
    {
        store->optimiseStore();
    }
};

struct CmdOptimizeStore : CmdOptimiseStore
{
    std::string name() override
    {
        return "optimize-store";
    }
};

static RegisterCommand r1(make_ref<CmdOptimiseStore>());
static RegisterCommand r2(make_ref<CmdOptimizeStore>());
<|endoftext|>


<commit_before>#include "PauseMenuState.h"
#include "Game.h"
#include "InputHandler.h"
#include "MainMenuState.h"

const std::string PauseMenuState::s_menuID = "PAUSEMENU";

PauseMenuState::PauseMenuState() : MenuState::MenuState(3) {
	s_vActions.push_back(PauseMenuState::resumeGame);
	s_vActions.push_back(PauseMenuState::goToMainMenu);
	s_vActions.push_back(PauseMenuState::quitGame);
}

std::string PauseMenuState::getStateID() const {
	return s_menuID;
}

void PauseMenuState::resumeGame() {
	Game::Instance()->getStateMachine()->popState();
}

void PauseMenuState::goToMainMenu() {
	Game::Instance()->getStateMachine()->clean();
	Game::Instance()->getStateMachine()->pushState(new MainMenuState());
}

void PauseMenuState::quitGame() {
	Game::Instance()->quit();
}
<commit_msg>useless include<commit_after>#include "PauseMenuState.h"
#include "Game.h"
#include "MainMenuState.h"

const std::string PauseMenuState::s_menuID = "PAUSEMENU";

PauseMenuState::PauseMenuState() : MenuState::MenuState(3) {
	s_vActions.push_back(PauseMenuState::resumeGame);
	s_vActions.push_back(PauseMenuState::goToMainMenu);
	s_vActions.push_back(PauseMenuState::quitGame);
}

std::string PauseMenuState::getStateID() const {
	return s_menuID;
}

void PauseMenuState::resumeGame() {
	Game::Instance()->getStateMachine()->popState();
}

void PauseMenuState::goToMainMenu() {
	Game::Instance()->getStateMachine()->clean();
	Game::Instance()->getStateMachine()->pushState(new MainMenuState());
}

void PauseMenuState::quitGame() {
	Game::Instance()->quit();
}
<|endoftext|>


<commit_before>#ifndef STAN_IO_ARRAY_VAR_CONTEXT_HPP
#define STAN_IO_ARRAY_VAR_CONTEXT_HPP

#include <stan/io/var_context.hpp>
#include <boost/throw_exception.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include <utility>

namespace stan {

namespace io {

/**
 * An array_var_context object represents a named arrays
 * with dimensions constructed from an array, a vector
 * of names, and a vector of all dimensions for each element.
 */
class array_var_context : public var_context {
 private:
  // Pairs
  template <typename T>
  using pair_
      = std::pair<std::string, std::pair<std::vector<T>, std::vector<size_t>>>;

  // Map holding reals
  using map_r_ = std::vector<pair_<double>>;
  map_r_ vars_r_;
  using map_i_ = std::vector<pair_<int>>;
  map_i_ vars_i_;
  // When search for variable name fails, return one these
  std::vector<double> const empty_vec_r_;
  std::vector<int> const empty_vec_i_;
  std::vector<size_t> const empty_vec_ui_;

  template <typename Str>
  auto find_var_r(Str&& name) const {
    return std::find_if(vars_r_.begin(), vars_r_.end(),
     [&](auto&& element){ return element.first == name;});
  }

  template <typename Str>
  auto find_var_i(Str&& name) const {
    return std::find_if(vars_i_.begin(), vars_i_.end(),
     [&](auto&& element){ return element.first == name;});
  }

  // Find method
  bool contains_r_only(const std::string& name) const {
    return find_var_r(name) != vars_r_.end();
  }

  /**
   * Check (1) if the vector size of dimensions is no smaller
   * than the name vector size; (2) if the size of the input
   * array is large enough for what is needed.
   *
   * @param names The names for each variable
   * @param array_size The total size of the vector holding the values we want
   * to access.
   * @param dims Vector holding the dimensions for each variable.
   * @return If the array size is equal to the number of dimensions,
   * a vector of the cumulative sum of the dimensions of each inner element of
   * dims. The return of this function is used in the add_* methods to get the
   * sequence of values For each variable.
   */

  template <typename T>
  std::vector<size_t> validate_dims(
      const std::vector<std::string>& names, const T array_size,
      const std::vector<std::vector<size_t>>& dims) {
    const size_t num_par = names.size();
    if (num_par > dims.size()) {
      std::stringstream msg;
      msg << "size of vector of dimensions (found " << dims.size() << ") "
          << "should be no smaller than number of parameters (found " << num_par
          << ").";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    std::vector<size_t> elem_dims_total(dims.size() + 1);
    elem_dims_total[0] = 0;
    int i = 0;
    for (i = 0; i < dims.size(); i++) {
      elem_dims_total[i + 1] = std::accumulate(dims[i].begin(), dims[i].end(),
                                               1, std::multiplies<T>());
      elem_dims_total[i + 1] += elem_dims_total[i];
    }
    if (elem_dims_total[i] > array_size) {
      std::stringstream msg;
      msg << "array is not long enough for all elements: " << array_size
          << " is found, but " << elem_dims_total[i] << " is needed.";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    return elem_dims_total;
  }

  /**
   * Adds a set of floating point variables to the floating point map.
   * @param names Names of each variable.
   * @param values The real values of variable in a contiguous
   * column major order container.
   * @param dims the dimensions for each variable.
   */
  void add_r(const std::vector<std::string>& names,
             const std::vector<double>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_[i]
          = {names[i],
             {{values.data() + dim_vec[i], values.data() + dim_vec[i + 1]},
              dims[i]}};
    }
  }

  void add_r(const std::vector<std::string>& names,
             const Eigen::VectorXd& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    using val_d_t = decltype(values.data());
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_[i]
          = {names[i],
             {{values.data() + dim_vec[i], values.data() + dim_vec[i + 1]},
              dims[i]}};
    }
  }

  /**
   * Adds a set of integer variables to the integer map.
   * @param names Names of each variable.
   * @param values The integer values of variable in a vector.
   * @param dims the dimensions for each variable.
   */
  void add_i(const std::vector<std::string>& names,
             const std::vector<int>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_i_[i]
          = {names[i],
             {{values.data() + dim_vec[i], values.data() + dim_vec[i + 1]},
              dims[i]}};
    }
  }

 public:
  /**
   * Construct an array_var_context from only real value arrays.
   *
   * @param names_r  names for each element
   * @param values_r a vector of double values for all elements
   * @param dim_r   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r)
      : vars_r_(names_r.size()) {
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Construct an array_var_context from only integer value arrays.
   *
   * @param names_i  names for each element
   * @param values_i a vector of integer values for all elements
   * @param dim_i   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
  }

  /**
   * Construct an array_var_context from arrays of both double
   * and integer separately
   *
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i)
      : vars_r_(names_r.size()), vars_i_(names_i.size()) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Return true if this dump contains the specified
   * variable name is defined. This method returns true
   * even if the values are all integers.
   *
   * @param name Variable name to test.
   * @return true if the variable exists.
   */
  bool contains_r(const std::string& name) const {
    return contains_r_only(name) || contains_i(name);
  }

  /**
   * Return true if this dump contains an integer
   * valued array with the specified name.
   *
   * @param name Variable name to test.
   * @return true if the variable name has an integer
   * array value.
   */
  bool contains_i(const std::string& name) const {
    return find_var_i(name) != vars_i_.end();
  }

  /**
   * Return the double values for the variable with the specified
   * name or null.
   *
   * @param name Name of variable.
   * @return Values of variable.
   *
   */
  std::vector<double> vals_r(const std::string& name) const {
    auto ret_val_r = find_var_r(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.first;
    } else {
      auto ret_val_i = find_var_i(name);
      if (ret_val_i != vars_i_.end()) {
        return {ret_val_i->second.first.begin(), ret_val_i->second.first.end()};
      }
    }
    return empty_vec_r_;
  }

  /**
   * Return the dimensions for the double variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_r(const std::string& name) const {
    auto ret_val_r = find_var_r(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.second;
    } else {
      auto ret_val_i = find_var_i(name);
      if (ret_val_i != vars_i_.end()) {
        return ret_val_i->second.second;
      }
    }
    return empty_vec_ui_;
  }

  /**
   * Return the integer values for the variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Values.
   */
  std::vector<int> vals_i(const std::string& name) const {
    auto ret_val_i = find_var_i(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.first;
    }
    return empty_vec_i_;
  }

  /**
   * Return the dimensions for the integer variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_i(const std::string& name) const {
    auto ret_val_i = find_var_i(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.second;
    }
    return empty_vec_ui_;
  }

  /**
   * Return a list of the names of the floating point variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_r(std::vector<std::string>& names) const {
    names.clear();
    for (const auto& vars_r_iter : vars_r_) {
      names.push_back(vars_r_iter.first);
    }
  }

  /**
   * Return a list of the names of the integer variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_i(std::vector<std::string>& names) const {
    names.clear();
    for (const auto& vars_i_iter : vars_r_) {
      names.push_back(vars_i_iter.first);
    }
  }

  /**
   * Remove variable from the object.
   *
   * @param name Name of the variable to remove.
   * @return If variable is removed returns true, else
   *   returns false.
   */
  bool remove(const std::string& name) {
    vars_i_.erase(find_var_i(name));
    vars_r_.erase(find_var_r(name));
    return true;
  }
};
}  // namespace io
}  // namespace stan
#endif
<commit_msg>move back to map<commit_after>#ifndef STAN_IO_ARRAY_VAR_CONTEXT_HPP
#define STAN_IO_ARRAY_VAR_CONTEXT_HPP

#include <stan/io/var_context.hpp>
#include <boost/throw_exception.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <numeric>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include <utility>

namespace stan {

namespace io {

/**
 * An array_var_context object represents a named arrays
 * with dimensions constructed from an array, a vector
 * of names, and a vector of all dimensions for each element.
 */
class array_var_context : public var_context {
 private:
  // Pairs
  template <typename T>
  using pair_ = std::pair<std::vector<T>, std::vector<size_t>>;

  // Map holding reals
  using map_r_ = std::map<std::string, pair_<double>>;
  map_r_ vars_r_;
  using map_i_ = std::map<std::string, pair_<int>>;
  map_i_ vars_i_;
  // When search for variable name fails, return one these
  std::vector<double> const empty_vec_r_{0};
  std::vector<int> const empty_vec_i_{0};
  std::vector<size_t> const empty_vec_ui_{0};

  // Find method
  bool contains_r_only(const std::string& name) const {
    return vars_r_.find(name) != vars_r_.end();
  }

  /**
   * Check (1) if the vector size of dimensions is no smaller
   * than the name vector size; (2) if the size of the input
   * array is large enough for what is needed.
   *
   * @param names The names for each variable
   * @param array_size The total size of the vector holding the values we want
   * to access.
   * @param dims Vector holding the dimensions for each variable.
   * @return If the array size is equal to the number of dimensions,
   * a vector of the cumulative sum of the dimensions of each inner element of
   * dims. The return of this function is used in the add_* methods to get the
   * sequence of values For each variable.
   */

  template <typename T>
  std::vector<size_t> validate_dims(
      const std::vector<std::string>& names, const T array_size,
      const std::vector<std::vector<size_t>>& dims) {
    const size_t num_par = names.size();
    if (num_par > dims.size()) {
      std::stringstream msg;
      msg << "size of vector of dimensions (found " << dims.size() << ") "
          << "should be no smaller than number of parameters (found " << num_par
          << ").";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    std::vector<size_t> elem_dims_total(dims.size() + 1);
    elem_dims_total[0] = 0;
    int i = 0;
    for (i = 0; i < dims.size(); i++) {
      elem_dims_total[i + 1] = std::accumulate(dims[i].begin(), dims[i].end(),
                                               1, std::multiplies<T>())
                                + elem_dims_total[i];;
    }
    if (elem_dims_total[i] > array_size) {
      std::stringstream msg;
      msg << "array is not long enough for all elements: " << array_size
          << " is found, but " << elem_dims_total[i] << " is needed.";
      BOOST_THROW_EXCEPTION(std::invalid_argument(msg.str()));
    }
    return elem_dims_total;
  }

  /**
   * Adds a set of floating point variables to the floating point map.
   * @param names Names of each variable.
   * @param values The real values of variable in a contiguous
   * column major order container.
   * @param dims the dimensions for each variable.
   */
  void add_r(const std::vector<std::string>& names,
             const std::vector<double>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_r_.emplace(names[i], pair_<double>{{values.data() + dim_vec[i],
         values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

  void add_r(const std::vector<std::string>& names,
             const Eigen::VectorXd& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    const auto name_size = names.size();
    for (size_t i = 0; i < name_size; i++) {
      vars_r_.emplace(names[i], pair_<double>{{values.data() + dim_vec[i],
          values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

  /**
   * Adds a set of integer variables to the integer map.
   * @param names Names of each variable.
   * @param values The integer values of variable in a vector.
   * @param dims the dimensions for each variable.
   */
  void add_i(const std::vector<std::string>& names,
             const std::vector<int>& values,
             const std::vector<std::vector<size_t>>& dims) {
    std::vector<size_t> dim_vec = validate_dims(names, values.size(), dims);
    for (size_t i = 0; i < names.size(); i++) {
      vars_i_.emplace(names[i], pair_<int>{{values.data() + dim_vec[i],
        values.data() + dim_vec[i + 1]}, dims[i]});
    }
  }

 public:
  /**
   * Construct an array_var_context from only real value arrays.
   *
   * @param names_r  names for each element
   * @param values_r a vector of double values for all elements
   * @param dim_r   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r) {
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r) {
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Construct an array_var_context from only integer value arrays.
   *
   * @param names_i  names for each element
   * @param values_i a vector of integer values for all elements
   * @param dim_i   a vector of dimensions
   */
  array_var_context(const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i) {
    add_i(names_i, values_i, dim_i);
  }

  /**
   * Construct an array_var_context from arrays of both double
   * and integer separately
   *
   */
  array_var_context(const std::vector<std::string>& names_r,
                    const std::vector<double>& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  array_var_context(const std::vector<std::string>& names_r,
                    const Eigen::VectorXd& values_r,
                    const std::vector<std::vector<size_t>>& dim_r,
                    const std::vector<std::string>& names_i,
                    const std::vector<int>& values_i,
                    const std::vector<std::vector<size_t>>& dim_i) {
    add_i(names_i, values_i, dim_i);
    add_r(names_r, values_r, dim_r);
  }

  /**
   * Return true if this dump contains the specified
   * variable name is defined. This method returns true
   * even if the values are all integers.
   *
   * @param name Variable name to test.
   * @return true if the variable exists.
   */
  bool contains_r(const std::string& name) const {
    return contains_r_only(name) || contains_i(name);
  }

  /**
   * Return true if this dump contains an integer
   * valued array with the specified name.
   *
   * @param name Variable name to test.
   * @return true if the variable name has an integer
   * array value.
   */
  bool contains_i(const std::string& name) const {
    return vars_i_.find(name) != vars_i_.end();
  }

  /**
   * Return the double values for the variable with the specified
   * name or null.
   *
   * @param name Name of variable.
   * @return Values of variable.
   *
   */
  std::vector<double> vals_r(const std::string& name) const {
    const auto ret_val_r = vars_r_.find(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.first;
    } else {
      const auto ret_val_i = vars_i_.find(name);
      if (ret_val_i != vars_i_.end()) {
        return {ret_val_i->second.first.begin(), ret_val_i->second.first.end()};
      }
    }
    return empty_vec_r_;
  }

  /**
   * Return the dimensions for the double variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_r(const std::string& name) const {
    const auto ret_val_r = vars_r_.find(name);
    if (ret_val_r != vars_r_.end()) {
      return ret_val_r->second.second;
    } else {
      const auto ret_val_i = vars_i_.find(name);
      if (ret_val_i != vars_i_.end()) {
        return ret_val_i->second.second;
      }
    }
    return empty_vec_ui_;
  }

  /**
   * Return the integer values for the variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Values.
   */
  std::vector<int> vals_i(const std::string& name) const {
    auto ret_val_i = vars_i_.find(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.first;
    }
    return empty_vec_i_;
  }

  /**
   * Return the dimensions for the integer variable with the specified
   * name.
   *
   * @param name Name of variable.
   * @return Dimensions of variable.
   */
  std::vector<size_t> dims_i(const std::string& name) const {
    auto ret_val_i = vars_i_.find(name);
    if (ret_val_i != vars_i_.end()) {
      return ret_val_i->second.second;
    }
    return empty_vec_ui_;
  }

  /**
   * Return a list of the names of the floating point variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_r(std::vector<std::string>& names) const {
    names.clear();
    names.reserve(vars_r_.size());
    for (const auto& vars_r_iter : vars_r_) {
      names.push_back(vars_r_iter.first);
    }
  }

  /**
   * Return a list of the names of the integer variables in
   * the dump.
   *
   * @param names Vector to store the list of names in.
   */
  virtual void names_i(std::vector<std::string>& names) const {
    names.clear();
    names.reserve(vars_i_.size());
    for (const auto& vars_i_iter : vars_r_) {
      names.push_back(vars_i_iter.first);
    }
  }

  /**
   * Remove variable from the object.
   *
   * @param name Name of the variable to remove.
   * @return If variable is removed returns true, else
   *   returns false.
   */
  bool remove(const std::string& name) {
    vars_i_.erase(name);
    vars_r_.erase(name);
    return true;
  }
};
}  // namespace io
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "treent/ResponsiveTextRenderSystem.h"
#include "treent/LocationComponent.h"
#include <boost/algorithm/string.hpp>
#include "cinder/app/App.h"
#include "cinder/Rand.h"

using namespace std;
using namespace cinder;

namespace treent
{

	RespTextComponent::RespTextComponent( ci::gl::TextureFontRef font, const string &text, const float &rank, const ci::ColorA &col, const ci::Vec2f &vel ) :
  _font( font ),
  _color( col ),
  _curr_value( rank ),
  _prev_value( rank ),
  _velocity( vel ),
  _content( text )
{
	// dimensions of text box, increased based on rank
	_rect_width = 50.0f;
	_rect_height = 100.0f;

	// default dimensions of text box and font
	_base_rect_width = _rect_width;
	_base_rect_height = _rect_height;
	_base_font_size = _font->getFont().getSize();

	// ideal max number of characters is a default value for now
	_max_chars = 12; // setMaxChars( text );
  _line_aspect_ratio = _max_chars * 0.519; // using a default font aspect ratio value for now
  reflowLayout( rank, text );
}

void RespTextComponent::setText( const std::string &text )
{
	gl::TextureFont::DrawOptions opt;
	opt.scale( 1.0f / app::getWindow()->getContentScale() ).pixelSnap( false );
	auto gp = _font->getGlyphPlacements( text, opt );
}

int RespTextComponent::setMaxChars( const std::string &text )
{
	string workingWord = "";  //working string
	string maxWord = "";  //biggest word

	// find longest word in string
	for (int i = 0; i < text.size( ); i++)
	{
		//If it's not a space, semicolon, colon, or comma, add it to the word, if it is, reset workingWord
		if (text[i] != ' ' && text[i] != ';' && text[i] != ':' && text[i] != ',')
		{	workingWord += text[i]; }
		else
		{	workingWord = ""; }

		// If workingword > maxWord, we have a new maxWord
		if (workingWord.size( ) > maxWord.size( ))
		{	maxWord = workingWord; }
	}

	return maxWord.size();
}

// split the headline into lines based on character count and word length
void RespTextComponent::splitLines( const std::string &text, int charLimit )
{
	// split text into vector of words
	vector<std::string> words;
	boost::split( words, text, boost::is_any_of( " " ) );

	std::string line = ""; // line to be added, filled with default text

	std::string currWord = ""; // current word
	std::string remainder = ""; // remainder of original text
	std::string nextTwoWords = ""; // next two words
	int wordIndex = 0;

	if ( wordIndex < words.size( ) )
	{
		// currWord is always one word behind nextTwoWords
		// add words to both until the length of one string is less than charLimit
        // per line, while the length of the other is greater than charLimit
		while (nextTwoWords.length() < charLimit)
		{
			currWord = nextTwoWords;
			nextTwoWords += words[wordIndex] + " ";
			wordIndex++;
			if (wordIndex >= words.size())
				break;
		}

		// add a line for whichever string is closer to the character limit
		if ((math<int>::abs( currWord.length() - charLimit ) < math<int>::abs( nextTwoWords.length() - charLimit )) && nextTwoWords.length() > 2)
		{
			line = currWord;
			wordIndex--;
		}
		else
		{
			line = nextTwoWords;
		}

		gl::TextureFont::DrawOptions opt;

		float lineSize = line.size( );
		float lineScale = lmap( lineSize, 1.0f, (float) charLimit, 0.1f, 1.0f );
		opt.scale( lineScale ).pixelSnap( true );
		auto gp = _font->getGlyphPlacements( line, Rectf( 0, 0, _rect_width, _line_height*2 ),opt );
		_glyph_placements.push_back( gp );
		_opts.push_back( opt );

		// repeat with the remainder of the original string
		for (int i = wordIndex; i < words.size(); i++)
		{
			remainder += words[i] + " ";
		}

		if (remainder.size() > charLimit)
		{
			splitLines( remainder, charLimit );
		}

		// if the length of the text is less than charLimit, add
		// this as the last line.
		else
		{
			float lineSize = remainder.size();
			float lineScale = lmap( lineSize, 1.0f, (float) charLimit, 0.1f, 1.0f );

			opt.scale( lineScale ).pixelSnap( true );
			app::console() << "scale: " << opt.getScale() << endl;
			auto gp = _font->getGlyphPlacements( remainder, Rectf( 0, 0, _rect_width, _line_height * 2 ),opt );
			_glyph_placements.push_back( gp );
			_opts.push_back( opt );
		}
	}
}

void RespTextComponent::reflowLayout( float val, const std::string &text )
{
	// change rect dimensions & font size based on rank
	float scaler = lmap( val, 1.0f, 10.0f, 0.5f, 2.0f );

	// with the assumption that val > 0, scale text box width and height by scaler
	_rect_height = _base_rect_height * scaler;
	_rect_width = _base_rect_width * scaler;

	// scale font size with text box
	auto currfont = _font->getFont();
	_font = gl::TextureFont::create( Font( currfont.getName(), _base_font_size * scaler ) );

	auto ideal_line_height = _rect_width /( _line_aspect_ratio*scaler);
	int line_count = ceil( _rect_height / ideal_line_height );

	_line_height = _rect_height / line_count;

	app::console( ) << "line count: " << line_count << endl;
	app::console( ) << "text length: " << text.length() << endl;

	// target character count per line is length of total string divided by number of lines
	int char_ct_per_line = ceil( text.length() / line_count );

	if (char_ct_per_line < setMaxChars( text ))
	{
		// make sure the longest word in the headline is not longer than the
		// per-line character count
		char_ct_per_line = setMaxChars( text );
	}
	app::console( ) << "char count: " << char_ct_per_line << endl;

	_opts.clear();
	_glyph_placements.clear();
	splitLines( text, char_ct_per_line);
}

//
//  MARK: - ResponsiveTextRenderSystem
//
void ResponsiveTextRenderSystem::update( EntityManagerRef entities, EventManagerRef events, double dt )
{
  _grouped_text.clear();
  for (auto entity : entities->entities_with_components<LocationComponent, RespTextComponent>( ))
  {
    LocationComponentRef location;
	RespTextComponentRef     text;
    entity.unpack( location, text );

    _grouped_text[text->_font].push_back( make_pair( location, text ) );
  }
}

void ResponsiveTextRenderSystem::draw( ) const
{
  for( auto &pair : _grouped_text )
  {
    // TODO: custom extension of TextureFont so we can bind each font texture once per draw.
    auto &blocks = pair.second;
    for( auto &pair : blocks )
    {
      LocationComponentRef location = pair.first;
	  RespTextComponentRef text = pair.second;

      gl::ScopedModelMatrix matrix;
      gl::multModelMatrix( Matrix44f( location->matrix ) );

	  for (int i = 0; i < text->_glyph_placements.size(); i++)
	  {
		  auto gp = text->_glyph_placements[i];
		  gl::color( text->_color );

		  // need a good way to calculate line separation value
		  text->_font->drawGlyphs( gp, Vec2f( 0, (text->_font->getFont().getSize()) * i ), text->_opts[i] );
	  }
    }
  }
}

} // treent::

<commit_msg>removed some debug stuff<commit_after>/*
 * Copyright (c) 2014 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "treent/ResponsiveTextRenderSystem.h"
#include "treent/LocationComponent.h"
#include <boost/algorithm/string.hpp>
#include "cinder/app/App.h"
#include "cinder/Rand.h"

using namespace std;
using namespace cinder;

namespace treent
{

	RespTextComponent::RespTextComponent( ci::gl::TextureFontRef font, const string &text, const float &rank, const ci::ColorA &col, const ci::Vec2f &vel ) :
  _font( font ),
  _color( col ),
  _curr_value( rank ),
  _prev_value( rank ),
  _velocity( vel ),
  _content( text )
{
	// dimensions of text box, increased based on rank
	_rect_width = 50.0f;
	_rect_height = 100.0f;

	// default dimensions of text box and font
	_base_rect_width = _rect_width;
	_base_rect_height = _rect_height;
	_base_font_size = _font->getFont().getSize();

	// ideal max number of characters is a default value for now
	_max_chars = 12; // setMaxChars( text );
  _line_aspect_ratio = _max_chars * 0.519; // using a default font aspect ratio value for now
  reflowLayout( rank, text );
}

void RespTextComponent::setText( const std::string &text )
{
	gl::TextureFont::DrawOptions opt;
	opt.scale( 1.0f / app::getWindow()->getContentScale() ).pixelSnap( false );
	auto gp = _font->getGlyphPlacements( text, opt );
}

int RespTextComponent::setMaxChars( const std::string &text )
{
	string workingWord = "";  //working string
	string maxWord = "";  //biggest word

	// find longest word in string
	for (int i = 0; i < text.size( ); i++)
	{
		//If it's not a space, semicolon, colon, or comma, add it to the word, if it is, reset workingWord
		if (text[i] != ' ' && text[i] != ';' && text[i] != ':' && text[i] != ',')
		{	workingWord += text[i]; }
		else
		{	workingWord = ""; }

		// If workingword > maxWord, we have a new maxWord
		if (workingWord.size( ) > maxWord.size( ))
		{	maxWord = workingWord; }
	}

	return maxWord.size();
}

// split the headline into lines based on character count and word length
void RespTextComponent::splitLines( const std::string &text, int charLimit )
{
	// split text into vector of words
	vector<std::string> words;
	boost::split( words, text, boost::is_any_of( " " ) );

	std::string line = ""; // line to be added, filled with default text

	std::string currWord = ""; // current word
	std::string remainder = ""; // remainder of original text
	std::string nextTwoWords = ""; // next two words
	int wordIndex = 0;

	if ( wordIndex < words.size( ) )
	{
		// currWord is always one word behind nextTwoWords
		// add words to both until the length of one string is less than charLimit
        // per line, while the length of the other is greater than charLimit
		while (nextTwoWords.length() < charLimit)
		{
			currWord = nextTwoWords;
			nextTwoWords += words[wordIndex] + " ";
			wordIndex++;
			if (wordIndex >= words.size())
				break;
		}

		// add a line for whichever string is closer to the character limit
		if ((math<int>::abs( currWord.length() - charLimit ) < math<int>::abs( nextTwoWords.length() - charLimit )) && nextTwoWords.length() > 2)
		{
			line = currWord;
			wordIndex--;
		}
		else
		{
			line = nextTwoWords;
		}

		gl::TextureFont::DrawOptions opt;

		float lineSize = line.size( );
		float lineScale = lmap( lineSize, 1.0f, (float) charLimit, 0.1f, 1.0f );
		opt.scale( lineScale ).pixelSnap( true );
		auto gp = _font->getGlyphPlacements( line, Rectf( 0, 0, _rect_width, _line_height*2 ),opt );
		_glyph_placements.push_back( gp );
		_opts.push_back( opt );

		// repeat with the remainder of the original string
		for (int i = wordIndex; i < words.size(); i++)
		{
			remainder += words[i] + " ";
		}

		if (remainder.size() > charLimit)
		{
			splitLines( remainder, charLimit );
		}

		// if the length of the text is less than charLimit, add
		// this as the last line.
		else
		{
			float lineSize = remainder.size();
			float lineScale = lmap( lineSize, 1.0f, (float) charLimit, 0.1f, 1.0f );

			opt.scale( lineScale ).pixelSnap( true );
			app::console() << "scale: " << opt.getScale() << endl;
			auto gp = _font->getGlyphPlacements( remainder, Rectf( 0, 0, _rect_width, _line_height * 2 ),opt );
			_glyph_placements.push_back( gp );
			_opts.push_back( opt );
		}
	}
}

void RespTextComponent::reflowLayout( float val, const std::string &text )
{
	// change rect dimensions & font size based on rank
	float scaler = lmap( val, 1.0f, 10.0f, 0.5f, 2.0f );

	// with the assumption that val > 0, scale text box width and height by scaler
	_rect_height = _base_rect_height * scaler;
	_rect_width = _base_rect_width * scaler;

	// scale font size with text box
	auto currfont = _font->getFont();
	_font = gl::TextureFont::create( Font( currfont.getName(), _base_font_size * scaler ) );

	auto ideal_line_height = _rect_width /( _line_aspect_ratio*scaler);
	int line_count = ceil( _rect_height / ideal_line_height );

	_line_height = _rect_height / line_count;

	// target character count per line is length of total string divided by number of lines
	int char_ct_per_line = ceil( text.length() / line_count );

	if (char_ct_per_line < setMaxChars( text ))
	{
		// make sure the longest word in the headline is not longer than the
		// per-line character count
		char_ct_per_line = setMaxChars( text );
	}

	_opts.clear();
	_glyph_placements.clear();
	splitLines( text, char_ct_per_line);
}

//
//  MARK: - ResponsiveTextRenderSystem
//
void ResponsiveTextRenderSystem::update( EntityManagerRef entities, EventManagerRef events, double dt )
{
  _grouped_text.clear();
  for (auto entity : entities->entities_with_components<LocationComponent, RespTextComponent>( ))
  {
    LocationComponentRef location;
	RespTextComponentRef     text;
    entity.unpack( location, text );

    _grouped_text[text->_font].push_back( make_pair( location, text ) );
  }
}

void ResponsiveTextRenderSystem::draw( ) const
{
  for( auto &pair : _grouped_text )
  {
    // TODO: custom extension of TextureFont so we can bind each font texture once per draw.
    auto &blocks = pair.second;
    for( auto &pair : blocks )
    {
      LocationComponentRef location = pair.first;
	  RespTextComponentRef text = pair.second;

      gl::ScopedModelMatrix matrix;
      gl::multModelMatrix( Matrix44f( location->matrix ) );

	  for (int i = 0; i < text->_glyph_placements.size(); i++)
	  {
		  auto gp = text->_glyph_placements[i];

		  // if above a certain rank, display the headline in color
		  if (text->_curr_value >= 7)
			  gl::color( text->_color );
		  else
			  gl::color( ColorA::white() );

		  // need a good way to calculate line separation value
		  text->_font->drawGlyphs( gp, Vec2f( 0, (text->_font->getFont().getSize()) * i ), text->_opts[i] );
	  }
    }
  }
}

} // treent::

<|endoftext|>


<commit_before>// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "DelayedLoader.h"
#include "EmbeddedPython.h"
#include "Logger.h"
#include <iostream>

extern EmbeddedPython *python;
extern std::string pythonInitializationError;

std::shared_ptr<spdlog::logger> Logger::logfile = getFallbackLogger();

#ifndef _WIN32
__attribute__((constructor))
#endif
void libraryLoad()
{
    // Ignore delay loading dlls for now as there are problems with loading
    // data from those dlls - and we need that data!
    /*
    int retval = 0;
    if ((retval = LoadAllImports()) != 0)
    {
        std::string error_message = "Failed to load python" PYTHON_VERSION ".dll "
                                    "(error: " + std::to_string(retval) + "). "
                                    "Ensure that Python " PYTHON_VERSION_DOTTED " is correctly installed!";
        LOG_ERROR(error_message);
        pythonInitializationError = error_message;
        return TRUE;
    }
    */
    createLogger("PythiaLogger", LITERAL("Pythia_c.log"));

    try
    {
        python = new EmbeddedPython();
        LOG_INFO("Python extension successfully loaded");
    }
    catch (const std::exception& ex)
    {
        LOG_ERROR(std::string("Caught error when creating the embedded python: ") + ex.what());
        pythonInitializationError = ex.what();
    }
}

#ifndef _WIN32
__attribute__((destructor))
#endif
void libraryUnload()
{
    if (python)
    {
        delete python;
        python = nullptr;
    }
    //LOG_FLUSH();
    spdlog::drop_all();
}

#ifdef _WIN32
BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            libraryLoad();
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;

        case DLL_PROCESS_DETACH:
            libraryUnload();
            break;
    }
    return TRUE;
}
#endif
<commit_msg>Move fallback logger initialization to libraryLoad()<commit_after>// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "DelayedLoader.h"
#include "EmbeddedPython.h"
#include "Logger.h"
#include <iostream>

extern EmbeddedPython *python;
extern std::string pythonInitializationError;

std::shared_ptr<spdlog::logger> Logger::logfile = nullptr;

#ifndef _WIN32
__attribute__((constructor))
#endif
void libraryLoad()
{
    Logger::logfile = getFallbackLogger();
    // Ignore delay loading dlls for now as there are problems with loading
    // data from those dlls - and we need that data!
    /*
    int retval = 0;
    if ((retval = LoadAllImports()) != 0)
    {
        std::string error_message = "Failed to load python" PYTHON_VERSION ".dll "
                                    "(error: " + std::to_string(retval) + "). "
                                    "Ensure that Python " PYTHON_VERSION_DOTTED " is correctly installed!";
        LOG_ERROR(error_message);
        pythonInitializationError = error_message;
        return TRUE;
    }
    */
    createLogger("PythiaLogger", LITERAL("Pythia_c.log"));

    try
    {
        python = new EmbeddedPython();
        LOG_INFO("Python extension successfully loaded");
    }
    catch (const std::exception& ex)
    {
        LOG_ERROR(std::string("Caught error when creating the embedded python: ") + ex.what());
        pythonInitializationError = ex.what();
    }
}

#ifndef _WIN32
__attribute__((destructor))
#endif
void libraryUnload()
{
    if (python)
    {
        delete python;
        python = nullptr;
    }
    //LOG_FLUSH();
    spdlog::drop_all();
}

#ifdef _WIN32
BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            libraryLoad();
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;

        case DLL_PROCESS_DETACH:
            libraryUnload();
            break;
    }
    return TRUE;
}
#endif
<|endoftext|>


<commit_before>#include <iostream>
#include "object/object.hh"
#include "object/atom.hh"

#define ECHO(This) std::cerr << This << std::endl
#define NEWLINE()  std::cerr << std::endl

using namespace object;
using libport::Symbol;

int
main ()
{
  Integer i (23);
  i["value 2"] = new Integer(5);
  ECHO(i);

  NEWLINE();
  Object o;
  o["drink"] = new Integer(51);
  o["name"]  = new String("Pastis");
  o["degre"] = new Float(.45);
  o["x"] = new Object();
  (*o["x"])["val"] = new String("o.x.val");
  ECHO(o);

  NEWLINE();
  rObject top = new Object ();
  (*top)["name"] = new String("Top_Class");
  (*top)["val"]  = new Integer(42);
  ECHO(*top);

  rObject left = new Object ();
  (*left)["name"] = new String("Left_class");
  (*left).parent_add (top);
  ECHO(*left);
  (*left).parent_add (top);
  ECHO(*left);
  (*left).parent_remove (top);
  ECHO(*left);
  (*left).parent_remove (top);
  ECHO(*left);
  (*left).parent_add (top);
  ECHO(*left);

  NEWLINE();
  rObject top_name = (*top).lookup ("name");
  ECHO(*top_name);
  rObject top_val = (*top).lookup ("val");
  ECHO(*top_val);
  rObject left_name = (*left).lookup ("name");
  ECHO(*left_name);
  rObject left_val = (*left).lookup ("val");
  ECHO(*left_val);

  NEWLINE();
  try
  {
  rObject left_nosuch = (*left).lookup ("no such attr");
  ECHO(*left_nosuch);
  }
  catch (std::exception e)
  { }

  return 0;
}
<commit_msg>Space changes.<commit_after>#include <iostream>
#include "object/object.hh"
#include "object/atom.hh"

#define ECHO(This) std::cerr << This << std::endl
#define NEWLINE()  std::cerr << std::endl

using namespace object;
using libport::Symbol;

int
main ()
{
  Integer i (23);
  i["value 2"] = new Integer(5);
  ECHO(i);

  NEWLINE();
  Object o;
  o["drink"] = new Integer(51);
  o["name"]  = new String("Pastis");
  o["degre"] = new Float(.45);
  o["x"] = new Object();
  (*o["x"])["val"] = new String("o.x.val");
  ECHO(o);

  NEWLINE();
  rObject top = new Object ();
  (*top)["name"] = new String("Top_Class");
  (*top)["val"]  = new Integer(42);
  ECHO(*top);

  rObject left = new Object ();
  (*left)["name"] = new String("Left_class");
  (*left).parent_add (top);
  ECHO(*left);
  (*left).parent_add (top);
  ECHO(*left);
  (*left).parent_remove (top);
  ECHO(*left);
  (*left).parent_remove (top);
  ECHO(*left);
  (*left).parent_add (top);
  ECHO(*left);

  NEWLINE();
  rObject top_name = (*top).lookup ("name");
  ECHO(*top_name);
  rObject top_val = (*top).lookup ("val");
  ECHO(*top_val);
  rObject left_name = (*left).lookup ("name");
  ECHO(*left_name);
  rObject left_val = (*left).lookup ("val");
  ECHO(*left_val);

  NEWLINE();
  try
  {
    rObject left_nosuch = (*left).lookup ("no such attr");
    ECHO(*left_nosuch);
  }
  catch (std::exception)
  { }

  return 0;
}
<|endoftext|>