<commit_before>//===--- KeyPaths.cpp - Key path helper symbols ---------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Metadata.h"
#include <cstdint>
#include <cstring>

using namespace swift;

SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
void swift_copyKeyPathTrivialIndices(const void *src, void *dest, size_t bytes) {
  memcpy(dest, src, bytes);
}

SWIFT_CC(swift)
static bool equateGenericArguments(const void *a, const void *b, size_t bytes) {
  // Generic arguments can't affect equality, since an equivalent key path may
  // have been formed in a fully concrete context without capturing generic
  // arguments.
  return true;
}

SWIFT_CC(swift)
static intptr_t hashGenericArguments(const void *src, size_t bytes) {
  // Generic arguments can't affect equality, since an equivalent key path may
  // have been formed in a fully concrete context without capturing generic
  // arguments. The implementation recognizes a hash value return of '0' as
  // "no effect on the hash".
  return 0;
}

struct KeyPathGenericWitnessTable {
  void *destroy;
  SWIFT_CC(swift) void (* __ptrauth_swift_runtime_function_entry_with_key(swift::SpecialPointerAuthDiscriminators::KeyPathCopy) copy)(const void *src, void *dest, size_t bytes);
  SWIFT_CC(swift) bool (* __ptrauth_swift_runtime_function_entry_with_key(swift::SpecialPointerAuthDiscriminators::KeyPathEquals) equals)(const void *, const void *, size_t);
  SWIFT_CC(swift) intptr_t (* __ptrauth_swift_runtime_function_entry_with_key(swift::SpecialPointerAuthDiscriminators::KeyPathHash) hash)(const void *src, size_t bytes);
};

/// A prefab witness table for computed key path components that only include
/// captured generic arguments.
SWIFT_RUNTIME_EXPORT
KeyPathGenericWitnessTable swift_keyPathGenericWitnessTable = {
  nullptr,
  swift_copyKeyPathTrivialIndices,
  equateGenericArguments,
  hashGenericArguments,
};

/****************************************************************************/
/** Projection functions ****************************************************/
/****************************************************************************/

namespace {
  struct AddrAndOwner {
    OpaqueValue *Addr;
    HeapObject *Owner;
  };
}

// These functions are all implemented in the stdlib.  Their type
// parameters are passed impliictly in the isa of the key path.

extern "C"
SWIFT_CC(swift) void
swift_getAtKeyPath(SWIFT_INDIRECT_RESULT void *result,
                   const OpaqueValue *root, void *keyPath);

extern "C"
SWIFT_CC(swift) AddrAndOwner
_swift_modifyAtWritableKeyPath_impl(OpaqueValue *root, void *keyPath);

extern "C"
SWIFT_CC(swift) AddrAndOwner
_swift_modifyAtReferenceWritableKeyPath_impl(const OpaqueValue *root,
                                             void *keyPath);

namespace {
  struct YieldOnceTemporary {
    const Metadata *Type;

    // Yield-once buffers can't be memcpy'ed, so it doesn't matter that
    // isValueInline() returns false for non-bitwise-takable types --- but
    // it doesn't hurt, either.
    ValueBuffer Buffer;

    YieldOnceTemporary(const Metadata *type) : Type(type) {}

    static OpaqueValue *allocateIn(const Metadata *type,
                                   YieldOnceBuffer *buffer) {
      auto *temp =
        new (reinterpret_cast<void*>(buffer)) YieldOnceTemporary(type);
      return type->allocateBufferIn(&temp->Buffer);
    }

    static void destroyAndDeallocateIn(YieldOnceBuffer *buffer) {
      auto *temp = reinterpret_cast<YieldOnceTemporary*>(buffer);
      temp->Type->vw_destroy(temp->Type->projectBufferFrom(&temp->Buffer));
      temp->Type->deallocateBufferIn(&temp->Buffer);
    }
  };

  static_assert(sizeof(YieldOnceTemporary) <= sizeof(YieldOnceBuffer) &&
                alignof(YieldOnceTemporary) <= alignof(YieldOnceBuffer),
                "temporary doesn't fit in a YieldOnceBuffer");
}

static SWIFT_CC(swift)
void _destroy_temporary_continuation(YieldOnceBuffer *buffer, bool forUnwind) {
  YieldOnceTemporary::destroyAndDeallocateIn(buffer);
}

// The resilient offset to the start of KeyPath's class-specific data.
extern "C" size_t MANGLE_SYM(s7KeyPathCMo);

YieldOnceResult<const OpaqueValue*>
swift::swift_readAtKeyPath(YieldOnceBuffer *buffer,
                           const OpaqueValue *root, void *keyPath) {
  // The Value type parameter is passed in the class of the key path object.
  // KeyPath is a native class, so we can just load its metadata directly
  // even on ObjC-interop targets.
  const Metadata *keyPathType = static_cast<HeapObject*>(keyPath)->metadata;

  // To find the generic arguments, we just have to find the class-specific
  // data section of the class; the generic arguments are always at the start
  // of that.
  //
  // We use the resilient access pattern because it's easy; since we're within
  // KeyPath's resilience domain, that's not really necessary, and it would
  // be totally valid to hard-code an offset.
  auto keyPathGenericArgs =
    reinterpret_cast<const Metadata * const *>(
      reinterpret_cast<const char*>(keyPathType) + MANGLE_SYM(s7KeyPathCMo));
  const Metadata *valueTy = keyPathGenericArgs[1];

  // Allocate the buffer.
  auto result = YieldOnceTemporary::allocateIn(valueTy, buffer);

  // Read into the buffer.
  swift_getAtKeyPath(result, root, keyPath);

  // Return a continuation that destroys the value in the buffer
  // and deallocates it.
  return { swift_ptrauth_sign_opaque_read_resume_function(
             &_destroy_temporary_continuation, buffer),
           result };
}

static SWIFT_CC(swift)
void _release_owner_continuation(YieldOnceBuffer *buffer, bool forUnwind) {
  swift_unknownObjectRelease(buffer->Data[0]);
}

YieldOnceResult<OpaqueValue*>
swift::swift_modifyAtWritableKeyPath(YieldOnceBuffer *buffer,
                                     OpaqueValue *root, void *keyPath) {
  auto addrAndOwner =
    _swift_modifyAtWritableKeyPath_impl(root, keyPath);
  buffer->Data[0] = addrAndOwner.Owner;

  return { swift_ptrauth_sign_opaque_modify_resume_function(
             &_release_owner_continuation, buffer),
           addrAndOwner.Addr };
}

YieldOnceResult<OpaqueValue*>
swift::swift_modifyAtReferenceWritableKeyPath(YieldOnceBuffer *buffer,
                                              const OpaqueValue *root,
                                              void *keyPath) {
  auto addrAndOwner =
    _swift_modifyAtReferenceWritableKeyPath_impl(root, keyPath);
  buffer->Data[0] = addrAndOwner.Owner;

  return { swift_ptrauth_sign_opaque_modify_resume_function(
             &_release_owner_continuation, buffer),
           addrAndOwner.Addr };
}
<commit_msg>Fixes typo in comment in KeyPaths.cpp (#32240)<commit_after>//===--- KeyPaths.cpp - Key path helper symbols ---------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Metadata.h"
#include <cstdint>
#include <cstring>

using namespace swift;

SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
void swift_copyKeyPathTrivialIndices(const void *src, void *dest, size_t bytes) {
  memcpy(dest, src, bytes);
}

SWIFT_CC(swift)
static bool equateGenericArguments(const void *a, const void *b, size_t bytes) {
  // Generic arguments can't affect equality, since an equivalent key path may
  // have been formed in a fully concrete context without capturing generic
  // arguments.
  return true;
}

SWIFT_CC(swift)
static intptr_t hashGenericArguments(const void *src, size_t bytes) {
  // Generic arguments can't affect equality, since an equivalent key path may
  // have been formed in a fully concrete context without capturing generic
  // arguments. The implementation recognizes a hash value return of '0' as
  // "no effect on the hash".
  return 0;
}

struct KeyPathGenericWitnessTable {
  void *destroy;
  SWIFT_CC(swift) void (* __ptrauth_swift_runtime_function_entry_with_key(swift::SpecialPointerAuthDiscriminators::KeyPathCopy) copy)(const void *src, void *dest, size_t bytes);
  SWIFT_CC(swift) bool (* __ptrauth_swift_runtime_function_entry_with_key(swift::SpecialPointerAuthDiscriminators::KeyPathEquals) equals)(const void *, const void *, size_t);
  SWIFT_CC(swift) intptr_t (* __ptrauth_swift_runtime_function_entry_with_key(swift::SpecialPointerAuthDiscriminators::KeyPathHash) hash)(const void *src, size_t bytes);
};

/// A prefab witness table for computed key path components that only include
/// captured generic arguments.
SWIFT_RUNTIME_EXPORT
KeyPathGenericWitnessTable swift_keyPathGenericWitnessTable = {
  nullptr,
  swift_copyKeyPathTrivialIndices,
  equateGenericArguments,
  hashGenericArguments,
};

/****************************************************************************/
/** Projection functions ****************************************************/
/****************************************************************************/

namespace {
  struct AddrAndOwner {
    OpaqueValue *Addr;
    HeapObject *Owner;
  };
}

// These functions are all implemented in the stdlib.  Their type
// parameters are passed implicitly in the isa of the key path.

extern "C"
SWIFT_CC(swift) void
swift_getAtKeyPath(SWIFT_INDIRECT_RESULT void *result,
                   const OpaqueValue *root, void *keyPath);

extern "C"
SWIFT_CC(swift) AddrAndOwner
_swift_modifyAtWritableKeyPath_impl(OpaqueValue *root, void *keyPath);

extern "C"
SWIFT_CC(swift) AddrAndOwner
_swift_modifyAtReferenceWritableKeyPath_impl(const OpaqueValue *root,
                                             void *keyPath);

namespace {
  struct YieldOnceTemporary {
    const Metadata *Type;

    // Yield-once buffers can't be memcpy'ed, so it doesn't matter that
    // isValueInline() returns false for non-bitwise-takable types --- but
    // it doesn't hurt, either.
    ValueBuffer Buffer;

    YieldOnceTemporary(const Metadata *type) : Type(type) {}

    static OpaqueValue *allocateIn(const Metadata *type,
                                   YieldOnceBuffer *buffer) {
      auto *temp =
        new (reinterpret_cast<void*>(buffer)) YieldOnceTemporary(type);
      return type->allocateBufferIn(&temp->Buffer);
    }

    static void destroyAndDeallocateIn(YieldOnceBuffer *buffer) {
      auto *temp = reinterpret_cast<YieldOnceTemporary*>(buffer);
      temp->Type->vw_destroy(temp->Type->projectBufferFrom(&temp->Buffer));
      temp->Type->deallocateBufferIn(&temp->Buffer);
    }
  };

  static_assert(sizeof(YieldOnceTemporary) <= sizeof(YieldOnceBuffer) &&
                alignof(YieldOnceTemporary) <= alignof(YieldOnceBuffer),
                "temporary doesn't fit in a YieldOnceBuffer");
}

static SWIFT_CC(swift)
void _destroy_temporary_continuation(YieldOnceBuffer *buffer, bool forUnwind) {
  YieldOnceTemporary::destroyAndDeallocateIn(buffer);
}

// The resilient offset to the start of KeyPath's class-specific data.
extern "C" size_t MANGLE_SYM(s7KeyPathCMo);

YieldOnceResult<const OpaqueValue*>
swift::swift_readAtKeyPath(YieldOnceBuffer *buffer,
                           const OpaqueValue *root, void *keyPath) {
  // The Value type parameter is passed in the class of the key path object.
  // KeyPath is a native class, so we can just load its metadata directly
  // even on ObjC-interop targets.
  const Metadata *keyPathType = static_cast<HeapObject*>(keyPath)->metadata;

  // To find the generic arguments, we just have to find the class-specific
  // data section of the class; the generic arguments are always at the start
  // of that.
  //
  // We use the resilient access pattern because it's easy; since we're within
  // KeyPath's resilience domain, that's not really necessary, and it would
  // be totally valid to hard-code an offset.
  auto keyPathGenericArgs =
    reinterpret_cast<const Metadata * const *>(
      reinterpret_cast<const char*>(keyPathType) + MANGLE_SYM(s7KeyPathCMo));
  const Metadata *valueTy = keyPathGenericArgs[1];

  // Allocate the buffer.
  auto result = YieldOnceTemporary::allocateIn(valueTy, buffer);

  // Read into the buffer.
  swift_getAtKeyPath(result, root, keyPath);

  // Return a continuation that destroys the value in the buffer
  // and deallocates it.
  return { swift_ptrauth_sign_opaque_read_resume_function(
             &_destroy_temporary_continuation, buffer),
           result };
}

static SWIFT_CC(swift)
void _release_owner_continuation(YieldOnceBuffer *buffer, bool forUnwind) {
  swift_unknownObjectRelease(buffer->Data[0]);
}

YieldOnceResult<OpaqueValue*>
swift::swift_modifyAtWritableKeyPath(YieldOnceBuffer *buffer,
                                     OpaqueValue *root, void *keyPath) {
  auto addrAndOwner =
    _swift_modifyAtWritableKeyPath_impl(root, keyPath);
  buffer->Data[0] = addrAndOwner.Owner;

  return { swift_ptrauth_sign_opaque_modify_resume_function(
             &_release_owner_continuation, buffer),
           addrAndOwner.Addr };
}

YieldOnceResult<OpaqueValue*>
swift::swift_modifyAtReferenceWritableKeyPath(YieldOnceBuffer *buffer,
                                              const OpaqueValue *root,
                                              void *keyPath) {
  auto addrAndOwner =
    _swift_modifyAtReferenceWritableKeyPath_impl(root, keyPath);
  buffer->Data[0] = addrAndOwner.Owner;

  return { swift_ptrauth_sign_opaque_modify_resume_function(
             &_release_owner_continuation, buffer),
           addrAndOwner.Addr };
}
<|endoftext|>


<commit_before>#include <windows.h>
#include <tchar.h>

#include <newpluginapi.h>
#include <m_langpack.h>
#include <m_clist.h>
#include <m_skin.h>

HINSTANCE hInst = NULL;
int hLangpack;

PLUGININFOEX pluginInfo = {
	sizeof(PLUGININFOEX),
	"Styx History Synchronizer",
	PLUGIN_MAKE_VERSION(0, 0, 0, 1),
	"History synchronizer with dedicated server.",
	"F. von Never",
	"neverthness@gmail.com",
	" 2013 F. von Never",
	"https://github.com/ForNeVeR",
	UNICODE_AWARE,
	{ 0xf38aa380, 0x2267, 0x4ff7, { 0x9b, 0x19, 0xae, 0x96, 0x6b, 0xac, 0x49, 0xd8 } } // {F38AA380-2267-4FF7-9B19-AE966BAC49D8}
};

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	hInst = hinstDLL;
	return TRUE;
}

INT_PTR PluginMenuCommand(WPARAM wParam, LPARAM lParam)
{
	MessageBox(NULL, TranslateT("Just groovy, baby!"), TranslateT("Plugin-o-rama"), MB_OK);
	return 0;
}

extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
{
	return &pluginInfo;
}

extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_TESTPLUGIN, MIID_LAST};

extern "C" __declspec(dllexport) int Load()
{
	mir_getLP(&pluginInfo);

	CLISTMENUITEM mi = {0};

	CreateServiceFunction("TestPlug/MenuCommand", PluginMenuCommand);
	mi.cbSize = sizeof(mi);
	mi.position = -0x7FFFFFFF;
	mi.flags = CMIF_TCHAR;
	mi.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
	mi.ptszName = LPGENT("&Test Plugin...");
	mi.pszService = "TestPlug/MenuCommand";
	Menu_AddMainMenuItem(&mi);
	return 0;
}

extern "C" __declspec(dllexport) int Unload(void)
{
	return 0;
}
<commit_msg>Clear coding style, adapt some code.<commit_after>#include <windows.h>
#include <tchar.h>

#include <newpluginapi.h>
#include <m_langpack.h>
#include <m_clist.h>
#include <m_skin.h>

const auto EnableServiceName = "Styx/EnableCommand";

HINSTANCE libraryInstance = nullptr;

// Do not remove - part of API.
int hLangpack;

PLUGININFOEX pluginInfo = {
	sizeof(PLUGININFOEX),
	"Styx History Synchronizer",
	PLUGIN_MAKE_VERSION(0, 0, 0, 1),
	"History synchronizer with dedicated server.",
	"F. von Never",
	"neverthness@gmail.com",
	" 2013 F. von Never",
	"https://github.com/ForNeVeR",
	UNICODE_AWARE,
	{ 0xf38aa380, 0x2267, 0x4ff7, { 0x9b, 0x19, 0xae, 0x96, 0x6b, 0xac, 0x49, 0xd8 } } // {F38AA380-2267-4FF7-9B19-AE966BAC49D8}
};

BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
	libraryInstance = instance;
	return TRUE;
}

INT_PTR EnableCommand(WPARAM wParam, LPARAM lParam)
{
	// TODO: Enable synchronization if not enabled.
	return 0;
}

extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion)
{
	return &pluginInfo;
}

extern "C" __declspec(dllexport) const MUUID interfaces[] = { MIID_LAST };

extern "C" __declspec(dllexport) int Load()
{
	mir_getLP(&pluginInfo);

	CreateServiceFunction(EnableServiceName, &EnableCommand);

	auto mi = CLISTMENUITEM();
	mi.cbSize = sizeof(mi);
	mi.position = -0x7FFFFFFF;
	mi.flags = CMIF_UNICODE;
	mi.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
	mi.ptszName = LPGENT("&Enable Styx");
	mi.pszService = const_cast<char*>(EnableServiceName);

	Menu_AddMainMenuItem(&mi);

	return 0;
}

extern "C" __declspec(dllexport) int Unload(void)
{
	// TODO: Disable synchronization if enabled.
	return 0;
}
<|endoftext|>


<commit_before>//! @Alan
//! Exercise 10.11:
//! Write a program that uses stable_sort and isShorter to sort a vector passed
//! to your version of elimDups.
//! Print the vector to verify that your program is correct.
//!

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <list>

//! print a container like vector,deque, list,etc.
template<typename Sequence>
inline std::ostream& println(Sequence const& seq)
{
    for(auto const& elem : seq) std::cout << elem << " ";
    std::cout << std::endl;

    return std::cout;
}

inline bool
is_shorter(std::string const& lhs, std::string const& rhs)
{
    return  lhs.size() < rhs.size();
}

void elimdups(std::vector<std::string> &vs)
{
    std::sort(vs.begin(), vs.end());
    auto new_end = std::unique(vs.begin(),vs.end());
    vs.erase(new_end, vs.end());
}

int main()
{
    std::vector<std::string> v{
        "1234", "1234", "1234", "Hi", "alan", "wang"
    };
    elimdups(v);
    std::stable_sort(v.begin(), v.end(), is_shorter);
    std::cout << "ex10.11 :\n";
    println(v);

    return 0;
}
//! output
//ex10.11 :
//Hi 1234 alan

<commit_msg>the comment at the end line is not right.<commit_after>//! @Alan
//! Exercise 10.11:
//! Write a program that uses stable_sort and isShorter to sort a vector passed
//! to your version of elimDups.
//! Print the vector to verify that your program is correct.
//!

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <list>

//! print a container like vector,deque, list,etc.
template<typename Sequence>
inline std::ostream& println(Sequence const& seq)
{
    for(auto const& elem : seq) std::cout << elem << " ";
    std::cout << std::endl;

    return std::cout;
}

inline bool
is_shorter(std::string const& lhs, std::string const& rhs)
{
    return  lhs.size() < rhs.size();
}

void elimdups(std::vector<std::string> &vs)
{
    std::sort(vs.begin(), vs.end());
    auto new_end = std::unique(vs.begin(),vs.end());
    vs.erase(new_end, vs.end());
}

int main()
{
    std::vector<std::string> v{
        "1234", "1234", "1234", "Hi", "alan", "wang"
    };
    elimdups(v);
    std::stable_sort(v.begin(), v.end(), is_shorter);
    std::cout << "ex10.11 :\n";
    println(v);

    return 0;
}
//! output
//ex10.11 :
//Hi 1234 alan wang

<|endoftext|>


<commit_before>// Bug 564005 - Valgrind errors and crash on exit with Gtk::UIManager
// Bug 154498 - Unnecessary warning on console: signalproxy_connectionnode.cc

#include <glibmm.h>
#include <sigc++/sigc++.h>
#include <iostream>
#include <stdlib.h>

#define ACTIVATE_BUG 1

// A class with its own reference-count, for use with RefPtr.
class Something
{
public:
  Something()
  : ref_count_(1),
    max_ref_count_(ref_count_)
  {}

  void reference()
  {
    ++ref_count_;

    //Track the highest-ever max count.
    if(max_ref_count_ < ref_count_)
      max_ref_count_ = ref_count_;
  }

  void unreference()
  {
    if (--ref_count_ <= 0)
      delete this;
  }

  //Just so we can check it in our test.
  int ref_count()
  {
    return ref_count_;
  }

  //Just so we can check it in our test.
  int max_ref_count()
  {
    return max_ref_count_;
  }

private:
  int ref_count_;
  int max_ref_count_;
};

class Parent
{
public:
  explicit Parent(const Glib::RefPtr<Something>& something)
  : something_(something),
    was_constructed_via_copy_constructor_(true),
    was_constructed_via_move_constructor_(false)
  {
  }

  explicit Parent(const Glib::RefPtr<Something>&& something)
  : something_(std::move(something)),
    was_constructed_via_copy_constructor_(false),
    was_constructed_via_move_constructor_(true)
  {
  }

  //Non copyable
  Parent(const Parent& src) = delete;
  Parent& operator=(const Parent& src) = delete;

  bool was_constructed_via_copy_constructor() const
  {
    return was_constructed_via_copy_constructor_;
  }

  bool was_constructed_via_move_constructor() const
  {
    return was_constructed_via_move_constructor_;
  }

  int something_ref_count() const
  {
    return something_->ref_count();
  }

  int something_max_ref_count() const
  {
    return something_->max_ref_count();
  }

private:
  Glib::RefPtr<Something> something_;
  bool was_constructed_via_copy_constructor_;
  bool was_constructed_via_move_constructor_;

};

static
void test_initial_refcount()
{
  Glib::RefPtr<Something> refSomething (new Something());
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
}

static
void test_refptr_copy_constructor()
{
  Glib::RefPtr<Something> refSomething (new Something());
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);

  {
    Glib::RefPtr<Something> refSomething2(refSomething);
    g_assert_cmpint(refSomething->ref_count(), ==, 2);
    g_assert_cmpint(refSomething2->ref_count(), ==, 2);
    g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
  }

  //Test the refcount after other references should have been released
  //when other RefPtrs went out of scope:
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
}

static
void test_refptr_assignment_operator()
{
  Glib::RefPtr<Something> refSomething (new Something());
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);

  {
    Glib::RefPtr<Something> refSomething2 = refSomething;
    g_assert_cmpint(refSomething->ref_count(), ==, 2);
    g_assert_cmpint(refSomething2->ref_count(), ==, 2);
    g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
  }

  //Test the refcount after other references should have been released
  //when other RefPtrs went out of scope:
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
}

static
Glib::RefPtr<Something> get_something()
{
  static Glib::RefPtr<Something> something_to_get;

  //Reinitialize it each time:
  something_to_get = Glib::RefPtr<Something>(new Something());

  return something_to_get;
}

static
void test_refptr_with_parent_copy_constructor()
{
  //We use get_something() because test_refptr_with_parent_move_constructor() does.
  Glib::RefPtr<Something> refSomething = get_something();
  g_assert_cmpint(refSomething->ref_count(), ==, 2); //1 here and 1 inside get_something()
  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);

  {
    Parent parent(refSomething);
    g_assert(!parent.was_constructed_via_move_constructor());
    g_assert(parent.was_constructed_via_copy_constructor());
    g_assert_cmpint(parent.something_ref_count(), ==, 3); //1 here, 1 in parent, and 1 inside get_something()
    g_assert_cmpint(parent.something_max_ref_count(), ==, 3);
  }

  //Test the refcount after other references should have been released
  //when other RefPtrs went out of scope:
  g_assert_cmpint(refSomething->ref_count(), ==, 2); //1 here and 1 inside get_something()
  g_assert_cmpint(refSomething->max_ref_count(), ==, 3);
}

static
void test_refptr_with_parent_move_constructor()
{
  Parent parent(get_something());
  g_assert(parent.was_constructed_via_move_constructor());
  g_assert(!parent.was_constructed_via_copy_constructor());
  g_assert_cmpint(parent.something_ref_count(), ==, 2); //1 in parent and 1 inside get_something()
  g_assert_cmpint(parent.something_max_ref_count(), ==, 3); //TODO: Avoid the extra ref in RefPtr::swap()?
}

int main(int, char**)
{
  //Test initial refcount:
  test_initial_refcount();

  //Test refcount when using the RefPtr copy constructor:
  test_refptr_copy_constructor();

  //Test refcount when using the RefPtr assignment operator (operator=):
  test_refptr_assignment_operator();

  //Test the refcount when another class makes a copy via its constructor:
  test_refptr_with_parent_copy_constructor();

  //Test the refcount when another class makes a copy via its
  //(perfect-forwarding)move constructor, which should not involve a temporary
  //instance:
  test_refptr_with_parent_move_constructor();

  return EXIT_SUCCESS;
}
<commit_msg>tests/glibmm_refptr: Correct the move constructor test.<commit_after>// Bug 564005 - Valgrind errors and crash on exit with Gtk::UIManager
// Bug 154498 - Unnecessary warning on console: signalproxy_connectionnode.cc

#include <glibmm.h>
#include <sigc++/sigc++.h>
#include <iostream>
#include <stdlib.h>

#define ACTIVATE_BUG 1

// A class with its own reference-count, for use with RefPtr.
class Something
{
public:
  Something()
  : ref_count_(1),
    max_ref_count_(ref_count_)
  {}

  void reference()
  {
    ++ref_count_;

    //Track the highest-ever max count.
    if(max_ref_count_ < ref_count_)
      max_ref_count_ = ref_count_;
  }

  void unreference()
  {
    if (--ref_count_ <= 0)
      delete this;
  }

  //Just so we can check it in our test.
  int ref_count()
  {
    return ref_count_;
  }

  //Just so we can check it in our test.
  int max_ref_count()
  {
    return max_ref_count_;
  }

private:
  int ref_count_;
  int max_ref_count_;
};

class Parent
{
public:
  explicit Parent(const Glib::RefPtr<Something>& something)
  : something_(something),
    was_constructed_via_copy_constructor_(true),
    was_constructed_via_move_constructor_(false)
  {
  }

  explicit Parent(Glib::RefPtr<Something>&& something)
  : something_(std::move(something)),
    was_constructed_via_copy_constructor_(false),
    was_constructed_via_move_constructor_(true)
  {
  }

  //Non copyable
  Parent(const Parent& src) = delete;
  Parent& operator=(const Parent& src) = delete;

  bool was_constructed_via_copy_constructor() const
  {
    return was_constructed_via_copy_constructor_;
  }

  bool was_constructed_via_move_constructor() const
  {
    return was_constructed_via_move_constructor_;
  }

  int something_ref_count() const
  {
    return something_->ref_count();
  }

  int something_max_ref_count() const
  {
    return something_->max_ref_count();
  }

private:
  Glib::RefPtr<Something> something_;
  bool was_constructed_via_copy_constructor_;
  bool was_constructed_via_move_constructor_;

};

static
void test_initial_refcount()
{
  Glib::RefPtr<Something> refSomething (new Something());
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);
}

static
void test_refptr_copy_constructor()
{
  Glib::RefPtr<Something> refSomething (new Something());
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);

  {
    Glib::RefPtr<Something> refSomething2(refSomething);
    g_assert_cmpint(refSomething->ref_count(), ==, 2);
    g_assert_cmpint(refSomething2->ref_count(), ==, 2);
    g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
  }

  //Test the refcount after other references should have been released
  //when other RefPtrs went out of scope:
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
}

static
void test_refptr_assignment_operator()
{
  Glib::RefPtr<Something> refSomething (new Something());
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 1);

  {
    Glib::RefPtr<Something> refSomething2 = refSomething;
    g_assert_cmpint(refSomething->ref_count(), ==, 2);
    g_assert_cmpint(refSomething2->ref_count(), ==, 2);
    g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
  }

  //Test the refcount after other references should have been released
  //when other RefPtrs went out of scope:
  g_assert_cmpint(refSomething->ref_count(), ==, 1);
  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);
}

static
Glib::RefPtr<Something> get_something()
{
  static Glib::RefPtr<Something> something_to_get;

  //Reinitialize it each time:
  something_to_get = Glib::RefPtr<Something>(new Something());

  return something_to_get;
}

static
void test_refptr_with_parent_copy_constructor()
{
  //We use get_something() because test_refptr_with_parent_move_constructor() does.
  Glib::RefPtr<Something> refSomething = get_something();
  g_assert_cmpint(refSomething->ref_count(), ==, 2); //1 here and 1 inside get_something()
  g_assert_cmpint(refSomething->max_ref_count(), ==, 2);

  {
    Parent parent(refSomething);
    g_assert(!parent.was_constructed_via_move_constructor());
    g_assert(parent.was_constructed_via_copy_constructor());
    g_assert_cmpint(parent.something_ref_count(), ==, 3); //1 here, 1 in parent, and 1 inside get_something()
    g_assert_cmpint(parent.something_max_ref_count(), ==, 3);
  }

  //Test the refcount after other references should have been released
  //when other RefPtrs went out of scope:
  g_assert_cmpint(refSomething->ref_count(), ==, 2); //1 here and 1 inside get_something()
  g_assert_cmpint(refSomething->max_ref_count(), ==, 3);
}

static
void test_refptr_with_parent_move_constructor()
{
  Parent parent(get_something());
  g_assert(parent.was_constructed_via_move_constructor());
  g_assert(!parent.was_constructed_via_copy_constructor());
  g_assert_cmpint(parent.something_ref_count(), ==, 2); //1 in parent and 1 inside get_something()
  g_assert_cmpint(parent.something_max_ref_count(), ==, 2);
}

int main(int, char**)
{
  //Test initial refcount:
  test_initial_refcount();

  //Test refcount when using the RefPtr copy constructor:
  test_refptr_copy_constructor();

  //Test refcount when using the RefPtr assignment operator (operator=):
  test_refptr_assignment_operator();

  //Test the refcount when another class makes a copy via its constructor:
  test_refptr_with_parent_copy_constructor();

  //Test the refcount when another class makes a copy via its
  //(perfect-forwarding)move constructor, which should not involve a temporary
  //instance:
  test_refptr_with_parent_move_constructor();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Petter Strandmark 2012--2013
//
// Test functions from
// Jorge J. More, Burton S. Garbow and Kenneth E. Hillstrom,
// "Testing unconstrained optimization software",
// Transactions on Mathematical Software 7(1):17-41, 1981.
// http://www.caam.rice.edu/~zhang/caam454/nls/MGH.pdf
//
#include <cmath>
#include <iostream>
#include <memory>
#include <random>
#include <sstream>

#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <spii/google_test_compatibility.h>

#include <spii/auto_diff_term.h>
#include <spii/solver.h>

using namespace spii;

std::stringstream global_string_stream;
void info_log_function(const std::string& str)
{
	global_string_stream << str << "\n";
}

std::unique_ptr<Solver> create_solver()
{
	std::unique_ptr<NewtonSolver> solver(new NewtonSolver);
	solver->log_function = info_log_function;

	solver->function_improvement_tolerance = 0;
	solver->argument_improvement_tolerance = 0;
	solver->gradient_tolerance = 1e-7;

	return std::move(solver);
}

int cumulative_iterations   = 0;
int cumulative_evalutations = 0;
double cumulative_time      = 0;

template<typename Functor, int dimension>
double run_test_with_factorization_method(double* var, Solver* solver)
{
	Function f;
	f.add_variable(var, dimension);
	f.add_term(std::make_shared<AutoDiffTerm<Functor, dimension>>(), var);

	SolverResults results;
	global_string_stream.str("");
	solver->solve(f, &results);
	INFO(global_string_stream.str());
	INFO(results);

	std::stringstream sout;
	for (int i = 0; i < dimension; ++i) {
		sout << "x" << i + 1 << " = " << var[i] << ",  ";
	}
	INFO(sout.str());

	EXPECT_TRUE(results.exit_condition == SolverResults::GRADIENT_TOLERANCE);

	cumulative_evalutations += f.evaluations_with_gradient;
	cumulative_time         += results.total_time - results.log_time;
	INFO("Cumulative evaluations: " << cumulative_evalutations);
	INFO("Cumulative time       : " << cumulative_time);

	return f.evaluate();
}

class Powell3D;

template<typename Functor, int dimension>
double run_test(double* var, Solver* solver_input = 0)
{
	auto own_solver = create_solver();
	if (solver_input == 0) {
		solver_input = own_solver.get();
	}
	auto solver = dynamic_cast<NewtonSolver*>(solver_input);
	spii_assert(solver);

	// First, test that the iterative factorization method
	// achieves convergence.
	std::vector<double> var_copy(var, var + dimension);
	solver->factorization_method = NewtonSolver::ITERATIVE;
	run_test_with_factorization_method<Functor, dimension>(&var_copy[0], solver);

	// Then, test the BKP factorization and return the results using
	// this method.
	solver->factorization_method = NewtonSolver::BKP;

	//--------------------
	//TODO: Investigate further.
	//
	if (typeid(Functor) == typeid(Powell3D)) {
		solver->gradient_tolerance = 1e-1;
	}
	//--------------------

	return run_test_with_factorization_method<Functor, dimension>(var, solver);
}

#include "suite_more_et_al.h"
#include "suite_test_opt.h"
#include "suite_uctp.h"
<commit_msg>Fix compilation error in Clang.<commit_after>// Petter Strandmark 2012--2013
//
// Test functions from
// Jorge J. More, Burton S. Garbow and Kenneth E. Hillstrom,
// "Testing unconstrained optimization software",
// Transactions on Mathematical Software 7(1):17-41, 1981.
// http://www.caam.rice.edu/~zhang/caam454/nls/MGH.pdf
//
#include <cmath>
#include <iostream>
#include <memory>
#include <random>
#include <sstream>

#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <spii/google_test_compatibility.h>

#include <spii/auto_diff_term.h>
#include <spii/solver.h>

using namespace spii;

std::stringstream global_string_stream;
void info_log_function(const std::string& str)
{
	global_string_stream << str << "\n";
}

std::unique_ptr<Solver> create_solver()
{
	std::unique_ptr<NewtonSolver> solver(new NewtonSolver);
	solver->log_function = info_log_function;

	solver->function_improvement_tolerance = 0;
	solver->argument_improvement_tolerance = 0;
	solver->gradient_tolerance = 1e-7;

	return std::move(solver);
}

int cumulative_iterations   = 0;
int cumulative_evalutations = 0;
double cumulative_time      = 0;

template<typename Functor, int dimension>
double run_test_with_factorization_method(double* var, Solver* solver)
{
	Function f;
	f.add_variable(var, dimension);
	f.add_term(std::make_shared<AutoDiffTerm<Functor, dimension>>(), var);

	SolverResults results;
	global_string_stream.str("");
	solver->solve(f, &results);
	INFO(global_string_stream.str());
	INFO(results);

	std::stringstream sout;
	for (int i = 0; i < dimension; ++i) {
		sout << "x" << i + 1 << " = " << var[i] << ",  ";
	}
	INFO(sout.str());

	EXPECT_TRUE(results.exit_condition == SolverResults::GRADIENT_TOLERANCE);

	cumulative_evalutations += f.evaluations_with_gradient;
	cumulative_time         += results.total_time - results.log_time;
	INFO("Cumulative evaluations: " << cumulative_evalutations);
	INFO("Cumulative time       : " << cumulative_time);

	return f.evaluate();
}

template<typename Functor, int dimension>
double run_test(double* var, Solver* solver_input = 0)
{
	auto own_solver = create_solver();
	if (solver_input == 0) {
		solver_input = own_solver.get();
	}
	auto solver = dynamic_cast<NewtonSolver*>(solver_input);
	spii_assert(solver);

	// First, test that the iterative factorization method
	// achieves convergence.
	std::vector<double> var_copy(var, var + dimension);
	solver->factorization_method = NewtonSolver::ITERATIVE;
	run_test_with_factorization_method<Functor, dimension>(&var_copy[0], solver);

	// Then, test the BKP factorization and return the results using
	// this method.
	solver->factorization_method = NewtonSolver::BKP;

	//--------------------
	//TODO: Investigate further.
	//
	std::string functor_name = typeid(Functor).name();
	if (functor_name.find("Powell3D") != std::string::npos) {
		solver->gradient_tolerance = 1e-1;
	}
	//--------------------

	return run_test_with_factorization_method<Functor, dimension>(var, solver);
}

#include "suite_more_et_al.h"
#include "suite_test_opt.h"
#include "suite_uctp.h"
<|endoftext|>


<commit_before>#ifndef THREAD_POOL_HPP
#define THREAD_POOL_HPP

#include <noncopyable.hpp>
#include <worker.hpp>
#include <atomic>
#include <stdexcept>
#include <memory>
#include <vector>
#include <future>
#include <type_traits>

/**
 * @brief The ThreadPoolOptions struct provides construction options for ThreadPool.
 */
struct ThreadPoolOptions {
    enum {AUTODETECT = 0};
    size_t threads_count = AUTODETECT;
    size_t worker_queue_size = 1024;
};

/**
 * @brief The ThreadPool class implements thread pool pattern.
 * It is highly scalable and fast.
 * It is header only.
 * It implements both work-stealing and work-distribution balancing startegies.
 * It implements cooperative scheduling strategy for tasks.
 */
class ThreadPool : NonCopyable {
public:
    /**
     * @brief ThreadPool Construct and start new thread pool.
     * @param options Creation options.
     */
    explicit ThreadPool(const ThreadPoolOptions &options = ThreadPoolOptions());

    /**
     * @brief ~ThreadPool Stop all workers and destroy thread pool.
     */
    ~ThreadPool();

    /**
     * @brief post Post piece of job to thread pool.
     * @param handler Handler to be called from thread pool worker. It has to be callable as 'handler()'.
     * @throws std::overflow_error if worker's queue is full.
     * @note All exceptions thrown by handler will be suppressed. Use process to get result of handler's
     * execution or exception rised.
     */
    template <typename Handler>
    void post(Handler &&handler);

    /**
     * @brief process Post piece of job to thread pool and get future for this job.
     * @param handler Handler to be called from thread pool worker. It has to be callable as 'handler()'.
     * @return Future which hold handler result or rised exception.
     * @throws std::overflow_error if worker's queue is full.
     */
    template <typename Handler, typename R = typename std::result_of<Handler()>::type>
    typename std::future<R> process(Handler &&handler);

private:
    /**
     * @brief get_worker Helper function to select next executing worker.
     * @return Reference to worker.
     */
    Worker & getWorker();

    std::vector<std::unique_ptr<Worker>> m_workers;
    std::atomic<size_t> m_next_worker;
};

/// Implementation

inline ThreadPool::ThreadPool(const ThreadPoolOptions &options)
    : m_next_worker(0)
{
    size_t workers_count = options.threads_count;

    if (ThreadPoolOptions::AUTODETECT == options.threads_count) {
        workers_count = std::thread::hardware_concurrency();
    }

    if (0 == workers_count) {
        workers_count = 1;
    }

    m_workers.resize(workers_count);
    for (auto &worker_ptr : m_workers) {
        worker_ptr.reset(new Worker(options.worker_queue_size));
    }

    for (size_t i = 0; i < m_workers.size(); ++i) {
        Worker *steal_donor = m_workers[(i + 1) % m_workers.size()].get();
        m_workers[i]->start(i, steal_donor);
    }
}

inline ThreadPool::~ThreadPool()
{
    for (auto &worker_ptr : m_workers) {
        worker_ptr->stop();
    }
}

template <typename Handler>
inline void ThreadPool::post(Handler &&handler)
{
    if (!getWorker().post(std::forward<Handler>(handler)))
    {
        throw std::overflow_error("worker queue is full");
    }
}

template <typename Handler, typename R>
typename std::future<R> ThreadPool::process(Handler &&handler)
{
    std::packaged_task<R()> task([handler = std::move(handler)] () {
        return handler();
    });

    std::future<R> result = task.get_future();

    if (!getWorker().post(task))
    {
        throw std::overflow_error("worker queue is full");
    }

    return result;
}

inline Worker & ThreadPool::getWorker()
{
    size_t id = Worker::getWorkerIdForCurrentThread();

    if (id > m_workers.size()) {
        id = m_next_worker.fetch_add(1, std::memory_order_relaxed) % m_workers.size();
    }

    return *m_workers[id];
}

#endif

<commit_msg>update comment<commit_after>#ifndef THREAD_POOL_HPP
#define THREAD_POOL_HPP

#include <noncopyable.hpp>
#include <worker.hpp>
#include <atomic>
#include <stdexcept>
#include <memory>
#include <vector>
#include <future>
#include <type_traits>

/**
 * @brief The ThreadPoolOptions struct provides construction options for ThreadPool.
 */
struct ThreadPoolOptions {
    enum {AUTODETECT = 0};
    size_t threads_count = AUTODETECT;
    size_t worker_queue_size = 1024;
};

/**
 * @brief The ThreadPool class implements thread pool pattern.
 * It is highly scalable and fast.
 * It is header only.
 * It implements both work-stealing and work-distribution balancing startegies.
 * It implements cooperative scheduling strategy for tasks.
 */
class ThreadPool : NonCopyable {
public:
    /**
     * @brief ThreadPool Construct and start new thread pool.
     * @param options Creation options.
     */
    explicit ThreadPool(const ThreadPoolOptions &options = ThreadPoolOptions());

    /**
     * @brief ~ThreadPool Stop all workers and destroy thread pool.
     */
    ~ThreadPool();

    /**
     * @brief post Post piece of job to thread pool.
     * @param handler Handler to be called from thread pool worker. It has to be callable as 'handler()'.
     * @throws std::overflow_error if worker's queue is full.
     * @note All exceptions thrown by handler will be suppressed. Use process to get result of handler's
     * execution or exception rised.
     */
    template <typename Handler>
    void post(Handler &&handler);

    /**
     * @brief process Post piece of job to thread pool and get future for this job.
     * @param handler Handler to be called from thread pool worker. It has to be callable as 'handler()'.
     * @return Future which hold handler result or raised exception.
     * @throws std::overflow_error if worker's queue is full.
     * @note This method of posting job to thread pool is much slower than 'post' due to std::future and
     * std::packaged_task construction overhead.
     */
    template <typename Handler, typename R = typename std::result_of<Handler()>::type>
    typename std::future<R> process(Handler &&handler);

private:
    /**
     * @brief get_worker Helper function to select next executing worker.
     * @return Reference to worker.
     */
    Worker & getWorker();

    std::vector<std::unique_ptr<Worker>> m_workers;
    std::atomic<size_t> m_next_worker;
};

/// Implementation

inline ThreadPool::ThreadPool(const ThreadPoolOptions &options)
    : m_next_worker(0)
{
    size_t workers_count = options.threads_count;

    if (ThreadPoolOptions::AUTODETECT == options.threads_count) {
        workers_count = std::thread::hardware_concurrency();
    }

    if (0 == workers_count) {
        workers_count = 1;
    }

    m_workers.resize(workers_count);
    for (auto &worker_ptr : m_workers) {
        worker_ptr.reset(new Worker(options.worker_queue_size));
    }

    for (size_t i = 0; i < m_workers.size(); ++i) {
        Worker *steal_donor = m_workers[(i + 1) % m_workers.size()].get();
        m_workers[i]->start(i, steal_donor);
    }
}

inline ThreadPool::~ThreadPool()
{
    for (auto &worker_ptr : m_workers) {
        worker_ptr->stop();
    }
}

template <typename Handler>
inline void ThreadPool::post(Handler &&handler)
{
    if (!getWorker().post(std::forward<Handler>(handler)))
    {
        throw std::overflow_error("worker queue is full");
    }
}

template <typename Handler, typename R>
typename std::future<R> ThreadPool::process(Handler &&handler)
{
    std::packaged_task<R()> task([handler = std::move(handler)] () {
        return handler();
    });

    std::future<R> result = task.get_future();

    if (!getWorker().post(task))
    {
        throw std::overflow_error("worker queue is full");
    }

    return result;
}

inline Worker & ThreadPool::getWorker()
{
    size_t id = Worker::getWorkerIdForCurrentThread();

    if (id > m_workers.size()) {
        id = m_next_worker.fetch_add(1, std::memory_order_relaxed) % m_workers.size();
    }

    return *m_workers[id];
}

#endif

<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "thrift_validation.hh"
#include "thrift/utils.hh"
#include "db/system_keyspace.hh"
#include <regex>
#include "utils/fb_utilities.hh"

using namespace thrift;
using namespace ::apache::thrift;

namespace thrift_validation {

void validate_key(const schema& s, const bytes_view& k) {
    if (k.empty()) {
        throw make_exception<InvalidRequestException>("Key may not be empty");
    }

    auto max = static_cast<uint32_t>(utils::fb_utilities::MAX_UNSIGNED_SHORT);
    if (k.size() > max) {
        throw make_exception<InvalidRequestException>("Key length of %d is longer than maximum of %d", k.size(), max);
    }

    // FIXME: implement
    //s.partition_key_type()->validate(k);
}

void validate_keyspace_not_system(const std::string& keyspace) {
    std::string name;
    name.resize(keyspace.length());
    std::transform(keyspace.begin(), keyspace.end(), name.begin(), ::tolower);
    if (is_system_keyspace(name)) {
        throw make_exception<InvalidRequestException>("system keyspace is not user-modifiable");
    }
}

void validate_ks_def(const KsDef& ks_def) {
    validate_keyspace_not_system(ks_def.name);
    std::regex name_regex("\\w+");
    if (!std::regex_match(ks_def.name, name_regex)) {
        throw make_exception<InvalidRequestException>("\"%s\" is not a valid keyspace name", ks_def.name);
    }
    if (ks_def.name.length() > schema::NAME_LENGTH) {
        throw make_exception<InvalidRequestException>("Keyspace names shouldn't be more than %d characters long (got \"%s\")", schema::NAME_LENGTH, ks_def.name);
    }
}

void validate_cf_def(const CfDef& cf_def) {
    std::regex name_regex("\\w+");
    if (!std::regex_match(cf_def.name, name_regex)) {
        throw make_exception<InvalidRequestException>("\"%s\" is not a valid column family name", cf_def.name);
    }
    if (cf_def.name.length() > schema::NAME_LENGTH) {
        throw make_exception<InvalidRequestException>("Keyspace names shouldn't be more than %d characters long (got \"%s\")", schema::NAME_LENGTH, cf_def.name);
    }
}

void validate_column_name(const std::string& name) {
    auto max_name_length = static_cast<uint32_t>(utils::fb_utilities::MAX_UNSIGNED_SHORT);
    if (name.size() > max_name_length) {
        throw make_exception<InvalidRequestException>("column name length must not be greater than %s", max_name_length);
    }
    if (name.empty()) {
        throw make_exception<InvalidRequestException>("column name must not be empty");
    }
}

void validate_column_names(const std::vector<std::string>& names) {
    for (auto&& name : names) {
        validate_column_name(name);
    }
}

void validate_column(const Column& col, const column_definition& def) {
    if (!col.__isset.value) {
        throw make_exception<InvalidRequestException>("Column value is required");
    }
    if (!col.__isset.timestamp) {
        throw make_exception<InvalidRequestException>("Column timestamp is required");
    }
    def.type->validate(to_bytes_view(col.value));
}

}
<commit_msg>thrift: validate_column_name: fix exception format string<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "thrift_validation.hh"
#include "thrift/utils.hh"
#include "db/system_keyspace.hh"
#include <regex>
#include "utils/fb_utilities.hh"

using namespace thrift;
using namespace ::apache::thrift;

namespace thrift_validation {

void validate_key(const schema& s, const bytes_view& k) {
    if (k.empty()) {
        throw make_exception<InvalidRequestException>("Key may not be empty");
    }

    auto max = static_cast<uint32_t>(utils::fb_utilities::MAX_UNSIGNED_SHORT);
    if (k.size() > max) {
        throw make_exception<InvalidRequestException>("Key length of %d is longer than maximum of %d", k.size(), max);
    }

    // FIXME: implement
    //s.partition_key_type()->validate(k);
}

void validate_keyspace_not_system(const std::string& keyspace) {
    std::string name;
    name.resize(keyspace.length());
    std::transform(keyspace.begin(), keyspace.end(), name.begin(), ::tolower);
    if (is_system_keyspace(name)) {
        throw make_exception<InvalidRequestException>("system keyspace is not user-modifiable");
    }
}

void validate_ks_def(const KsDef& ks_def) {
    validate_keyspace_not_system(ks_def.name);
    std::regex name_regex("\\w+");
    if (!std::regex_match(ks_def.name, name_regex)) {
        throw make_exception<InvalidRequestException>("\"%s\" is not a valid keyspace name", ks_def.name);
    }
    if (ks_def.name.length() > schema::NAME_LENGTH) {
        throw make_exception<InvalidRequestException>("Keyspace names shouldn't be more than %d characters long (got \"%s\")", schema::NAME_LENGTH, ks_def.name);
    }
}

void validate_cf_def(const CfDef& cf_def) {
    std::regex name_regex("\\w+");
    if (!std::regex_match(cf_def.name, name_regex)) {
        throw make_exception<InvalidRequestException>("\"%s\" is not a valid column family name", cf_def.name);
    }
    if (cf_def.name.length() > schema::NAME_LENGTH) {
        throw make_exception<InvalidRequestException>("Keyspace names shouldn't be more than %d characters long (got \"%s\")", schema::NAME_LENGTH, cf_def.name);
    }
}

void validate_column_name(const std::string& name) {
    auto max_name_length = static_cast<uint32_t>(utils::fb_utilities::MAX_UNSIGNED_SHORT);
    if (name.size() > max_name_length) {
        throw make_exception<InvalidRequestException>("column name length must not be greater than %u", max_name_length);
    }
    if (name.empty()) {
        throw make_exception<InvalidRequestException>("column name must not be empty");
    }
}

void validate_column_names(const std::vector<std::string>& names) {
    for (auto&& name : names) {
        validate_column_name(name);
    }
}

void validate_column(const Column& col, const column_definition& def) {
    if (!col.__isset.value) {
        throw make_exception<InvalidRequestException>("Column value is required");
    }
    if (!col.__isset.timestamp) {
        throw make_exception<InvalidRequestException>("Column timestamp is required");
    }
    def.type->validate(to_bytes_view(col.value));
}

}
<|endoftext|>


<commit_before>#include "CTerm.h"
#include "CTermTree.h"

#include <algorithm>
#include <iostream>

using namespace std;

/* AVL class definition */
template <class T>
void CTermTree<T>::rebalance(CTerm<T> *n) {
    setBalance(n);

    if (n == NULL) return;

    if (n->balance == -2) {
        if (height(n->left->left) >= height(n->left->right))
            n = rotateRight(n);
        else
            n = rotateLeftThenRight(n);
    }
    else if (n->balance == 2) {
        if (height(n->right->right) >= height(n->right->left))
            n = rotateLeft(n);
        else
            n = rotateRightThenLeft(n);
    }

    if (n->parent != NULL) {
        rebalance(n->parent);
    }
    else {
        root = n;
    }
}

template <class T>
CTerm<T>* CTermTree<T>::rotateLeft(CTerm<T> *a) {
    cout << "ROTATE LEFT" << endl;
    CTerm<T> *b = a->right;
    b->parent = a->parent;
    a->right = b->left;

    if (a->right != NULL)
        a->right->parent = a;

    b->left = a;
    a->parent = b;

    if (b->parent != NULL) {
        if (b->parent->right == a) {
            b->parent->right = b;
        }
        else {
            b->parent->left = b;
        }
    }

    setBalance(a);
    setBalance(b);
    return b;
}

template <class T>
CTerm<T>* CTermTree<T>::rotateRight(CTerm<T> *a) {
    cout << "ROTATE RIGHT" << endl;
    CTerm<T> *b = a->left;
    b->parent = a->parent;
    a->left = b->right;

    if (a->left != NULL)
        a->left->parent = a;

    b->right = a;
    a->parent = b;

    if (b->parent != NULL) {
        if (b->parent->right == a) {
            b->parent->right = b;
        }
        else {
            b->parent->left = b;
        }
    }

    setBalance(a);
    setBalance(b);
    return b;
}

template <class T>
CTerm<T>* CTermTree<T>::rotateLeftThenRight(CTerm<T> *n) {
    n->left = rotateLeft(n->left);
    return rotateRight(n);
}

template <class T>
CTerm<T>* CTermTree<T>::rotateRightThenLeft(CTerm<T> *n) {
    n->right = rotateRight(n->right);
    return rotateLeft(n);
}

template <class T>
int CTermTree<T>::height(CTerm<T> *n) {
    if (n == NULL)
        return -1;
    return 1 + std::max(height(n->left), height(n->right));
}

template <class T>
void CTermTree<T>::setBalance(CTerm<T> *n) {
    n->balance = height(n->right) - height(n->left);
}

template <class T>
void CTermTree<T>::printBalance(CTerm<T> *n) {
    if (n != NULL) {
        printBalance(n->left);
        std::cout << n->balance << " ";
        printBalance(n->right);
    }
}

template <class T>
void CTermTree<T>::printInOrder(CTerm<T> *n) {
    if (n != NULL) {
        printInOrder(n->left);
        std::cout << n->key << ":"<< &n << ",";
        printInOrder(n->right);
    }
}

template <class T>
void CTermTree<T>::renderInOrder(CTerm<T> *n, int level) {

    // int i;
    // if (n!=NULL)
    // {
    //     display(n->right, level + 1);
    //     printf("\n");
    //     if (n == root)
    //     cout<<"Root -> ";
    //     for (i = 0; i < level && ptr != root; i++)
    //         cout<<"        ";
    //     cout<<ptr->data;
    //     display(ptr->left, level + 1);
    // }

    if (n != NULL) {
        renderInOrder(n->right, level+1);
      // for (int i = 0; i < level; i++)
      //   cout<<"---";
        cout << endl;
        //cout << endl;
      for (int i = 0; i < level; i++)
        if (level > 1) cout<<"        ";
        cout << "->" << n->key;
        renderInOrder(n->left, level+1);
    }

}

template <class T>
CTerm<T>* CTermTree<T>::findMin(CTerm<T> *n) {
    return (n->left) ? findMin(n->left) : n;
}

template <class T>
CTermTree<T>::CTermTree(void) : root(NULL) {}

template <class T>
CTermTree<T>::~CTermTree(void) {
    delete root;
}

template <class T>
bool CTermTree<T>::insert(T key) {
    if (root == NULL) {
        root = new CTerm<T>(key, NULL);
    }
    else {
        CTerm<T>
            *n = root,
            *parent;

        while (true) {
            if (n->key == key)
                return false;

            parent = n;

            bool goLeft = n->key > key;
            n = goLeft ? n->left : n->right;

            if (n == NULL) {
                if (goLeft) {
                    parent->left = new CTerm<T>(key, parent);
                }
                else {
                    parent->right = new CTerm<T>(key, parent);
                }

                //rebalance(parent);
                break;
            }
        }
    }

    return true;
}

template <class T>
CTerm<T>* CTermTree<T>::deleteKey2(CTerm<T> *r, T delKey){
  if(r == NULL) return r;
  else if(delKey < r->key) r->left  = deleteKey2(r->left,  delKey);
  else if(delKey > r->key) r->right = deleteKey2(r->right, delKey);
  else {
    //cout << "Nasiel som: " << delKey << endl;
    // Case 1: No Child
    if(r->left == NULL && r->right == NULL){
      //cout << "Deti nemal" << endl;
      delete r;
      r = NULL;
    // Case 2: one child
    } else if(r->left == NULL){
      //CTerm<T> *temp = r;
      r = r->right;
      rebalance(r);
      //delete temp;
      //cout << "Mal praveho syna" << endl;
    } else if(r->right == NULL){
      //CTerm<T> *temp = r;
      r = r->left;
      rebalance(r);
      //delete temp;
      //cout << "Mal laveho syna" << endl;
    } else{
      CTerm<T> *temp = findMin(r->right);
      //cout << "Mal oboch synov a nasledovnik je: " << temp->key << endl;
      r->key = temp->key;
      r->right = deleteKey2(r->right, temp->key);
    }

    //rebalance(r);

  }
  //rebalance(r);
  return r;
}

template <class T>
void CTermTree<T>::deleteKey3(const T delKey) {
  root = deleteKey2(root, delKey);
}

template <class T>
void CTermTree<T>::deleteKey(const T delKey) {
    if (root == NULL)
        return;

    CTerm<T>
        *n       = root,
        *parent  = root,
        *delNode = NULL,
        *child   = root;

    while (child != NULL) {
        parent = n;
        n = child;
        child = delKey >= n->key ? n->right : n->left;
        if (delKey == n->key)
        {
            delNode = n;
        }
    }

    /*cout << "N = " << n->key;
    cout << ", PARENT = " << parent->key;
    cout << ", DELNODE = " << delNode->key << endl;*/
    //cout << ", CHILD = " << child->key << endl;

    if (delNode != NULL) {
        delNode->key = n->key;

        child = n->left != NULL ? n->left : n->right;
        //cout << "CHILD = " << child->key << endl;
        if (root->key == delKey) {
            //CTerm<T> * newRoot = child;
            root = child;
            cout << "WHOOP root " << endl;
        }
        else {
            if (parent->left == n) {
                delete parent->right;
                cout << "OLD" << parent->left;
                parent->left = child;
                cout << "; NEW" << parent->left << endl;
            }
            else {
                delete parent->left;
                cout << "OLD" << parent->right;
                parent->right = child;
                cout << "; NEW" << parent->right << endl;
            }

            rebalance(parent);

        }
    }
}

template <class T>
void CTermTree<T>::printBalance() {
    printBalance(root);
    std::cout << std::endl;
}

template <class T>
void CTermTree<T>::printInOrder() {
    printInOrder(root);
    std::cout << std::endl;
}

template <class T>
void CTermTree<T>::renderInOrder() {
    renderInOrder(root, 1);
    std::cout << std::endl;
}

template <class T>
T CTermTree<T>::findMin() {
    CTerm<T> *minKey = findMin(root);
    return minKey->key;
}

template <class T>
bool CTermTree<T>::search(const T delKey) {
    if (root == NULL)
        return false;

    CTerm<T>
        *n        = root,
        *parent   = root,
        *findNode = NULL,
        *child   = root;

    while (child != NULL) {
        parent = n;
        n = child;
        child = delKey >= n->key ? n->right : n->left;
        if (delKey == n->key)
            return true;
    }
    return false;
}
<commit_msg>Fixing AVL for good I hope<commit_after>#include "CTerm.h"
#include "CTermTree.h"

#include <algorithm>
#include <iostream>

using namespace std;

/* AVL class definition */
template <class T>
void CTermTree<T>::rebalance(CTerm<T> *n) {
    setBalance(n);

    if (n->balance <= -2) {
        if (height(n->left->left) >= height(n->left->right))
            n = rotateRight(n);
        else
            n = rotateLeftThenRight(n);
    }
    else if (n->balance >= 2) {
        if (height(n->right->right) >= height(n->right->left))
            n = rotateLeft(n);
        else
            n = rotateRightThenLeft(n);
    }

    if (n->parent != NULL) {
        rebalance(n->parent);
    }
    else {
        root = n;
    }
}

template <class T>
CTerm<T>* CTermTree<T>::rotateLeft(CTerm<T> *a) {
    //cout << "ROTATE LEFT" << endl;
    CTerm<T> *b = a->right;
    b->parent = a->parent;
    a->right = b->left;

    if (a->right != NULL)
        a->right->parent = a;

    b->left = a;
    a->parent = b;

    if (b->parent != NULL) {
        if (b->parent->right == a) {
            b->parent->right = b;
        }
        else {
            b->parent->left = b;
        }
    }

    setBalance(a);
    setBalance(b);
    return b;
}

template <class T>
CTerm<T>* CTermTree<T>::rotateRight(CTerm<T> *a) {
    //cout << "ROTATE RIGHT" << endl;
    CTerm<T> *b = a->left;
    b->parent = a->parent;
    a->left = b->right;

    if (a->left != NULL)
        a->left->parent = a;

    b->right = a;
    a->parent = b;

    if (b->parent != NULL) {
        if (b->parent->right == a) {
            b->parent->right = b;
        }
        else {
            b->parent->left = b;
        }
    }

    setBalance(a);
    setBalance(b);
    return b;
}

template <class T>
CTerm<T>* CTermTree<T>::rotateLeftThenRight(CTerm<T> *n) {
    n->left = rotateLeft(n->left);
    return rotateRight(n);
}

template <class T>
CTerm<T>* CTermTree<T>::rotateRightThenLeft(CTerm<T> *n) {
    n->right = rotateRight(n->right);
    return rotateLeft(n);
}

template <class T>
int CTermTree<T>::height(CTerm<T> *n) {
    if (n == NULL)
        return -1;
    return 1 + std::max(height(n->left), height(n->right));
}

template <class T>
void CTermTree<T>::setBalance(CTerm<T> *n) {
    n->balance = height(n->right) - height(n->left);
}

template <class T>
void CTermTree<T>::printBalance(CTerm<T> *n) {
    if (n != NULL) {
        printBalance(n->left);
        std::cout << n->balance << " ";
        printBalance(n->right);
    }
}

template <class T>
void CTermTree<T>::printInOrder(CTerm<T> *n) {
    if (n != NULL) {
        printInOrder(n->left);
        std::cout << n->key;
        if (n->parent) cout << "|_" << n->parent->key << "_| ";
        else cout << "|_NULL_| ";
        cout <<"(";
        if (n->left) cout << n->left->key << "<-";
        if (n->right) cout << "->" << n->right->key;
        cout << "), ";
        printInOrder(n->right);
    }
}

template <class T>
void CTermTree<T>::renderInOrder(CTerm<T> *n, int level) {

    if (n != NULL) {
        renderInOrder(n->right, level+1);
      // for (int i = 0; i < level; i++)
      //   cout<<"---";
        cout << endl;
        //cout << endl;
      for (int i = 0; i < level; i++)
        if (level > 1) cout<<"        ";
        cout << "->" << n->key;
        renderInOrder(n->left, level+1);
    }

}

template <class T>
CTerm<T>* CTermTree<T>::findMin(CTerm<T> *n) {
    return (n->left) ? findMin(n->left) : n;
}

template <class T>
CTermTree<T>::CTermTree(void) : root(NULL) {}

template <class T>
CTermTree<T>::~CTermTree(void) {
    delete root;
}

template <class T>
bool CTermTree<T>::insert(T key) {
    if (root == NULL) {
        root = new CTerm<T>(key, NULL);
    }
    else {
        CTerm<T>
            *n = root,
            *parent;

        while (true) {
            if (n->key == key)
                return false;

            parent = n;

            bool goLeft = n->key > key;
            n = goLeft ? n->left : n->right;

            if (n == NULL) {
                if (goLeft) {
                    parent->left = new CTerm<T>(key, parent);
                }
                else {
                    parent->right = new CTerm<T>(key, parent);
                }

                rebalance(parent);
                break;
            }
        }
    }

    return true;
}

template <class T>
void CTermTree<T>::deleteKey(const T delKey) {
    if (root == NULL)
        return;

    CTerm<T>
        *n       = root,
        *parent  = root,
        *delNode = NULL,
        *child   = root;

    while (child != NULL) {
        parent = n;
        n = child;
        child = delKey >= n->key ? n->right : n->left;
        if (delKey == n->key)
        {
            delNode = n;
        }
    }

    if (delNode != NULL) {
        delNode->key = n->key;

        child = n->left != NULL ? n->left : n->right;
        //cout << "CHILD = " << child->key << endl;
        if (root->key == delKey) {
            root->left = root->right = NULL; delete root; root = NULL;
            root = child;
            root->parent = NULL;
        }
        else {
            if (parent->left == n) {
                //cout << "LEFT OMMITED" << endl;
                //parent->left->left = parent->left->right = NULL;
                //delete parent->left; parent->left = NULL;
                //child->parent = parent->left;
                parent->left = child;
                if (parent->left != NULL)
                parent->left->parent = parent;

            }
            else {
                //cout << "RIGHT OMMITED" << endl;
                //parent->right->left = parent->right->right = NULL;
                //delete parent->right; parent->right = NULL;
                // if (parent != NULL)
                //   child->parent = parent;
                // else
                //   child->parent = NULL;
                parent->right = child;
                if (parent->right != NULL)
                parent->right->parent = parent;

            }

            rebalance(parent);

        }
    }
}

template <class T>
void CTermTree<T>::printBalance() {
    printBalance(root);
    std::cout << std::endl;
}

template <class T>
void CTermTree<T>::printInOrder() {
    printInOrder(root);
    std::cout << std::endl;
}

template <class T>
void CTermTree<T>::renderInOrder() {
    renderInOrder(root, 1);
    std::cout << std::endl;
}

template <class T>
T CTermTree<T>::findMin() {
    CTerm<T> *minKey = findMin(root);
    return minKey->key;
}

template <class T>
bool CTermTree<T>::search(const T delKey) {
    if (root == NULL)
        return false;

    CTerm<T>
        *n        = root,
        *parent   = root,
        *findNode = NULL,
        *child   = root;

    while (child != NULL) {
        parent = n;
        n = child;
        child = delKey >= n->key ? n->right : n->left;
        if (delKey == n->key)
            return true;
    }
    return false;
}
<|endoftext|>


<commit_before>#include "CssWriter.h"

CssWriter::CssWriter(ostream* out) {
  this->out = out;
}

void CssWriter::writeStylesheet(Stylesheet* s) {
  vector<AtRule*>* atrules = s->getAtRules();
  vector<AtRule*>::iterator aIt;
  vector<Ruleset*>* rulesets = s->getRulesets();
  vector<Ruleset*>::iterator rIt;

  for (aIt = atrules->begin(); aIt < atrules->end(); aIt++) {
    writeAtRule(*aIt);
    out->write(";", 1);
  }
  for (rIt = rulesets->begin(); rIt < rulesets->end(); rIt++) {
    writeRuleset(*rIt);
  }
}

void CssWriter::writeAtRule(AtRule* atrule) {
  TokenList* rule = atrule->getRule();
  TokenListIterator* it = rule->iterator();

  out->write(atrule->getKeyword()->c_str(),
             atrule->getKeyword()->size());
  out->write(" ", 1);

  while (it->hasNext()) {
    Token* next = it->next();
    out->write(next->str.c_str(), next->str.size());
  }

}

void CssWriter::writeRuleset(Ruleset* ruleset) {
  TokenList* selector = ruleset->getSelector();
  TokenListIterator* it;

  vector<Declaration*>* declarations = ruleset->getDeclarations();
  vector<Declaration*>::iterator dIt;

  if (selector != NULL) {
    for (it = selector->iterator(); it->hasNext();) {
      Token* next = it->next();
      out->write(next->str.c_str(), next->str.size());
    }
  }
  out->write("{", 1);
  for (dIt = declarations->begin(); dIt < declarations->end(); dIt++) {
    writeDeclaration(*dIt);
    if (dIt + 1 < declarations->end())
      out->write(";", 1);
  }
  out->write("}", 1);
}

void CssWriter::writeDeclaration(Declaration* declaration) {
  TokenList* value = declaration->getValue();
  TokenListIterator* it = value->iterator();

  out->write(declaration->getProperty()->c_str(),
             declaration->getProperty()->size());
  out->write(":", 1);

  while (it->hasNext()) {
    Token* next = it->next();
    out->write(next->str.c_str(), next->str.size());
  }
}

<commit_msg>CssWriter now ignores empty Rulesets.<commit_after>#include "CssWriter.h"

CssWriter::CssWriter(ostream* out) {
  this->out = out;
}

void CssWriter::writeStylesheet(Stylesheet* s) {
  vector<AtRule*>* atrules = s->getAtRules();
  vector<AtRule*>::iterator aIt;
  vector<Ruleset*>* rulesets = s->getRulesets();
  vector<Ruleset*>::iterator rIt;

  for (aIt = atrules->begin(); aIt < atrules->end(); aIt++) {
    writeAtRule(*aIt);
    out->write(";", 1);
  }
  for (rIt = rulesets->begin(); rIt < rulesets->end(); rIt++) {
    writeRuleset(*rIt);
  }
}

void CssWriter::writeAtRule(AtRule* atrule) {
  TokenList* rule = atrule->getRule();
  TokenListIterator* it = rule->iterator();

  out->write(atrule->getKeyword()->c_str(),
             atrule->getKeyword()->size());
  out->write(" ", 1);

  while (it->hasNext()) {
    Token* next = it->next();
    out->write(next->str.c_str(), next->str.size());
  }

}

void CssWriter::writeRuleset(Ruleset* ruleset) {
  TokenList* selector = ruleset->getSelector();
  TokenListIterator* it;

  vector<Declaration*>* declarations = ruleset->getDeclarations();
  vector<Declaration*>::iterator dIt;

  if (declarations->size() == 0)
    return;

  if (selector != NULL) {
    for (it = selector->iterator(); it->hasNext();) {
      Token* next = it->next();
      out->write(next->str.c_str(), next->str.size());
    }
  }
  out->write("{", 1);
  for (dIt = declarations->begin(); dIt < declarations->end(); dIt++) {
    writeDeclaration(*dIt);
    if (dIt + 1 < declarations->end())
      out->write(";", 1);
  }
  out->write("}", 1);
}

void CssWriter::writeDeclaration(Declaration* declaration) {
  TokenList* value = declaration->getValue();
  TokenListIterator* it = value->iterator();

  out->write(declaration->getProperty()->c_str(),
             declaration->getProperty()->size());
  out->write(":", 1);

  while (it->hasNext()) {
    Token* next = it->next();
    out->write(next->str.c_str(), next->str.size());
  }
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015, 2016, Intel Corporation
 *
 * 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.
 *
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * 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
 * OWNER 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 LOG OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <string.h>
#include <stdio.h>
#include <iostream>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/mman.h>

#include "Exception.hpp"
#include "geopm_env.h"
#include "config.h"

#ifndef NAME_MAX
#define NAME_MAX 1024
#endif

extern "C"
{
    void geopm_error_message(int err, char *msg, size_t size)
    {
        switch (err) {
            case GEOPM_ERROR_RUNTIME:
                strncpy(msg, "<geopm> Runtime error", size);
                break;
            case GEOPM_ERROR_LOGIC:
                strncpy(msg, "<geopm> Logic error", size);
                break;
            case GEOPM_ERROR_INVALID:
                strncpy(msg, "<geopm> Invalid argument", size);
                break;
            case GEOPM_ERROR_POLICY_NULL:
                strncpy(msg, "<geopm> The geopm_policy_c pointer is NULL, use geopm_policy_create()", size);
                break;
            case GEOPM_ERROR_FILE_PARSE:
                strncpy(msg, "<geopm> Unable to parse input file", size);
                break;
            case GEOPM_ERROR_LEVEL_RANGE:
                strncpy(msg, "<geopm> Control hierarchy level is out of range", size);
                break;
            case GEOPM_ERROR_CTL_COMM:
                strncpy(msg, "<geopm> Communication error in control hierarchy", size);
                break;
            case GEOPM_ERROR_SAMPLE_INCOMPLETE:
                strncpy(msg, "<geopm> All children have not sent all samples", size);
                break;
            case GEOPM_ERROR_POLICY_UNKNOWN:
                strncpy(msg, "<geopm> No policy has been set", size);
                break;
            case GEOPM_ERROR_NOT_IMPLEMENTED:
                strncpy(msg, "<geopm> Feature not yet implemented", size);
                break;
            case GEOPM_ERROR_NOT_TESTED:
                strncpy(msg, "<geopm> Feature not yet tested", size);
                break;
            case GEOPM_ERROR_PLATFORM_UNSUPPORTED:
                strncpy(msg, "<geopm> Current platform not supported or unrecognized", size);
                break;
            case GEOPM_ERROR_MSR_OPEN:
                strncpy(msg, "<geopm> Could not open MSR device", size);
                break;
            case GEOPM_ERROR_MSR_READ:
                strncpy(msg, "<geopm> Could not read from MSR device", size);
                break;
            case GEOPM_ERROR_MSR_WRITE:
                strncpy(msg, "<geopm> Could not write to MSR device", size);
                break;
            case GEOPM_ERROR_OPENMP_UNSUPPORTED:
                strncpy(msg, "<geopm> Not compiled with support for OpenMP", size);
                break;
            case GEOPM_ERROR_PROF_NULL:
                strncpy(msg, "<geopm> The geopm_prof_c pointer is NULL, use geopm_prof_create()", size);
                break;
            case GEOPM_ERROR_DECIDER_UNSUPPORTED:
                strncpy(msg, "<geopm> Specified Decider not supported or unrecognized", size);
                break;
            case GEOPM_ERROR_FACTORY_NULL:
                strncpy(msg, "<geopm> The geopm_factory_c pointer is NULL, pass in a valid factory object", size);
                break;
            case GEOPM_ERROR_SHUTDOWN:
                strncpy(msg, "<geopm> Shutdown policy has been signaled", size);
                break;
            case GEOPM_ERROR_TOO_MANY_COLLISIONS:
                strncpy(msg, "<geopm> Too many collisions when inserting into hash table", size);
                break;
            case GEOPM_ERROR_AFFINITY:
                strncpy(msg, "<geopm> MPI ranks are not affitinized to distinct CPUs", size);
                break;
            case GEOPM_ERROR_ENVIRONMENT:
                strncpy(msg, "<geopm> Unset or invalid environement variable", size);
                break;
            default:
#ifndef _GNU_SOURCE
                int undef = strerror_r(err, msg, size);
                if (undef && undef != ERANGE) {
                    snprintf(msg, size, "<geopm> Unknown error: %i", err);
                }
#else
                strncpy(msg, strerror_r(err, msg, size), size);
#endif
                break;
        }
        if (size > 0) {
            msg[size-1] = '\0';
        }
    }

    static void geopm_destroy_shmem(void)
    {
        DIR *did = opendir("/dev/shm");
        if (did &&
            strlen(geopm_env_shmkey()) &&
            *(geopm_env_shmkey()) == '/' &&
            strchr(geopm_env_shmkey(), ' ') == NULL &&
            strchr(geopm_env_shmkey() + 1, '/') == NULL) {

            struct dirent *entry;
            char shm_key[NAME_MAX];
            shm_key[0] = '/';
            shm_key[NAME_MAX - 1] = '\0';
            while ((entry = readdir(did))) {
                if (strstr(entry->d_name, geopm_env_shmkey() + 1) == entry->d_name) {
                   strncpy(shm_key + 1, entry->d_name, NAME_MAX - 2);
                   shm_unlink(shm_key);
                }
            }
        }
    }
}

namespace geopm
{

    static std::string error_message(int err);

    int exception_handler(std::exception_ptr eptr)
    {
        int err = GEOPM_ERROR_RUNTIME;
        try {
            if (eptr) {
                std::rethrow_exception(eptr);
            }
        }
        catch (const std::exception &ex) {
            const geopm::Exception *ex_geopm = dynamic_cast<const geopm::Exception *>(&ex);
            const std::system_error *ex_sys = dynamic_cast<const std::system_error *>(&ex);
            const std::runtime_error *ex_rt = dynamic_cast<const std::runtime_error *>(&ex);

            if (ex_geopm) {
#ifdef GEOPM_DEBUG
                std::cerr << "Error: " << ex_geopm->what() << std::endl;
#endif
                err = ex_geopm->err_value();
            }
            else if (ex_sys) {
#ifdef GEOPM_DEBUG
                std::cerr << "Error: " << ex_sys->what() << std::endl;
#endif
                err = ex_sys->code().value();
            }
            else if (ex_rt) {
#ifdef GEOPM_DEBUG
                std::cerr << "Error: " << ex_rt->what() << std::endl;
#endif
                err = errno ? errno : GEOPM_ERROR_RUNTIME;
            }
            else {
#ifdef GEOPM_DEBUG
                std::cerr << "Error: " << ex.what() << std::endl;
#endif
                err = errno ? errno : GEOPM_ERROR_RUNTIME;
            }
        }

        geopm_destroy_shmem();

        return err;
    }

    Exception::Exception(const std::string &what, int err, const char *file, int line)
        : std::runtime_error(error_message(err) + (
                                 what.size() != 0 ? (": " + what) : "") + (
                                 file != NULL ? (": at geopm/" + std::string(file) + ":" + std::to_string(line)) : ""))
        , m_err(err ? err : GEOPM_ERROR_RUNTIME)
    {

    }

    Exception::Exception()
        : Exception("", GEOPM_ERROR_RUNTIME, NULL, 0)
    {

    }

    Exception::Exception(int err)
        : Exception("", err, NULL, 0)
    {

    }

    Exception::Exception(const std::string &what, int err)
        : Exception(what, err, NULL, 0)
    {

    }

    Exception::Exception(int err, const char *file, int line)
        : Exception("", err, file, line)
    {

    }

    Exception::~Exception()
    {

    }

    int Exception::err_value(void) const
    {
        return m_err;
    }

    SignalException::SignalException(int signum)
        : Exception("Signal " + std::to_string(signum) + " raised", errno)
    {

    }

    SignalException::~SignalException()
    {

    }

    static std::string error_message(int err)
    {
        char tmp_msg[NAME_MAX];
        err = err ? err : GEOPM_ERROR_RUNTIME;
        geopm_error_message(err, tmp_msg, sizeof(tmp_msg));
        return tmp_msg;
    }
}
<commit_msg>Make SignalException robust to errno of zero.<commit_after>/*
 * Copyright (c) 2015, 2016, Intel Corporation
 *
 * 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.
 *
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * 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
 * OWNER 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 LOG OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <string.h>
#include <stdio.h>
#include <iostream>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/mman.h>

#include "Exception.hpp"
#include "geopm_env.h"
#include "config.h"

#ifndef NAME_MAX
#define NAME_MAX 1024
#endif

extern "C"
{
    void geopm_error_message(int err, char *msg, size_t size)
    {
        switch (err) {
            case GEOPM_ERROR_RUNTIME:
                strncpy(msg, "<geopm> Runtime error", size);
                break;
            case GEOPM_ERROR_LOGIC:
                strncpy(msg, "<geopm> Logic error", size);
                break;
            case GEOPM_ERROR_INVALID:
                strncpy(msg, "<geopm> Invalid argument", size);
                break;
            case GEOPM_ERROR_POLICY_NULL:
                strncpy(msg, "<geopm> The geopm_policy_c pointer is NULL, use geopm_policy_create()", size);
                break;
            case GEOPM_ERROR_FILE_PARSE:
                strncpy(msg, "<geopm> Unable to parse input file", size);
                break;
            case GEOPM_ERROR_LEVEL_RANGE:
                strncpy(msg, "<geopm> Control hierarchy level is out of range", size);
                break;
            case GEOPM_ERROR_CTL_COMM:
                strncpy(msg, "<geopm> Communication error in control hierarchy", size);
                break;
            case GEOPM_ERROR_SAMPLE_INCOMPLETE:
                strncpy(msg, "<geopm> All children have not sent all samples", size);
                break;
            case GEOPM_ERROR_POLICY_UNKNOWN:
                strncpy(msg, "<geopm> No policy has been set", size);
                break;
            case GEOPM_ERROR_NOT_IMPLEMENTED:
                strncpy(msg, "<geopm> Feature not yet implemented", size);
                break;
            case GEOPM_ERROR_NOT_TESTED:
                strncpy(msg, "<geopm> Feature not yet tested", size);
                break;
            case GEOPM_ERROR_PLATFORM_UNSUPPORTED:
                strncpy(msg, "<geopm> Current platform not supported or unrecognized", size);
                break;
            case GEOPM_ERROR_MSR_OPEN:
                strncpy(msg, "<geopm> Could not open MSR device", size);
                break;
            case GEOPM_ERROR_MSR_READ:
                strncpy(msg, "<geopm> Could not read from MSR device", size);
                break;
            case GEOPM_ERROR_MSR_WRITE:
                strncpy(msg, "<geopm> Could not write to MSR device", size);
                break;
            case GEOPM_ERROR_OPENMP_UNSUPPORTED:
                strncpy(msg, "<geopm> Not compiled with support for OpenMP", size);
                break;
            case GEOPM_ERROR_PROF_NULL:
                strncpy(msg, "<geopm> The geopm_prof_c pointer is NULL, use geopm_prof_create()", size);
                break;
            case GEOPM_ERROR_DECIDER_UNSUPPORTED:
                strncpy(msg, "<geopm> Specified Decider not supported or unrecognized", size);
                break;
            case GEOPM_ERROR_FACTORY_NULL:
                strncpy(msg, "<geopm> The geopm_factory_c pointer is NULL, pass in a valid factory object", size);
                break;
            case GEOPM_ERROR_SHUTDOWN:
                strncpy(msg, "<geopm> Shutdown policy has been signaled", size);
                break;
            case GEOPM_ERROR_TOO_MANY_COLLISIONS:
                strncpy(msg, "<geopm> Too many collisions when inserting into hash table", size);
                break;
            case GEOPM_ERROR_AFFINITY:
                strncpy(msg, "<geopm> MPI ranks are not affitinized to distinct CPUs", size);
                break;
            case GEOPM_ERROR_ENVIRONMENT:
                strncpy(msg, "<geopm> Unset or invalid environement variable", size);
                break;
            default:
#ifndef _GNU_SOURCE
                int undef = strerror_r(err, msg, size);
                if (undef && undef != ERANGE) {
                    snprintf(msg, size, "<geopm> Unknown error: %i", err);
                }
#else
                strncpy(msg, strerror_r(err, msg, size), size);
#endif
                break;
        }
        if (size > 0) {
            msg[size-1] = '\0';
        }
    }

    static void geopm_destroy_shmem(void)
    {
        DIR *did = opendir("/dev/shm");
        if (did &&
            strlen(geopm_env_shmkey()) &&
            *(geopm_env_shmkey()) == '/' &&
            strchr(geopm_env_shmkey(), ' ') == NULL &&
            strchr(geopm_env_shmkey() + 1, '/') == NULL) {

            struct dirent *entry;
            char shm_key[NAME_MAX];
            shm_key[0] = '/';
            shm_key[NAME_MAX - 1] = '\0';
            while ((entry = readdir(did))) {
                if (strstr(entry->d_name, geopm_env_shmkey() + 1) == entry->d_name) {
                   strncpy(shm_key + 1, entry->d_name, NAME_MAX - 2);
                   shm_unlink(shm_key);
                }
            }
        }
    }
}

namespace geopm
{

    static std::string error_message(int err);

    int exception_handler(std::exception_ptr eptr)
    {
        int err = GEOPM_ERROR_RUNTIME;
        try {
            if (eptr) {
                std::rethrow_exception(eptr);
            }
        }
        catch (const std::exception &ex) {
            const geopm::Exception *ex_geopm = dynamic_cast<const geopm::Exception *>(&ex);
            const std::system_error *ex_sys = dynamic_cast<const std::system_error *>(&ex);
            const std::runtime_error *ex_rt = dynamic_cast<const std::runtime_error *>(&ex);

            if (ex_geopm) {
#ifdef GEOPM_DEBUG
                std::cerr << "Error: " << ex_geopm->what() << std::endl;
#endif
                err = ex_geopm->err_value();
            }
            else if (ex_sys) {
#ifdef GEOPM_DEBUG
                std::cerr << "Error: " << ex_sys->what() << std::endl;
#endif
                err = ex_sys->code().value();
            }
            else if (ex_rt) {
#ifdef GEOPM_DEBUG
                std::cerr << "Error: " << ex_rt->what() << std::endl;
#endif
                err = errno ? errno : GEOPM_ERROR_RUNTIME;
            }
            else {
#ifdef GEOPM_DEBUG
                std::cerr << "Error: " << ex.what() << std::endl;
#endif
                err = errno ? errno : GEOPM_ERROR_RUNTIME;
            }
        }

        geopm_destroy_shmem();

        return err;
    }

    Exception::Exception(const std::string &what, int err, const char *file, int line)
        : std::runtime_error(error_message(err) + (
                                 what.size() != 0 ? (": " + what) : "") + (
                                 file != NULL ? (": at geopm/" + std::string(file) + ":" + std::to_string(line)) : ""))
        , m_err(err ? err : GEOPM_ERROR_RUNTIME)
    {

    }

    Exception::Exception()
        : Exception("", GEOPM_ERROR_RUNTIME, NULL, 0)
    {

    }

    Exception::Exception(int err)
        : Exception("", err, NULL, 0)
    {

    }

    Exception::Exception(const std::string &what, int err)
        : Exception(what, err, NULL, 0)
    {

    }

    Exception::Exception(int err, const char *file, int line)
        : Exception("", err, file, line)
    {

    }

    Exception::~Exception()
    {

    }

    int Exception::err_value(void) const
    {
        return m_err;
    }

    SignalException::SignalException(int signum)
        : Exception("Signal " + std::to_string(signum) + " raised", errno ? errno : GEOPM_ERROR_RUNTIME)
    {

    }

    SignalException::~SignalException()
    {

    }

    static std::string error_message(int err)
    {
        char tmp_msg[NAME_MAX];
        err = err ? err : GEOPM_ERROR_RUNTIME;
        geopm_error_message(err, tmp_msg, sizeof(tmp_msg));
        return tmp_msg;
    }
}
<|endoftext|>