<commit_before>/*
 * Copyright (c) 2012,2017-2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders 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 OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __BASE_COMPILER_HH__
#define __BASE_COMPILER_HH__

#include <memory>

#include "config/have_deprecated_namespace.hh"

// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

/*
 * Attributes that become standard in later versions of c++.
 */

// When the return value of a function should not be discarded, mark it with
// GEM5_NO_DISCARD.
#if __has_cpp_attribute(nodiscard) // Standard in c++17, with message in c++20.
#  define GEM5_NO_DISCARD [[nodiscard]]
#else
// Not supported, but it's optional so we can just omit it.
#  define GEM5_NO_DISCARD
#endif

// When a variable may purposefully not be used, for instance if it's only used
// in debug statements which might be disabled, mark it with GEM5_VAR_USED.
#if __has_cpp_attribute(maybe_unused) // Standard in c++17.
#  define GEM5_VAR_USED [[maybe_unused]]
#elif defined(__GNUC__)
// gcc and clang support a custom attribute which is essentially the same
// thing.
#  define GEM5_VAR_USED [[gnu::unused]]
#else
#  error "Don't know what to do for your compiler."
#endif

/*
 * Compiler specific features.
 */

#if defined(__GNUC__) // clang or gcc.
// Mark a structure as packed, so that no padding is added to its layout. This
// padding might be added to, for instance, ensure certain fields have certain
// alignment.
#  define GEM5_PACKED [[gnu::packed]]

// Prevent a function from being inlined.
#  define GEM5_NO_INLINE [[gnu::noinline]]

// Set the visibility of a symbol.
#  define GEM5_PUBLIC [[gnu:visibility("default")]]
#  define GEM5_LOCAL [[gnu::visibility("hidden")]]
#  define GEM5_WEAK [[gnu::weak]]

// Force an alignment for a variable.
#  define GEM5_ALIGNED(alignment) [[gnu::aligned(alignment)]]

// Marker for what should be an unreachable point in the code.
#  define GEM5_UNREACHABLE __builtin_unreachable()

// To mark a branch condition as likely taken, wrap it's condition with
// GEM5_LIKELY. To mark it as likely not taken, wrap it's condition with
// GEM5_UNLIKELY. These can be replaced with the standard attributes [[likely]]
// and [[unlikely]] in c++20, although the syntax is different enough that
// we can't do that with direct substitution.
#  define GEM5_LIKELY(cond) __builtin_expect(!!(cond), 1)
#  define GEM5_UNLIKELY(cond) __builtin_expect(!!(cond), 0)

// Mark a c++ declaration as deprecated, with a message explaining what to do
// to update to a non-deprecated alternative.
#  define GEM5_DEPRECATED(message) [[gnu::deprecated(message)]]
// Mark a C++ emum value as deprecated, with a message explaining what to do
// to update to a non-deprecated alternative. This wraps GEM5_DEPRECATED but
// is guarded by a preprocessor if directive to ensure it is not included
// when compiled in GCC < 6, as deprecation of enum values was introduced in
// GCC 6. All supported clang compilers allow enum value deprecation.
#  if defined(__clang__) || __GNUC__ >= 6
#    define GEM5_DEPRECATED_ENUM_VAL(message) GEM5_DEPRECATED(message)
#  else
#    define GEM5_DEPRECATED_ENUM_VAL(message)
#  endif
// Mark an expression-like macro as deprecated by wrapping it in some code
// which declares and uses a deprecated variable with the same name as the
// macro. The wrapping macro evaluates to the same thing as the original macro.
// The definition must be an c++ expression and not a statement because of how
// the original macro is wrapped.
#  define GEM5_DEPRECATED_MACRO(name, definition, message) \
     ([](){GEM5_DEPRECATED(message) int name{}; return name;}(), (definition))
// This version is for macros which are statement-like, which frequently use
// "do {} while (0)" to make their syntax look more like normal c++ statements.
#  define GEM5_DEPRECATED_MACRO_STMT(name, definition, message) \
     do {{definition;} GEM5_DEPRECATED_MACRO(name, {}, message);} while (0)

// To mark a class as deprecated in favor of a new name, add a respective
// instance of this macro to the file that used to declare the old name.
// This macro should be used *after* the new class has been defined.
#  define GEM5_DEPRECATED_CLASS(old_class, new_class) \
    using old_class \
        GEM5_DEPRECATED("Please use the new class name: '" #new_class "'") = \
        new_class

// These macros should be used when namespaces are deprecated in favor of
// a new name. They should be used wherever the namespace is declared.
// Namespace deprecation is broken for GNU < 10 [1], so there is no
// deprecation warning in that case. Clang only supports it from C++17 on.
// [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79817
#  if HAVE_DEPRECATED_NAMESPACE
#    define GEM5_DEPRECATED_NAMESPACE(old_namespace, new_namespace) \
       namespace new_namespace {} \
       namespace GEM5_DEPRECATED("Please use the new namespace: '" \
         #new_namespace "'") old_namespace { \
         using namespace new_namespace; \
       }
#  else
#    define GEM5_DEPRECATED_NAMESPACE(old_namespace, new_namespace) \
       namespace new_namespace {} \
       namespace old_namespace = new_namespace
#  endif

// Evaluate an expanded parameter pack in order. Multiple arguments can be
// passed in which be evaluated in order relative to each other as a group.
// The argument(s) must include a parameter pack to expand. This works because
// the elements of a brace inclosed initializer list are evaluated in order,
// as are the arguments to the comma operator, which evaluates to the last
// value. This is compiler specific because it uses variadic macros.
#define GEM5_FOR_EACH_IN_PACK(...) \
do { GEM5_VAR_USED int i[] = { 0, ((void)(__VA_ARGS__), 0)... }; } while (0)

#else
#  error "Don't know what to do for your compiler."
#endif

// When a member variable may be unused, mark it with GEM5_CLASS_VAR_USED. This
// needs to be limitted to clang only since clang warns on these unused
// variables, and g++ will actually warn if you use this attribute since it
// won't do anything there.
#if defined(__clang__) // clang only.
#  define GEM5_CLASS_VAR_USED GEM5_VAR_USED
#else
#  define GEM5_CLASS_VAR_USED
#endif

// Aliases for macros using the deprecated M5 prefix.
#define M5_VAR_USED GEM5_VAR_USED
#define M5_NODISCARD GEM5_NO_DISCARD
#define M5_FALLTHROUGH GEM5_FALLTHROUGH
#define M5_ATTR_PACKED GEM5_PACKED
#define M5_NO_INLINE GEM5_NO_INLINE
#define M5_PUBLIC GEM5_PUBLIC
#define M5_LOCAL GEM5_LOCAL
#define M5_WEAK GEM5_WEAK
#define M5_ALIGNED(x) GEM5_ALIGNED(x)
#define M5_UNREACHABLE GEM5_UNREACHABLE
#define M5_LIKELY(x) GEM5_LIKELY(x)
#define M5_UNLIKELY(x) GEM5_UNLIKELY(x)
#define M5_FOR_EACH_IN_PACK(...) GEM5_FOR_EACH_IN_PACK(__VA_ARGS__)
#define M5_CLASS_VAR_USED GEM5_CLASS_VAR_USED

#define GEM5_FALLTHROUGH GEM5_DEPRECATED_MACRO_STMT(GEM5_FALLTHROUGH,,\
        "Please use the [[fallthrough]] attribute directly."); [[fallthrough]]

#endif // __BASE_COMPILER_HH__
<commit_msg>base: Deprecate the GEM5_DEPRECATED macro.<commit_after>/*
 * Copyright (c) 2012,2017-2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders 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 OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __BASE_COMPILER_HH__
#define __BASE_COMPILER_HH__

#include <memory>

#include "config/have_deprecated_namespace.hh"

// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

/*
 * Attributes that become standard in later versions of c++.
 */

// When the return value of a function should not be discarded, mark it with
// GEM5_NO_DISCARD.
#if __has_cpp_attribute(nodiscard) // Standard in c++17, with message in c++20.
#  define GEM5_NO_DISCARD [[nodiscard]]
#else
// Not supported, but it's optional so we can just omit it.
#  define GEM5_NO_DISCARD
#endif

// When a variable may purposefully not be used, for instance if it's only used
// in debug statements which might be disabled, mark it with GEM5_VAR_USED.
#if __has_cpp_attribute(maybe_unused) // Standard in c++17.
#  define GEM5_VAR_USED [[maybe_unused]]
#elif defined(__GNUC__)
// gcc and clang support a custom attribute which is essentially the same
// thing.
#  define GEM5_VAR_USED [[gnu::unused]]
#else
#  error "Don't know what to do for your compiler."
#endif

/*
 * Compiler specific features.
 */

#if defined(__GNUC__) // clang or gcc.
// Mark a structure as packed, so that no padding is added to its layout. This
// padding might be added to, for instance, ensure certain fields have certain
// alignment.
#  define GEM5_PACKED [[gnu::packed]]

// Prevent a function from being inlined.
#  define GEM5_NO_INLINE [[gnu::noinline]]

// Set the visibility of a symbol.
#  define GEM5_PUBLIC [[gnu:visibility("default")]]
#  define GEM5_LOCAL [[gnu::visibility("hidden")]]
#  define GEM5_WEAK [[gnu::weak]]

// Force an alignment for a variable.
#  define GEM5_ALIGNED(alignment) [[gnu::aligned(alignment)]]

// Marker for what should be an unreachable point in the code.
#  define GEM5_UNREACHABLE __builtin_unreachable()

// To mark a branch condition as likely taken, wrap it's condition with
// GEM5_LIKELY. To mark it as likely not taken, wrap it's condition with
// GEM5_UNLIKELY. These can be replaced with the standard attributes [[likely]]
// and [[unlikely]] in c++20, although the syntax is different enough that
// we can't do that with direct substitution.
#  define GEM5_LIKELY(cond) __builtin_expect(!!(cond), 1)
#  define GEM5_UNLIKELY(cond) __builtin_expect(!!(cond), 0)

// Mark a C++ emum value as deprecated, with a message explaining what to do
// to update to a non-deprecated alternative. This wraps GEM5_DEPRECATED but
// is guarded by a preprocessor if directive to ensure it is not included
// when compiled in GCC < 6, as deprecation of enum values was introduced in
// GCC 6. All supported clang compilers allow enum value deprecation.
#  if defined(__clang__) || __GNUC__ >= 6
#    define GEM5_DEPRECATED_ENUM_VAL(message) [[deprecated(message)]]
#  else
#    define GEM5_DEPRECATED_ENUM_VAL(message)
#  endif
// Mark an expression-like macro as deprecated by wrapping it in some code
// which declares and uses a deprecated variable with the same name as the
// macro. The wrapping macro evaluates to the same thing as the original macro.
// The definition must be an c++ expression and not a statement because of how
// the original macro is wrapped.
#  define GEM5_DEPRECATED_MACRO(name, definition, message) \
     ([](){[[deprecated(message)]] int name{}; return name;}(), (definition))
// This version is for macros which are statement-like, which frequently use
// "do {} while (0)" to make their syntax look more like normal c++ statements.
#  define GEM5_DEPRECATED_MACRO_STMT(name, definition, message) \
     do {{definition;} GEM5_DEPRECATED_MACRO(name, {}, message);} while (0)

// To mark a class as deprecated in favor of a new name, add a respective
// instance of this macro to the file that used to declare the old name.
// This macro should be used *after* the new class has been defined.
#  define GEM5_DEPRECATED_CLASS(old_class, new_class) \
    using old_class \
        [[deprecated("Please use the new class name: '" #new_class "'")]] = \
        new_class

// These macros should be used when namespaces are deprecated in favor of
// a new name. They should be used wherever the namespace is declared.
// Namespace deprecation is broken for GNU < 10 [1], so there is no
// deprecation warning in that case. Clang only supports it from C++17 on.
// [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79817
#  if HAVE_DEPRECATED_NAMESPACE
#    define GEM5_DEPRECATED_NAMESPACE(old_namespace, new_namespace) \
       namespace new_namespace {} \
       namespace [[deprecated("Please use the new namespace: '" \
         #new_namespace "'")]] old_namespace { \
         using namespace new_namespace; \
       }
#  else
#    define GEM5_DEPRECATED_NAMESPACE(old_namespace, new_namespace) \
       namespace new_namespace {} \
       namespace old_namespace = new_namespace
#  endif

// Evaluate an expanded parameter pack in order. Multiple arguments can be
// passed in which be evaluated in order relative to each other as a group.
// The argument(s) must include a parameter pack to expand. This works because
// the elements of a brace inclosed initializer list are evaluated in order,
// as are the arguments to the comma operator, which evaluates to the last
// value. This is compiler specific because it uses variadic macros.
#define GEM5_FOR_EACH_IN_PACK(...) \
do { GEM5_VAR_USED int i[] = { 0, ((void)(__VA_ARGS__), 0)... }; } while (0)

#else
#  error "Don't know what to do for your compiler."
#endif

// When a member variable may be unused, mark it with GEM5_CLASS_VAR_USED. This
// needs to be limitted to clang only since clang warns on these unused
// variables, and g++ will actually warn if you use this attribute since it
// won't do anything there.
#if defined(__clang__) // clang only.
#  define GEM5_CLASS_VAR_USED GEM5_VAR_USED
#else
#  define GEM5_CLASS_VAR_USED
#endif

// Aliases for macros using the deprecated M5 prefix.
#define M5_VAR_USED GEM5_VAR_USED
#define M5_NODISCARD GEM5_NO_DISCARD
#define M5_FALLTHROUGH GEM5_FALLTHROUGH
#define M5_ATTR_PACKED GEM5_PACKED
#define M5_NO_INLINE GEM5_NO_INLINE
#define M5_PUBLIC GEM5_PUBLIC
#define M5_LOCAL GEM5_LOCAL
#define M5_WEAK GEM5_WEAK
#define M5_ALIGNED(x) GEM5_ALIGNED(x)
#define M5_UNREACHABLE GEM5_UNREACHABLE
#define M5_LIKELY(x) GEM5_LIKELY(x)
#define M5_UNLIKELY(x) GEM5_UNLIKELY(x)
#define M5_FOR_EACH_IN_PACK(...) GEM5_FOR_EACH_IN_PACK(__VA_ARGS__)
#define M5_CLASS_VAR_USED GEM5_CLASS_VAR_USED

#define GEM5_FALLTHROUGH GEM5_DEPRECATED_MACRO_STMT(GEM5_FALLTHROUGH,,\
        "Please use the [[fallthrough]] attribute directly."); [[fallthrough]]
#define GEM5_DEPRECATED(message) \
     [[deprecated(message " The GEM5_DEPRECATED macro is also deprecated, "\
             "please use the [[deprecated()]] attribute directly.")]]

#endif // __BASE_COMPILER_HH__
<|endoftext|>


<commit_before>//===-- sanitizer_allocator_testlib.cc ------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Malloc replacement library based on CombinedAllocator.
// The primary purpose of this file is an end-to-end integration test
// for CombinedAllocator.
//===----------------------------------------------------------------------===//
/* Usage:
clang++ -fno-exceptions  -g -fPIC -I. -I../include -Isanitizer \
 sanitizer_common/tests/sanitizer_allocator_testlib.cc \
 sanitizer_common/sanitizer_*.cc -shared -lpthread -o testmalloc.so
LD_PRELOAD=`pwd`/testmalloc.so /your/app
*/
#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_common.h"
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

#ifndef SANITIZER_MALLOC_HOOK
# define SANITIZER_MALLOC_HOOK(p, s)
#endif

#ifndef SANITIZER_FREE_HOOK
# define SANITIZER_FREE_HOOK(p)
#endif

namespace {
static const uptr kAllocatorSpace = 0x600000000000ULL;
static const uptr kAllocatorSize  =  0x10000000000ULL;  // 1T.

typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0,
  CompactSizeClassMap> PrimaryAllocator;
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
typedef LargeMmapAllocator<> SecondaryAllocator;
typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
          SecondaryAllocator> Allocator;

static Allocator allocator;
static THREADLOCAL AllocatorCache cache;
static THREADLOCAL bool global_inited;
static THREADLOCAL bool thread_inited;
static pthread_key_t pkey;

static void thread_dtor(void *v) {
  if ((long)v != 3) {
    pthread_setspecific(pkey, (void*)((long)v + 1));
    return;
  }
  allocator.SwallowCache(&cache);
}

static void NOINLINE thread_init() {
  if (!global_inited) {
    global_inited = true;
    allocator.Init();
    pthread_key_create(&pkey, thread_dtor);
  }
  thread_inited = true;
  pthread_setspecific(pkey, (void*)1);
  cache.Init();
}
}  // namespace

extern "C" {

void *malloc(size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  void *p = allocator.Allocate(&cache, size, 8);
  SANITIZER_MALLOC_HOOK(p, size);
  return p;
}

void free(void *p) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  SANITIZER_FREE_HOOK(p);
  allocator.Deallocate(&cache, p);
}

void *calloc(size_t nmemb, size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  size *= nmemb;
  void *p = allocator.Allocate(&cache, size, 8, false);
  memset(p, 0, size);
  SANITIZER_MALLOC_HOOK(p, size);
  return p;
}

void *realloc(void *p, size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  if (p) {
    SANITIZER_FREE_HOOK(p);
  }
  p = allocator.Reallocate(&cache, p, size, 8);
  if (p) {
    SANITIZER_MALLOC_HOOK(p, size);
  }
  return p;
}

void *memalign(size_t alignment, size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  void *p = allocator.Allocate(&cache, size, alignment);
  SANITIZER_MALLOC_HOOK(p, size);
  return p;
}

int posix_memalign(void **memptr, size_t alignment, size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  *memptr = allocator.Allocate(&cache, size, alignment);
  SANITIZER_MALLOC_HOOK(*memptr, size);
  return 0;
}

void *valloc(size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  if (size == 0)
    size = GetPageSizeCached();
  void *p = allocator.Allocate(&cache, size, GetPageSizeCached());
  SANITIZER_MALLOC_HOOK(p, size);
  return p;
}

void cfree(void *p) ALIAS("free");
void *pvalloc(size_t size) ALIAS("valloc");
void *__libc_memalign(size_t alignment, size_t size) ALIAS("memalign");

void malloc_usable_size() {
}

void mallinfo() {
}

void mallopt() {
}

}  // extern "C"
<commit_msg>asan: fix lint warnings<commit_after>//===-- sanitizer_allocator_testlib.cc ------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Malloc replacement library based on CombinedAllocator.
// The primary purpose of this file is an end-to-end integration test
// for CombinedAllocator.
//===----------------------------------------------------------------------===//
/* Usage:
clang++ -fno-exceptions  -g -fPIC -I. -I../include -Isanitizer \
 sanitizer_common/tests/sanitizer_allocator_testlib.cc \
 sanitizer_common/sanitizer_*.cc -shared -lpthread -o testmalloc.so
LD_PRELOAD=`pwd`/testmalloc.so /your/app
*/
#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_common.h"
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

#ifndef SANITIZER_MALLOC_HOOK
# define SANITIZER_MALLOC_HOOK(p, s)
#endif

#ifndef SANITIZER_FREE_HOOK
# define SANITIZER_FREE_HOOK(p)
#endif

namespace {
static const uptr kAllocatorSpace = 0x600000000000ULL;
static const uptr kAllocatorSize  =  0x10000000000ULL;  // 1T.

typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0,
  CompactSizeClassMap> PrimaryAllocator;
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
typedef LargeMmapAllocator<> SecondaryAllocator;
typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
          SecondaryAllocator> Allocator;

static Allocator allocator;
static THREADLOCAL AllocatorCache cache;
static THREADLOCAL bool global_inited;
static THREADLOCAL bool thread_inited;
static pthread_key_t pkey;

static void thread_dtor(void *v) {
  if ((uptr)v != 3) {
    pthread_setspecific(pkey, (void*)((uptr)v + 1));
    return;
  }
  allocator.SwallowCache(&cache);
}

static void NOINLINE thread_init() {
  if (!global_inited) {
    global_inited = true;
    allocator.Init();
    pthread_key_create(&pkey, thread_dtor);
  }
  thread_inited = true;
  pthread_setspecific(pkey, (void*)1);
  cache.Init();
}
}  // namespace

extern "C" {
void *malloc(size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  void *p = allocator.Allocate(&cache, size, 8);
  SANITIZER_MALLOC_HOOK(p, size);
  return p;
}

void free(void *p) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  SANITIZER_FREE_HOOK(p);
  allocator.Deallocate(&cache, p);
}

void *calloc(size_t nmemb, size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  size *= nmemb;
  void *p = allocator.Allocate(&cache, size, 8, false);
  memset(p, 0, size);
  SANITIZER_MALLOC_HOOK(p, size);
  return p;
}

void *realloc(void *p, size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  if (p) {
    SANITIZER_FREE_HOOK(p);
  }
  p = allocator.Reallocate(&cache, p, size, 8);
  if (p) {
    SANITIZER_MALLOC_HOOK(p, size);
  }
  return p;
}

void *memalign(size_t alignment, size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  void *p = allocator.Allocate(&cache, size, alignment);
  SANITIZER_MALLOC_HOOK(p, size);
  return p;
}

int posix_memalign(void **memptr, size_t alignment, size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  *memptr = allocator.Allocate(&cache, size, alignment);
  SANITIZER_MALLOC_HOOK(*memptr, size);
  return 0;
}

void *valloc(size_t size) {
  if (UNLIKELY(!thread_inited))
    thread_init();
  if (size == 0)
    size = GetPageSizeCached();
  void *p = allocator.Allocate(&cache, size, GetPageSizeCached());
  SANITIZER_MALLOC_HOOK(p, size);
  return p;
}

void cfree(void *p) ALIAS("free");
void *pvalloc(size_t size) ALIAS("valloc");
void *__libc_memalign(size_t alignment, size_t size) ALIAS("memalign");

void malloc_usable_size() {
}

void mallinfo() {
}

void mallopt() {
}
}  // extern "C"
<|endoftext|>


<commit_before>// Copyright (c) 2011 Sirikata Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.

#ifndef _SIRIKATA_CORE_RECORD_SST_STREAM_HPP_
#define _SIRIKATA_CORE_RECORD_SST_STREAM_HPP_

#include <sirikata/core/util/Platform.hpp>
#include <sirikata/core/network/Frame.hpp>
#include <sirikata/core/util/Liveness.hpp>
#include <sirikata/core/util/Time.hpp>

namespace Sirikata {

/** RecordSSTStream wraps a regular SST stream, turning it into a record-based
 *  stream, i.e. performing buffering and triggering callbacks for each record
 *  rather than for each set of received bytes. This is useful for reliable,
 *  message-oriented protocols. The user submits individual records to be sent
 *  and it uses simple framing to identify the records at the receiver.
 */
template<typename StreamPtrType>
class RecordSSTStream : public Liveness {
public:
    typedef std::tr1::function<void(MemoryReference)> RecordCallback;

    RecordSSTStream() {}
    ~RecordSSTStream() {
        destroy();
    }

    void initialize(StreamPtrType stream, RecordCallback cb) {
        mStream = stream;
        mCB = cb;

        using std::tr1::placeholders::_1;
        using std::tr1::placeholders::_2;

        assert(mStream);
        mStream->registerReadCallback(
            std::tr1::bind(
                &RecordSSTStream::handleRead, this,
                _1, _2
            )
        );
    }

    void write(const MemoryReference& data) {
        outstanding.push(Network::Frame::write(data.begin(), data.size()));
        writeSomeData(livenessToken());
    }

    void destroy() {
        letDie();

        if (!mStream) return;
        mStream->registerReadCallback(0);
    }
private:
    void handleRead(uint8* data, int size) {
        partial_frame.append((const char*)data, size);
        while(true) {
            String parsed = Network::Frame::parse(partial_frame);
            if (parsed.empty()) return;
            mCB( MemoryReference(parsed) );
        }
    }

    void writeSomeData(Liveness::Token alive) {
        if (!alive) return;

        static Duration retry_rate = Duration::milliseconds((int64)1);

        writing = true;

        if (!mStream) {
            // We're still waiting on the stream. Initialization should trigger
            // writing if it gets a stream and there's data waiting.
            writing = false;
            return;
        }

        // Otherwise, keep sending until we run out or
        while(!outstanding.empty()) {
            std::string& framed_msg = outstanding.front();
            int bytes_written = mStream->write((const uint8*)framed_msg.data(), framed_msg.size());
            if (bytes_written < 0) {
                // FIXME
                break;
            }
            else if (bytes_written < (int)framed_msg.size()) {
                framed_msg = framed_msg.substr(bytes_written);
                break;
            }
            else {
                outstanding.pop();
            }
        }

        if (outstanding.empty())
            writing = false;
        else
            mStream->getContext()->mainStrand->post(
                retry_rate,
                std::tr1::bind(&RecordSSTStream::writeSomeData, this, alive),
                "RecordSSTStream::writeSomeData"
            );
    }

    StreamPtrType mStream;
    RecordCallback mCB;

    // Outstanding data to be sent. FIXME efficiency
    std::queue<std::string> outstanding;
    // If writing is currently in progress
    bool writing;

    // Backlog of data, i.e. incomplete frame
    String partial_frame;
}; // class RecordSSTStream

} // namespace Sirikata

#endif //_SIRIKATA_CORE_RECORD_SST_STREAM_HPP_
<commit_msg>RecordSSTStream should be non-copyable because of how it passes its own this pointer into a callback for underlying sststream.<commit_after>// Copyright (c) 2011 Sirikata Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.

#ifndef _SIRIKATA_CORE_RECORD_SST_STREAM_HPP_
#define _SIRIKATA_CORE_RECORD_SST_STREAM_HPP_

#include <sirikata/core/util/Platform.hpp>
#include <sirikata/core/network/Frame.hpp>
#include <sirikata/core/util/Liveness.hpp>
#include <sirikata/core/util/Time.hpp>

namespace Sirikata {

/** RecordSSTStream wraps a regular SST stream, turning it into a record-based
 *  stream, i.e. performing buffering and triggering callbacks for each record
 *  rather than for each set of received bytes. This is useful for reliable,
 *  message-oriented protocols. The user submits individual records to be sent
 *  and it uses simple framing to identify the records at the receiver.
 */
template<typename StreamPtrType>
class RecordSSTStream : public Liveness, public Noncopyable {
public:
    typedef std::tr1::function<void(MemoryReference)> RecordCallback;

    RecordSSTStream() {}
    ~RecordSSTStream() {
        destroy();
    }

    void initialize(StreamPtrType stream, RecordCallback cb) {
        mStream = stream;
        mCB = cb;

        using std::tr1::placeholders::_1;
        using std::tr1::placeholders::_2;

        assert(mStream);
        mStream->registerReadCallback(
            std::tr1::bind(
                &RecordSSTStream::handleRead, this,
                _1, _2
            )
        );
    }

    void write(const MemoryReference& data) {
        outstanding.push(Network::Frame::write(data.begin(), data.size()));
        writeSomeData(livenessToken());
    }

    void destroy() {
        letDie();

        if (!mStream) return;
        mStream->registerReadCallback(0);
    }
private:

    RecordSSTStream(const RecordSSTStream&);

    void handleRead(uint8* data, int size) {
        partial_frame.append((const char*)data, size);
        while(true) {
            String parsed = Network::Frame::parse(partial_frame);
            if (parsed.empty()) return;
            mCB( MemoryReference(parsed) );
        }
    }

    void writeSomeData(Liveness::Token alive) {
        if (!alive) return;

        static Duration retry_rate = Duration::milliseconds((int64)1);

        writing = true;

        if (!mStream) {
            // We're still waiting on the stream. Initialization should trigger
            // writing if it gets a stream and there's data waiting.
            writing = false;
            return;
        }

        // Otherwise, keep sending until we run out or
        while(!outstanding.empty()) {
            std::string& framed_msg = outstanding.front();
            int bytes_written = mStream->write((const uint8*)framed_msg.data(), framed_msg.size());
            if (bytes_written < 0) {
                // FIXME
                break;
            }
            else if (bytes_written < (int)framed_msg.size()) {
                framed_msg = framed_msg.substr(bytes_written);
                break;
            }
            else {
                outstanding.pop();
            }
        }

        if (outstanding.empty())
            writing = false;
        else
            mStream->getContext()->mainStrand->post(
                retry_rate,
                std::tr1::bind(&RecordSSTStream::writeSomeData, this, alive),
                "RecordSSTStream::writeSomeData"
            );
    }

    StreamPtrType mStream;
    RecordCallback mCB;

    // Outstanding data to be sent. FIXME efficiency
    std::queue<std::string> outstanding;
    // If writing is currently in progress
    bool writing;

    // Backlog of data, i.e. incomplete frame
    String partial_frame;
}; // class RecordSSTStream

} // namespace Sirikata

#endif //_SIRIKATA_CORE_RECORD_SST_STREAM_HPP_
<|endoftext|>


<commit_before>/*  Sirikata
 *  SerializationCheck.hpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata 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 OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _SIRIKATA_SERIALIZATION_CHECK_HPP_
#define _SIRIKATA_SERIALIZATION_CHECK_HPP_

#include <sirikata/core/util/Platform.hpp>

#include <boost/thread/thread.hpp>

namespace Sirikata {

/** Verifies that code blocks you expect to be handled in a serialized
 *  fashion (i.e. non-concurrently) are actually handled that way.
 *  Mark these sections with calls to serializedEnter() and
 *  serializedExit() at the beinning and end respectively and those
 *  calls will assert in debug mode if this condition is violated.
 *  This can be used recursively within a thread -- multiple calls
 *  to serializedEnter() from the same thread will not result in
 *  an error.
 */
class SerializationCheck {
public:
    // Used to mark an entire scope as
    class Scoped {
    public:
        Scoped(SerializationCheck* p)
         : parent(p)
        {
            parent->serializedEnter();
        }

        ~Scoped() {
            parent->serializedExit();
        }
    private:
        Scoped();
        Scoped(Scoped& rhs);
        Scoped& operator=(Scoped& rhs);

        SerializationCheck* parent;
    };

    SerializationCheck()
     : mAccessors(0),
       mThreadID()
    {
    }

    inline void serializedEnter() const {
        int32 val = ++mAccessors;

        assert(val >= 1);

        if (val == 1) {
            // We're the first ones in here, we need to setup the thread id
            mThreadID = boost::this_thread::get_id();
        }
        else {
            // We got in here later on.  This is only valid if we were in the
            // same thread, so the thread had better already be marked and
            // match ours
            assert(mThreadID == boost::this_thread::get_id());
        }
    }

    inline void serializedExit() const {
        if (mAccessors == (int32)1) {
            // We should be the only one left accessing this and a
            // serializedEnter should *not* be getting called, so we
            // can erase the thread ID now.
            mThreadID = boost::thread::id();
        }

        int32 val = --mAccessors;
        assert(val >= 0);
    }
private:
    // Implementation Note: Technically this isn't all thread safe.  However,
    // the core component which tracks the number of accessors and their order
    // off access is thread safe. Any thread-unsafe accesses should only result
    // in a bad comparison, which should result in an assertion anyway since the
    // whole point of this class is to verify that multiple threads are not trying
    // to access shared data (including this object) at the same time.
    mutable AtomicValue<int32> mAccessors;
    mutable boost::thread::id mThreadID;
};

} // namespace Sirikata

#endif //_SIRIKATA_SERIALIZATION_CHECK_HPP_
<commit_msg>Only perform SerializationCheck in debug mode.<commit_after>/*  Sirikata
 *  SerializationCheck.hpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata 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 OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _SIRIKATA_SERIALIZATION_CHECK_HPP_
#define _SIRIKATA_SERIALIZATION_CHECK_HPP_

#include <sirikata/core/util/Platform.hpp>

#include <boost/thread/thread.hpp>

namespace Sirikata {

/** Verifies that code blocks you expect to be handled in a serialized
 *  fashion (i.e. non-concurrently) are actually handled that way.
 *  Mark these sections with calls to serializedEnter() and
 *  serializedExit() at the beinning and end respectively and those
 *  calls will assert in debug mode if this condition is violated.
 *  This can be used recursively within a thread -- multiple calls
 *  to serializedEnter() from the same thread will not result in
 *  an error.
 */
class SerializationCheck {
public:
    // Used to mark an entire scope as
    class Scoped {
    public:
        Scoped(SerializationCheck* p)
         : parent(p)
        {
            parent->serializedEnter();
        }

        ~Scoped() {
            parent->serializedExit();
        }
    private:
        Scoped();
        Scoped(Scoped& rhs);
        Scoped& operator=(Scoped& rhs);

        SerializationCheck* parent;
    };

    SerializationCheck()
#if SIRIKATA_DEBUG
     : mAccessors(0),
       mThreadID()
#endif //SIRIKATA_DEBUG
    {
    }

    inline void serializedEnter() const {
#if SIRIKATA_DEBUG
        int32 val = ++mAccessors;

        assert(val >= 1);

        if (val == 1) {
            // We're the first ones in here, we need to setup the thread id
            mThreadID = boost::this_thread::get_id();
        }
        else {
            // We got in here later on.  This is only valid if we were in the
            // same thread, so the thread had better already be marked and
            // match ours
            assert(mThreadID == boost::this_thread::get_id());
        }
#endif //SIRIKATA_DEBUG
    }

    inline void serializedExit() const {
#if SIRIKATA_DEBUG
        if (mAccessors == (int32)1) {
            // We should be the only one left accessing this and a
            // serializedEnter should *not* be getting called, so we
            // can erase the thread ID now.
            mThreadID = boost::thread::id();
        }

        int32 val = --mAccessors;
        assert(val >= 0);
#endif //SIRIKATA_DEBUG
    }
private:
#if SIRIKATA_DEBUG
    // Implementation Note: Technically this isn't all thread safe.  However,
    // the core component which tracks the number of accessors and their order
    // off access is thread safe. Any thread-unsafe accesses should only result
    // in a bad comparison, which should result in an assertion anyway since the
    // whole point of this class is to verify that multiple threads are not trying
    // to access shared data (including this object) at the same time.
    mutable AtomicValue<int32> mAccessors;
    mutable boost::thread::id mThreadID;
#endif //SIRIKATA_DEBUG
};

} // namespace Sirikata

#endif //_SIRIKATA_SERIALIZATION_CHECK_HPP_
<|endoftext|>


<commit_before>#include <iostream>
#include <windows.h>
#include <string>
#include <fstream>
#include <conio.h>
#include <Shlwapi.h>
#include <stdlib.h>
#include "General.h"
#include "Progress.h"
#pragma comment(lib, "shlwapi.lib")

#ifdef DEBUG
	#define VERSION "1.32d"
#endif
#ifdef RELEASE
	#define VERSION "1.32r"
#endif

using namespace std;

int main()
{
	// Initializing console.
	string input = "";
	string command = "";
	PrepareConsole("Tree", VERSION, "Please name the file which should be source of the tree.\nType \"help\" for further information.");

	// Loop waits for correct input.
	while (true)
	{
		Color(INPUT_COLOR);
		cout << "Tree.exe> ";
		getline(cin, input, '\n');
		command = ToLower(GetWord(input, 1));
		Color(OUTPUT_COLOR);

		// Parsing.
		if (command == "exit" || command == "quit")
		{
			// Leaving program when "exit" or "quit" has been typed.
			return(EXIT_SUCCESS);
		}
		else if (command == "help")
		{
			// Shows a description of all available commands.
			cout << "   Available Commands:" << endl;
			cout << "   help\t\tShows this page" << endl;
			cout << "   info\t\tGeneral information" << endl;
			cout << "   clear/cls\tClears the Screen" << endl;
			cout << "   exit\t\tTerminates the program" << endl << endl;
			cout << "   Enter any other string to designate the file containing the tree." << endl;
			cout << "   The program will create the listed files and directories," << endl;
			cout << "   until you press 'q' or the file reaches its end." << endl << endl;
		}
		else if (command == "info")
		{
			// Shows general info about the software.
			cout << "   Tree Version " << VERSION << endl;
			cout << "   Compiled: " << __DATE__ << ", " << __TIME__ << endl;
			cout << "   (c) 2012 - 2015 Julian Heinzel" << endl << endl;
		}
		else if (command == "clear" || command == "cls")
		{
			// Resets the terminal.
			PrepareConsole("Tree", VERSION, "Please name the file which should be source of the tree.\nType \"help\" for further information.");
		}
		else if (!PathFileExists(input.c_str()))
		{
			// Printing an error, if no command and no valid path has been typed.
			cout << "   Did not find file \"" + input + "\"." << endl << endl;
		}
		else
		{
			// Restoring the directory and file structure.
			string		line;
			ifstream	fileIn;
			Progress	progressBar;

			// Counting the total number of lines in the specified textfile.
			int numberOfLines = 0;
			cout << "   File found, counting lines..." << endl;
			fileIn.open(input);
			while (getline(fileIn, line))
			{
				numberOfLines += 1;
			}
			progressBar.Reset(numberOfLines, 3);

			// Opening file and skipping the first three lines.
			cout << "   Processing " << numberOfLines << " lines of text." << endl << "   ";
			fileIn.close();
			fileIn.open(input);
			getline(fileIn, line);
			getline(fileIn, line);
			getline(fileIn, line);

			// Creating directories and files.
			string path[100];
			path[0] = "C\\";
			if (!PathFileExists("C\\"))
			{
				CreateDirectory("C\\", 0);
			}

			// Loops through every line in the file.
			while (getline(fileIn, line))
			{
				bool	start = true;
				int		level = 0;
				int		length = strlen(line.c_str());
				int		space = 0;
				string	newName = "";

				// Update the terminal, quit on 'q' and 'e'
				progressBar.Increment();
				progressBar.Print();
				if (_kbhit())
				{
					char C = _getch();
					if (C == 'q' || C == 'e')
					{
						cout << endl << "   Program canceled. Processed " << progressBar.GetCounter() << " of " << progressBar.GetMaxElements() << " lines. (" << progressBar.GetString() << ")" << endl << endl;
						break;
					}
				}

				if (length == 0)
				{
					break;
				}

				// Extract directory/file name from line.
				for (int i = 0; i < length; i++)
				{
					char c = line[i];
					if ((c != ' ') && (c != '-') && (c != '\\') && (c != '|') && (c != '+') && (start = true))
					{
						start = false;
					}
					if (start == true)
					{
						space++;
					}
					if (start == false)
					{
						newName += c;
					}
				}
				start = true;
				level = ((space / 4) - 1);

				// If there is no valid file or directory name, the next line is beeing evaluated.
				if (newName == "")
				{
					continue;
				}

				// If there is a '+' or a '\' in the given line, the name will be interpreted as a directory.
				// The new path is saved and the directory created.
				if ((line.find('+') != -1) || (line.find("\\") != -1))
				{
					level += 1;
					path[level] = path[level - 1] + "\\" + newName;
					if (PathFileExists(path[level - 1].c_str()))
					{
						if (!PathFileExists(path[level].c_str()))
						{
							CreateDirectory(path[level].c_str(), 0);
						}
					}
				}
				else
				{
					// Otherwise a file is listed, which will then be created.
					ofstream fileOut;
					fileOut.open(path[level] + "\\" + newName);
					fileOut.close();
				}
			}

			if (progressBar.GetPercent() == 100)
			{
				// Info if the file has been successfully processed.
				cout << endl << "   Generated files from \"" + input + "\" succesfully." << endl << endl;
			}
		}
	}
	return(0);
}<commit_msg>Changed variable names, extracted method RestoreTree(), root folder changed to match the filename.<commit_after>#include <iostream>
#include <windows.h>
#include <string>
#include <fstream>
#include <conio.h>
#include <Shlwapi.h>
#include <stdlib.h>
#include <algorithm>
#include "General.h"
#include "Progress.h"
#pragma comment(lib, "shlwapi.lib")

#ifdef DEBUG
	#define VERSION "1.32d"
#endif
#ifdef RELEASE
	#define VERSION "1.32r"
#endif

using namespace std;

void RestoreTree(string filePath);

int main()
{
	// Initializing console.
	string input = "";
	string command = "";
	PrepareConsole("Tree", VERSION, "Please name the file which should be source of the tree.\nType \"help\" for further information.");

	// Loop waits for correct input.
	while (true)
	{
		Color(INPUT_COLOR);
		cout << "Tree.exe> ";
		getline(cin, input, '\n');
		command = ToLower(GetWord(input, 1));
		Color(OUTPUT_COLOR);

		// Parsing.
		if (command == "exit" || command == "quit")
		{
			// Leaving program when "exit" or "quit" has been typed.
			return(EXIT_SUCCESS);
		}
		else if (command == "help")
		{
			// Shows a description of all available commands.
			cout << "   Available Commands:" << endl;
			cout << "   help\t\tShows this page" << endl;
			cout << "   info\t\tGeneral information" << endl;
			cout << "   clear/cls\tClears the Screen" << endl;
			cout << "   exit\t\tTerminates the program" << endl << endl;
			cout << "   Enter any other string to designate the file containing the tree." << endl;
			cout << "   The program will create the listed files and directories," << endl;
			cout << "   until you press 'q' or the file reaches its end." << endl << endl;
		}
		else if (command == "info")
		{
			// Shows general info about the software.
			cout << "   Tree Version " << VERSION << endl;
			cout << "   Compiled: " << __DATE__ << ", " << __TIME__ << endl;
			cout << "   (c) 2012 - 2015 Julian Heinzel" << endl << endl;
		}
		else if (command == "clear" || command == "cls")
		{
			// Resets the terminal.
			PrepareConsole("Tree", VERSION, "Please name the file which should be source of the tree.\nType \"help\" for further information.");
		}
		else if (!PathFileExists(input.c_str()))
		{
			// Printing an error, if no command and no valid path has been typed.
			cout << "   Did not find file \"" + input + "\"." << endl << endl;
		}
		else
		{
			RestoreTree(input);
		}
	}
	return(EXIT_SUCCESS);
}

// Restores the directory and file structure.
void RestoreTree(string filePath)
{
	string		line;
	ifstream	fileIn;
	Progress	progressBar;

	// Counting the total number of lines in the specified textfile.
	int numberOfLines = 0;
	cout << "   File found, counting lines..." << endl;
	fileIn.open(filePath);
	while (getline(fileIn, line))
	{
		numberOfLines += 1;
	}
	progressBar.Reset(numberOfLines, 3);

	// Opening file and skipping the first three lines.
	cout << "   Processing " << numberOfLines << " lines of text." << endl << "   ";
	fileIn.close();
	fileIn.open(filePath);
	for (int i = 0; i < 3; i++) getline(fileIn, line);

	// Get the filename, replace '.' by '_', set the resulting string as root folder.
	string path[100];
	string fileName = GetFileName(filePath);
	replace(fileName.begin(), fileName.end(), '.', '_');
	path[0] = fileName;
	CreateDirectory(path[0].c_str(), 0);

	// Loops through every line in the file.
	while (getline(fileIn, line))
	{
		bool	readingName = false;
		int		level = 0;
		int		length = strlen(line.c_str());
		int		indention = 0;
		string	newName = "";

		// Update the terminal, quit on 'q' and 'e'
		progressBar.Increment();
		progressBar.Print();
		if (_kbhit())
		{
			char C = _getch();
			if (C == 'q' || C == 'e')
			{
				cout << endl << "   Program canceled. Processed "
					<< progressBar.GetCounter() << " of " << progressBar.GetMaxElements()
					<< " lines. (" << progressBar.GetString() << ")" << endl << endl;
				return;
			}
		}

		if (length == 0)
		{
			break;
		}

		// Extract directory/file name from line.
		for (int i = 0; i < length; i++)
		{
			char c = line[i];
			if ((c != ' ') && (c != '-') && (c != '\\') && (c != '|') && (c != '+') && (readingName == false))
			{
				readingName = true;
			}

			if (readingName == true)
			{
				newName += c;
			}
			else
			{
				indention++;
			}
		}
		level = ((indention / 4) - 1);

		// If there is no valid file or directory name, the next line is beeing evaluated.
		if (newName == "")
		{
			continue;
		}

		// If there is a '+' or a '\' in the given line, the name will be interpreted as a directory.
		// The new path is saved and the directory created.
		if ((line.find('+') != -1) || (line.find("\\") != -1))
		{
			level += 1;
			path[level] = path[level - 1] + "\\" + newName;
			CreateDirectory(path[level].c_str(), 0);
		}
		else
		{
			// Otherwise a file is listed, which will then be created.
			ofstream fileOut;
			fileOut.open(path[level] + "\\" + newName);
			fileOut.close();
		}
	}

	if (progressBar.GetPercent() == 100)
	{
		// Info if the file has been successfully processed.
		cout << endl << "   Generated files from \"" + filePath + "\" succesfully." << endl << endl;
	}
}<|endoftext|>


<commit_before>/*
 * This file is part of accounts-ui
 *
 * Copyright (C) 2009-2010 Nokia Corporation.
 *
 * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include "service-selection-page.h"
#include "account-sync-handler.h"
#include "provider-plugin-process.h"
#include "service-settings-widget.h"
#include "accountsmanagersingleton.h"
#include "account-setup-finished-page.h"
#include "provider-plugin-process.h"
#include "basic-header-widget.h"

//Qt
#include <QStringListModel>
#include <QItemSelection>
#include <QDebug>

//Meegotouch
#include <MLayout>
#include <MList>
#include <MGridLayoutPolicy>
#include <MLinearLayoutPolicy>
#include <MButton>
#include <MWidgetCreator>
#include <MContainer>
#include <MSeparator>
#include <MBasicListItem>
#include <MWidgetAction>
#include <MImageWidget>
#include <MLabel>
#include <MLocale>
#include <MPannableViewport>
#include <MPositionIndicator>

//libAccounts
#include <Accounts/Provider>
#include <Accounts/Manager>

namespace AccountsUI {

M_REGISTER_WIDGET_NO_CREATE(ServiceSelectionPage)

//TODO: write the service plugins
class ServiceSelectionPagePrivate
{
public:
    ServiceSelectionPagePrivate()
        : serviceList(0),
        saveAction(0),
        cancelAction(0),
        context(0),
        syncHandler(0),
        layoutServicePolicy(0)
        {}
    ~ServiceSelectionPagePrivate() {}

    MList *serviceList;
    MAction *saveAction;
    MAction *cancelAction;
    AbstractAccountSetupContext *context;
    QList<AbstractServiceSetupContext*> serviceContextList;
    QList<AbstractSetupContext*> abstractContexts;
    AccountSyncHandler *syncHandler;
    MLinearLayoutPolicy *layoutServicePolicy;
    QString serviceType;
    QMap<QString, bool> serviceStatusMap;
};

ServiceSelectionPage::ServiceSelectionPage(AbstractAccountSetupContext *context,
                                           QList<AbstractServiceSetupContext*>
                                           &serviceContextList,
                                           QGraphicsItem *parent)
        : MApplicationPage(parent),
        d_ptr(new ServiceSelectionPagePrivate())
{
    Q_D(ServiceSelectionPage);
    setStyleName("AccountsUiPage");
    d->context = context;
    d->serviceType = context->serviceType();
    d->context->account()->selectService(NULL);
    d->context->account()->setEnabled(true);
    d->serviceContextList = serviceContextList;
    d->abstractContexts.append(d->context);

    d->syncHandler = new AccountSyncHandler(this);
    connect(d->syncHandler, SIGNAL(syncStateChanged(const SyncState&)),
            this, SLOT(onSyncStateChanged(const SyncState&)));
    pannableViewport()->positionIndicator()->setStyleName("CommonPositionIndicatorInverted");
}

void ServiceSelectionPage::serviceSelected(QModelIndex index)
{
    Q_UNUSED(index);
}

ServiceSelectionPage::~ServiceSelectionPage()
{
    delete d_ptr;
}

void ServiceSelectionPage::createContent()
{
    Q_D(ServiceSelectionPage);

    setComponentsDisplayMode(EscapeButton, MApplicationPageModel::Hide);

    //we need a central widget to get the right layout size under the menubar
    MWidget *centralWidget = new MWidget();
    setCentralWidget(centralWidget);
    MLayout *layout = new MLayout(centralWidget);
    MLinearLayoutPolicy *layoutPolicy = new MLinearLayoutPolicy(layout, Qt::Vertical);
    layoutPolicy->setSpacing(0);

    if (d->context) {
        MWidget *upperWidget = new MWidget(this);
        MLayout *upperLayout = new MLayout(upperWidget);
        MLinearLayoutPolicy *upperLayoutPolicy = new MLinearLayoutPolicy(upperLayout, Qt::Vertical);
        upperLayoutPolicy->setSpacing(0);

        MLayout *topLayout = new MLayout();
        MLinearLayoutPolicy *topLayoutPolicy = new MLinearLayoutPolicy(topLayout, Qt::Vertical);
        topLayoutPolicy->setSpacing(0);

        QString providerName(d->context->account()->providerName());
        // xml file that describes the ui elements for the provider
        Accounts::Provider *provider = AccountsManager::instance()->provider(providerName);
        if (provider) {
            // loading common catalog to show device name string
            MLocale locale;
            QString catalog = "common";
            if (!catalog.isEmpty() && !locale.isInstalledTrCatalog(catalog)) {
                locale.installTrCatalog(catalog);
                MLocale::setDefault(locale);
            }

            // provider info header
            QDomElement root = provider->domDocument().documentElement();
            QDomElement providerIcon = root.firstChildElement("icon");
            QString providerIconId = providerIcon.text();

            BasicHeaderWidget *providerInfoItem = new BasicHeaderWidget(this);
            providerInfoItem->setImage(providerIconId);
            providerInfoItem->setTitle(qtTrId(provider->displayName().toLatin1()));
            providerInfoItem->setSubtitle(qtTrId(d->context->account()->displayName().toLatin1()));
            providerInfoItem->setObjectName("wgServiceSelectionPageBasicListItem");
            topLayoutPolicy->addItem(providerInfoItem, Qt::AlignLeft | Qt::AlignVCenter);

            // account connected message
            QDomElement accountConnectedMessage= root.firstChildElement("account-connected-message");
            if (!accountConnectedMessage.isNull()) {
                // display a account connected message for provider
                QString accountConnectedMessageId=
                        qtTrId((accountConnectedMessage.text()).toLatin1()).arg(qtTrId("qtn_comm_product_n9"));
                MLabel *accountConnectedMessageLabel=
                        new MLabel(accountConnectedMessageId);
                accountConnectedMessageLabel->setWordWrap(1);
		accountConnectedMessageLabel->setStyleName("CommonBodyTextInverted");
                topLayoutPolicy->addItem(accountConnectedMessageLabel, Qt::AlignLeft | Qt::AlignVCenter);
            }
        }

        MSeparator *separatorTop = new MSeparator(this);
        separatorTop->setStyleName("CommonItemDividerInverted");
        separatorTop->setOrientation(Qt::Horizontal);

        upperLayoutPolicy->addItem(topLayout);
        upperLayoutPolicy->addItem(separatorTop);

        layoutPolicy->addItem(upperWidget);
    }

    MWidget *serviceWidget = new MWidget();
    MLayout *serviceSettingLayout = new MLayout(serviceWidget);
    d->layoutServicePolicy = new MLinearLayoutPolicy(serviceSettingLayout, Qt::Vertical);
    d->layoutServicePolicy->setSpacing(0);

    for (int i = 0; i < d->serviceContextList.count(); i++) {
        //ServiceSettingsWidget sets the display widget of the changing settings
        ServiceSettingsWidget *settingsWidget =
            new ServiceSettingsWidget(d->serviceContextList.at(i), serviceWidget,
                                      ServiceSettingsWidget::MandatorySettings |
                                      ServiceSettingsWidget::EnableButton,
                                      true);
        const Accounts::Service *service = d->serviceContextList.at(i)->service();
        emit serviceEnabled(service->name(), true);
        d->serviceStatusMap.insert(service->name(), true);
        d->abstractContexts.append(d->serviceContextList.at(i));
        d->layoutServicePolicy->addItem(settingsWidget, Qt::AlignLeft);
        connect (settingsWidget, SIGNAL(serviceEnabled(const QString&, bool)),
                 this, SIGNAL(serviceEnabled(const QString&, bool)));
        connect (settingsWidget, SIGNAL(serviceEnabled(const QString&, bool)),
                 this, SLOT(setEnabledService(const QString&, bool)));
    }

    layoutPolicy->addItem(serviceWidget, Qt::AlignLeft);

    //% "DONE"
    d->saveAction = new MAction(qtTrId("qtn_comm_command_done"), centralWidget);
    d->saveAction->setLocation(MAction::ToolBarLocation);
    addAction(d->saveAction);

    //% "CANCEL"
    d->cancelAction = new MAction(qtTrId("qtn_comm_cancel"), centralWidget);
    d->cancelAction->setLocation(MAction::ToolBarLocation);
    addAction(d->cancelAction);
    layoutPolicy->addStretch();

    connect(d->saveAction, SIGNAL(triggered()),
            this, SLOT(onAccountInstallButton()));
    connect(d->cancelAction, SIGNAL(triggered()),
            this, SLOT(cancel()));
    connect(d->serviceList, SIGNAL(itemClicked(QModelIndex)),
            this,SLOT(serviceSelected(QModelIndex)));

    connect(this, SIGNAL(backButtonClicked()),
            this, SLOT(close()));
}

void ServiceSelectionPage::onAccountInstallButton()
{
    Q_D(ServiceSelectionPage);

    disconnect(d->saveAction, SIGNAL(triggered()),
               this, SLOT(onAccountInstallButton()));

    setProgressIndicatorVisible(true);
    for (int i = 0; i < d->serviceContextList.count(); i++) {
        const Accounts::Service *service = d->serviceContextList.at(i)->service();
        QMap<QString, bool>::iterator mapIterator =
                d->serviceStatusMap.find(service->name());
        if (mapIterator == d->serviceStatusMap.end())
            continue;
        d->serviceContextList.at(i)->enable(mapIterator.value());
        d->serviceStatusMap.remove(mapIterator.key());
    }
    d->syncHandler->validate(d->abstractContexts);
}

void ServiceSelectionPage::onSyncStateChanged(const SyncState &state)
{
    Q_D(ServiceSelectionPage);

    switch (state) {
        case Validated:
            d->syncHandler->store(d->abstractContexts);
            break;
        case Stored:
            if (d->serviceType.isEmpty()) {
                connect(d->context->account(), SIGNAL(synced()),
                        ProviderPluginProcess::instance(), SLOT(quit()));
                d->context->account()->sync();
            } else {
                d->context->account()->sync();
                AccountSetupFinishedPage *page = new AccountSetupFinishedPage(d->context);
                page->appear();
            }
            break;
        default:
            connect(d->saveAction, SIGNAL(triggered()),
                    this, SLOT(onAccountInstallButton()));
            connect(d->cancelAction, SIGNAL(triggered()),
                    this, SLOT(cancel()));
            setProgressIndicatorVisible(false);
            return;
    }
}

void ServiceSelectionPage::setWidget(MWidget *widget)
{
    Q_D(ServiceSelectionPage);

    if (d->layoutServicePolicy && widget)
        d->layoutServicePolicy->addItem(widget);
}

void ServiceSelectionPage::setEnabledService(const QString &serviceName,
                                            bool enabled)
{
    Q_D(ServiceSelectionPage);
    d->serviceStatusMap[serviceName] = enabled;
}

void ServiceSelectionPage::cancel()
{
    ProviderPluginProcess::instance()->setReturnToAccountsList(true);
}

} //namespace
<commit_msg>Fix for Bug 216995 - Service selection view is missing a label<commit_after>/*
 * This file is part of accounts-ui
 *
 * Copyright (C) 2009-2010 Nokia Corporation.
 *
 * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include "service-selection-page.h"
#include "account-sync-handler.h"
#include "provider-plugin-process.h"
#include "service-settings-widget.h"
#include "accountsmanagersingleton.h"
#include "account-setup-finished-page.h"
#include "provider-plugin-process.h"
#include "basic-header-widget.h"

//Qt
#include <QStringListModel>
#include <QItemSelection>
#include <QDebug>

//Meegotouch
#include <MLayout>
#include <MList>
#include <MGridLayoutPolicy>
#include <MLinearLayoutPolicy>
#include <MButton>
#include <MWidgetCreator>
#include <MContainer>
#include <MSeparator>
#include <MBasicListItem>
#include <MWidgetAction>
#include <MImageWidget>
#include <MLabel>
#include <MLocale>
#include <MPannableViewport>
#include <MPositionIndicator>

//libAccounts
#include <Accounts/Provider>
#include <Accounts/Manager>

namespace AccountsUI {

M_REGISTER_WIDGET_NO_CREATE(ServiceSelectionPage)

//TODO: write the service plugins
class ServiceSelectionPagePrivate
{
public:
    ServiceSelectionPagePrivate()
        : serviceList(0),
        saveAction(0),
        cancelAction(0),
        context(0),
        syncHandler(0),
        layoutServicePolicy(0)
        {}
    ~ServiceSelectionPagePrivate() {}

    MList *serviceList;
    MAction *saveAction;
    MAction *cancelAction;
    AbstractAccountSetupContext *context;
    QList<AbstractServiceSetupContext*> serviceContextList;
    QList<AbstractSetupContext*> abstractContexts;
    AccountSyncHandler *syncHandler;
    MLinearLayoutPolicy *layoutServicePolicy;
    QString serviceType;
    QMap<QString, bool> serviceStatusMap;
};

ServiceSelectionPage::ServiceSelectionPage(AbstractAccountSetupContext *context,
                                           QList<AbstractServiceSetupContext*>
                                           &serviceContextList,
                                           QGraphicsItem *parent)
        : MApplicationPage(parent),
        d_ptr(new ServiceSelectionPagePrivate())
{
    Q_D(ServiceSelectionPage);
    setStyleName("AccountsUiPage");
    d->context = context;
    d->serviceType = context->serviceType();
    d->context->account()->selectService(NULL);
    d->context->account()->setEnabled(true);
    d->serviceContextList = serviceContextList;
    d->abstractContexts.append(d->context);

    d->syncHandler = new AccountSyncHandler(this);
    connect(d->syncHandler, SIGNAL(syncStateChanged(const SyncState&)),
            this, SLOT(onSyncStateChanged(const SyncState&)));
    pannableViewport()->positionIndicator()->setStyleName("CommonPositionIndicatorInverted");
}

void ServiceSelectionPage::serviceSelected(QModelIndex index)
{
    Q_UNUSED(index);
}

ServiceSelectionPage::~ServiceSelectionPage()
{
    delete d_ptr;
}

void ServiceSelectionPage::createContent()
{
    Q_D(ServiceSelectionPage);

    setComponentsDisplayMode(EscapeButton, MApplicationPageModel::Hide);

    //we need a central widget to get the right layout size under the menubar
    MWidget *centralWidget = new MWidget();
    setCentralWidget(centralWidget);
    MLayout *layout = new MLayout(centralWidget);
    MLinearLayoutPolicy *layoutPolicy = new MLinearLayoutPolicy(layout, Qt::Vertical);
    layoutPolicy->setSpacing(0);

    if (d->context) {
        MWidget *upperWidget = new MWidget(this);
        MLayout *upperLayout = new MLayout(upperWidget);
        MLinearLayoutPolicy *upperLayoutPolicy = new MLinearLayoutPolicy(upperLayout, Qt::Vertical);
        upperLayoutPolicy->setSpacing(0);

        MLayout *topLayout = new MLayout();
        MLinearLayoutPolicy *topLayoutPolicy = new MLinearLayoutPolicy(topLayout, Qt::Vertical);
        topLayoutPolicy->setSpacing(0);

        QString providerName(d->context->account()->providerName());
        // xml file that describes the ui elements for the provider
        Accounts::Provider *provider = AccountsManager::instance()->provider(providerName);
        if (provider) {
            // loading common catalog to show device name string
            MLocale locale;
            QString catalog = "common";
            if (!catalog.isEmpty() && !locale.isInstalledTrCatalog(catalog)) {
                locale.installTrCatalog(catalog);
                MLocale::setDefault(locale);
            }

            // provider info header
            QDomElement root = provider->domDocument().documentElement();
            QDomElement providerIcon = root.firstChildElement("icon");
            QString providerIconId = providerIcon.text();

            BasicHeaderWidget *providerInfoItem = new BasicHeaderWidget(this);
            providerInfoItem->setImage(providerIconId);
            providerInfoItem->setTitle(qtTrId(provider->displayName().toLatin1()));
            providerInfoItem->setSubtitle(qtTrId(d->context->account()->displayName().toLatin1()));
            providerInfoItem->setObjectName("wgServiceSelectionPageBasicListItem");
            topLayoutPolicy->addItem(providerInfoItem, Qt::AlignLeft | Qt::AlignVCenter);

            // account connected message
            QString accountConnectedMessageId;
            QDomElement accountConnectedMessage= root.firstChildElement("account-connected-message");
            if (!accountConnectedMessage.isNull()) {
                // display a account connected message for provider
                accountConnectedMessageId =
                        qtTrId((accountConnectedMessage.text()).toLatin1()).arg(qtTrId("qtn_comm_product_n9"));
            }
            else {
                // default message for service selection.
                accountConnectedMessageId = qtTrId("qtn_acc_enable_services_in_apps");
            }
            MLabel *accountConnectedMessageLabel=
                    new MLabel(accountConnectedMessageId);
            accountConnectedMessageLabel->setWordWrap(1);
            accountConnectedMessageLabel->setStyleName("CommonBodyTextInverted");
            topLayoutPolicy->addItem(accountConnectedMessageLabel, Qt::AlignLeft | Qt::AlignVCenter);
        }

        MSeparator *separatorTop = new MSeparator(this);
        separatorTop->setStyleName("CommonItemDividerInverted");
        separatorTop->setOrientation(Qt::Horizontal);

        upperLayoutPolicy->addItem(topLayout);
        upperLayoutPolicy->addItem(separatorTop);

        layoutPolicy->addItem(upperWidget);
    }

    MWidget *serviceWidget = new MWidget();
    MLayout *serviceSettingLayout = new MLayout(serviceWidget);
    d->layoutServicePolicy = new MLinearLayoutPolicy(serviceSettingLayout, Qt::Vertical);
    d->layoutServicePolicy->setSpacing(0);

    for (int i = 0; i < d->serviceContextList.count(); i++) {
        //ServiceSettingsWidget sets the display widget of the changing settings
        ServiceSettingsWidget *settingsWidget =
            new ServiceSettingsWidget(d->serviceContextList.at(i), serviceWidget,
                                      ServiceSettingsWidget::MandatorySettings |
                                      ServiceSettingsWidget::EnableButton,
                                      true);
        const Accounts::Service *service = d->serviceContextList.at(i)->service();
        emit serviceEnabled(service->name(), true);
        d->serviceStatusMap.insert(service->name(), true);
        d->abstractContexts.append(d->serviceContextList.at(i));
        d->layoutServicePolicy->addItem(settingsWidget, Qt::AlignLeft);
        connect (settingsWidget, SIGNAL(serviceEnabled(const QString&, bool)),
                 this, SIGNAL(serviceEnabled(const QString&, bool)));
        connect (settingsWidget, SIGNAL(serviceEnabled(const QString&, bool)),
                 this, SLOT(setEnabledService(const QString&, bool)));
    }

    layoutPolicy->addItem(serviceWidget, Qt::AlignLeft);

    //% "DONE"
    d->saveAction = new MAction(qtTrId("qtn_comm_command_done"), centralWidget);
    d->saveAction->setLocation(MAction::ToolBarLocation);
    addAction(d->saveAction);

    //% "CANCEL"
    d->cancelAction = new MAction(qtTrId("qtn_comm_cancel"), centralWidget);
    d->cancelAction->setLocation(MAction::ToolBarLocation);
    addAction(d->cancelAction);
    layoutPolicy->addStretch();

    connect(d->saveAction, SIGNAL(triggered()),
            this, SLOT(onAccountInstallButton()));
    connect(d->cancelAction, SIGNAL(triggered()),
            this, SLOT(cancel()));
    connect(d->serviceList, SIGNAL(itemClicked(QModelIndex)),
            this,SLOT(serviceSelected(QModelIndex)));

    connect(this, SIGNAL(backButtonClicked()),
            this, SLOT(close()));
}

void ServiceSelectionPage::onAccountInstallButton()
{
    Q_D(ServiceSelectionPage);

    disconnect(d->saveAction, SIGNAL(triggered()),
               this, SLOT(onAccountInstallButton()));

    setProgressIndicatorVisible(true);
    for (int i = 0; i < d->serviceContextList.count(); i++) {
        const Accounts::Service *service = d->serviceContextList.at(i)->service();
        QMap<QString, bool>::iterator mapIterator =
                d->serviceStatusMap.find(service->name());
        if (mapIterator == d->serviceStatusMap.end())
            continue;
        d->serviceContextList.at(i)->enable(mapIterator.value());
        d->serviceStatusMap.remove(mapIterator.key());
    }
    d->syncHandler->validate(d->abstractContexts);
}

void ServiceSelectionPage::onSyncStateChanged(const SyncState &state)
{
    Q_D(ServiceSelectionPage);

    switch (state) {
        case Validated:
            d->syncHandler->store(d->abstractContexts);
            break;
        case Stored:
            if (d->serviceType.isEmpty()) {
                connect(d->context->account(), SIGNAL(synced()),
                        ProviderPluginProcess::instance(), SLOT(quit()));
                d->context->account()->sync();
            } else {
                d->context->account()->sync();
                AccountSetupFinishedPage *page = new AccountSetupFinishedPage(d->context);
                page->appear();
            }
            break;
        default:
            connect(d->saveAction, SIGNAL(triggered()),
                    this, SLOT(onAccountInstallButton()));
            connect(d->cancelAction, SIGNAL(triggered()),
                    this, SLOT(cancel()));
            setProgressIndicatorVisible(false);
            return;
    }
}

void ServiceSelectionPage::setWidget(MWidget *widget)
{
    Q_D(ServiceSelectionPage);

    if (d->layoutServicePolicy && widget)
        d->layoutServicePolicy->addItem(widget);
}

void ServiceSelectionPage::setEnabledService(const QString &serviceName,
                                            bool enabled)
{
    Q_D(ServiceSelectionPage);
    d->serviceStatusMap[serviceName] = enabled;
}

void ServiceSelectionPage::cancel()
{
    ProviderPluginProcess::instance()->setReturnToAccountsList(true);
}

} //namespace
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>

#include "objc/runtime.h"
#include "visibility.h"

#include <windows.h>
#define RtlAddGrowableFunctionTable ClangIsConfusedByTypedefReturnTypes
#include <rtlsupportapi.h>

#ifndef __has_builtin
#define __has_builtin(x) 0
#endif

#if !__has_builtin(__builtin_unreachable)
#define __builtin_unreachable abort
#endif

struct _MSVC_TypeDescriptor
{
	const void* pVFTable;
	void* spare;
	char name[0];
};

struct _MSVC_CatchableType
{
	unsigned int flags;
	unsigned long type;
	int mdisp;
	int pdisp;
	int vdisp;
	int size;
	unsigned long copyFunction;
};

struct _MSVC_CatchableTypeArray
{
	int count;
	unsigned long types[0];
};

struct _MSVC_ThrowInfo
{
	unsigned int attributes;
	unsigned long pfnUnwind;
	unsigned long pfnForwardCompat;
	unsigned long pCatchableTypeArray;
};

#if defined(_WIN64)
#define IMAGE_RELATIVE(ptr, base) (static_cast<unsigned long>((ptr ? ((uintptr_t)ptr - (uintptr_t)base) : (uintptr_t)nullptr)))
#else
#define IMAGE_RELATIVE(ptr, base) reinterpret_cast<unsigned long>((ptr))
#endif

extern "C" void __stdcall _CxxThrowException(void*, _MSVC_ThrowInfo*);

namespace
{

static std::string mangleObjcObject()
{
#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
	return ".PEAU.objc_object@@";
#else
	return ".PAU.objc_object@@";
#endif
}

static std::string mangleStructNamed(const char* className)
{
	// 32-bit:
	//  .PAUxxx@@ = ?? struct xxx * `RTTI Type Descriptor'
	// 64-bit:
	//  .PEAUxxx@@ = ?? struct xxx * __ptr64 `RTTI Type Descriptor'
	//return
	auto r =
#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
		std::string(".PEAU.objc_cls_") +
#else
		std::string(".PAU.objc_cls_") +
#endif
		className + "@@";
	return r;
}

void fillCatchableType(_MSVC_CatchableType* exceptType)
{
	exceptType->flags = 1;
	exceptType->mdisp = 0;
	exceptType->pdisp = -1;
	exceptType->vdisp = 0;
	exceptType->size = sizeof(id);
	exceptType->copyFunction = 0;
}

} // <anonymous-namespace>

struct X {};
PUBLIC extern "C" void objc_exception_rethrow(void* exc);

PUBLIC extern "C" void objc_exception_throw(id object)
{
	// Base used for image-relative addresses.
	char x;
	// This is the base vtable for all RTTI entries
	static const void* typeid_vtable = *(void**)&typeid(void *);

	SEL rethrow_sel = sel_registerName("rethrow");
	if ((nil != object) &&
		(class_respondsToSelector(object_getClass(object), rethrow_sel)))
	{
		IMP rethrow = objc_msg_lookup(object, rethrow_sel);
		rethrow(object, rethrow_sel);
		// Should not be reached!  If it is, then the rethrow method actually
		// didn't, so we throw it normally.
	}

	SEL processException_sel = sel_registerName("_processException");
	if ((nil != object) &&
		(class_respondsToSelector(object_getClass(object), processException_sel)))
	{
		IMP processException = objc_msg_lookup(object, processException_sel);
		processException(object, processException_sel);
	}

	// The 'id' base type will be taking up a spot in the list:
	size_t typeCount = 1;

	// Get count of all types in exception
	for (Class cls = object_getClass(object); cls != Nil; cls = class_getSuperclass(cls), ++typeCount)
		;

	// Unfortunately we can't put this in a real function since the alloca has to be in this stack frame:
#define CREATE_TYPE_DESCRIPTOR(desc, symName) \
	desc = reinterpret_cast<_MSVC_TypeDescriptor*>(alloca(sizeof(_MSVC_TypeDescriptor) + symName.size() + 1 /* null terminator */)); \
	desc->pVFTable = typeid_vtable; \
	desc->spare = nullptr; \
	strcpy_s(desc->name, symName.size() + 1, symName.c_str());

	auto exceptTypes =
		(_MSVC_CatchableTypeArray*)_alloca(sizeof(_MSVC_CatchableTypeArray) + sizeof(_MSVC_CatchableType*) * typeCount);
	exceptTypes->count = typeCount;

	// Add exception type and all base types to throw information
	size_t curTypeIndex = 0;
	for (Class cls = object_getClass(object); cls != Nil; cls = class_getSuperclass(cls))
	{
		auto exceptType = (_MSVC_CatchableType*)_alloca(sizeof(_MSVC_CatchableType));
		fillCatchableType(exceptType);

		auto mangledName = mangleStructNamed(class_getName(cls));
		_MSVC_TypeDescriptor *ty;
		CREATE_TYPE_DESCRIPTOR(ty, mangledName);
		exceptType->type = IMAGE_RELATIVE(ty, &x);
		exceptTypes->types[curTypeIndex++] = IMAGE_RELATIVE(exceptType, &x);
	}

	// Add id (struct objc_object*)
	auto exceptType = (_MSVC_CatchableType*)_alloca(sizeof(_MSVC_CatchableType));
	fillCatchableType(exceptType);
	auto idName = mangleObjcObject();
	_MSVC_TypeDescriptor *ty;
	CREATE_TYPE_DESCRIPTOR(ty, idName);
	exceptType->type = IMAGE_RELATIVE(ty, &x);
	exceptTypes->types[curTypeIndex++] = IMAGE_RELATIVE(exceptType, &x);

	_MSVC_ThrowInfo ti = {
		0, // attributes
		0, // pfnUnwind
		0, // pfnForwardCompat
		IMAGE_RELATIVE(exceptTypes, &x) // pCatchableTypeArray
	};
#	define EH_EXCEPTION_NUMBER ('msc' | 0xE0000000)
#	define EH_MAGIC_NUMBER1 0x19930520
#	define EXCEPTION_NONCONTINUABLE 0x1
	EXCEPTION_RECORD  exception;
	exception.ExceptionCode = EH_EXCEPTION_NUMBER;
	exception.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
	exception.ExceptionRecord = nullptr;
	exception.ExceptionAddress = nullptr;
	// The fourth parameter is the base address of the image (for us, this stack
	// frame), but we only use image-relative 32-bit addresses on 64-bit
	// platforms.  On 32-bit platforms, we use 32-bit absolute addresses.
	exception.NumberParameters = sizeof(void*) == 4 ? 3 : 4;
	exception.ExceptionInformation[0] = EH_MAGIC_NUMBER1;
	exception.ExceptionInformation[1] = reinterpret_cast<ULONG_PTR>(&object);
	exception.ExceptionInformation[2] = reinterpret_cast<ULONG_PTR>(&ti);
	exception.ExceptionInformation[3] = reinterpret_cast<ULONG_PTR>(&x);

#ifdef _WIN64
 	RtlRaiseException(&exception);
#else
	RaiseException(exception.ExceptionCode,
		exception.ExceptionFlags,
		exception.NumberParameters,
		exception.ExceptionInformation);
#endif
	__builtin_unreachable();
}

PUBLIC extern "C" void objc_exception_rethrow(void* exc)
{
	_CxxThrowException(nullptr, nullptr);
	__builtin_unreachable();
}

<commit_msg>[windows] Handle changes to clang's EH mangling<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>

#include "objc/runtime.h"
#include "visibility.h"

#include <windows.h>
#define RtlAddGrowableFunctionTable ClangIsConfusedByTypedefReturnTypes
#include <rtlsupportapi.h>

#ifndef __has_builtin
#define __has_builtin(x) 0
#endif

#if !__has_builtin(__builtin_unreachable)
#define __builtin_unreachable abort
#endif

struct _MSVC_TypeDescriptor
{
	const void* pVFTable;
	void* spare;
	char name[0];
};

struct _MSVC_CatchableType
{
	unsigned int flags;
	unsigned long type;
	int mdisp;
	int pdisp;
	int vdisp;
	int size;
	unsigned long copyFunction;
};

struct _MSVC_CatchableTypeArray
{
	int count;
	unsigned long types[0];
};

struct _MSVC_ThrowInfo
{
	unsigned int attributes;
	unsigned long pfnUnwind;
	unsigned long pfnForwardCompat;
	unsigned long pCatchableTypeArray;
};

#if defined(_WIN64)
#define IMAGE_RELATIVE(ptr, base) (static_cast<unsigned long>((ptr ? ((uintptr_t)ptr - (uintptr_t)base) : (uintptr_t)nullptr)))
#else
#define IMAGE_RELATIVE(ptr, base) reinterpret_cast<unsigned long>((ptr))
#endif

extern "C" void __stdcall _CxxThrowException(void*, _MSVC_ThrowInfo*);

namespace
{

static std::string mangleObjcObject()
{
#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
	return ".PEAUobjc_object@@";
#else
	return ".PAUobjc_object@@";
#endif
}

static std::string mangleStructNamed(const char* className)
{
	// 32-bit:
	//  .PAUxxx@@ = ?? struct xxx * `RTTI Type Descriptor'
	// 64-bit:
	//  .PEAUxxx@@ = ?? struct xxx * __ptr64 `RTTI Type Descriptor'
	//return
	auto r =
#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
		std::string(".PEAU") +
#else
		std::string(".PAU") +
#endif
		className + "@@";
	return r;
}

void fillCatchableType(_MSVC_CatchableType* exceptType)
{
	exceptType->flags = 1;
	exceptType->mdisp = 0;
	exceptType->pdisp = -1;
	exceptType->vdisp = 0;
	exceptType->size = sizeof(id);
	exceptType->copyFunction = 0;
}

} // <anonymous-namespace>

struct X {};
PUBLIC extern "C" void objc_exception_rethrow(void* exc);

PUBLIC extern "C" void objc_exception_throw(id object)
{
	// Base used for image-relative addresses.
	char x;
	// This is the base vtable for all RTTI entries
	static const void* typeid_vtable = *(void**)&typeid(void *);

	SEL rethrow_sel = sel_registerName("rethrow");
	if ((nil != object) &&
		(class_respondsToSelector(object_getClass(object), rethrow_sel)))
	{
		IMP rethrow = objc_msg_lookup(object, rethrow_sel);
		rethrow(object, rethrow_sel);
		// Should not be reached!  If it is, then the rethrow method actually
		// didn't, so we throw it normally.
	}

	SEL processException_sel = sel_registerName("_processException");
	if ((nil != object) &&
		(class_respondsToSelector(object_getClass(object), processException_sel)))
	{
		IMP processException = objc_msg_lookup(object, processException_sel);
		processException(object, processException_sel);
	}

	// The 'id' base type will be taking up a spot in the list:
	size_t typeCount = 1;

	// Get count of all types in exception
	for (Class cls = object_getClass(object); cls != Nil; cls = class_getSuperclass(cls), ++typeCount)
		;

	// Unfortunately we can't put this in a real function since the alloca has to be in this stack frame:
#define CREATE_TYPE_DESCRIPTOR(desc, symName) \
	desc = reinterpret_cast<_MSVC_TypeDescriptor*>(alloca(sizeof(_MSVC_TypeDescriptor) + symName.size() + 1 /* null terminator */)); \
	desc->pVFTable = typeid_vtable; \
	desc->spare = nullptr; \
	strcpy_s(desc->name, symName.size() + 1, symName.c_str());

	auto exceptTypes =
		(_MSVC_CatchableTypeArray*)_alloca(sizeof(_MSVC_CatchableTypeArray) + sizeof(_MSVC_CatchableType*) * typeCount);
	exceptTypes->count = typeCount;

	// Add exception type and all base types to throw information
	size_t curTypeIndex = 0;
	for (Class cls = object_getClass(object); cls != Nil; cls = class_getSuperclass(cls))
	{
		auto exceptType = (_MSVC_CatchableType*)_alloca(sizeof(_MSVC_CatchableType));
		fillCatchableType(exceptType);

		auto mangledName = mangleStructNamed(class_getName(cls));
		_MSVC_TypeDescriptor *ty;
		CREATE_TYPE_DESCRIPTOR(ty, mangledName);
		exceptType->type = IMAGE_RELATIVE(ty, &x);
		exceptTypes->types[curTypeIndex++] = IMAGE_RELATIVE(exceptType, &x);
	}

	// Add id (struct objc_object*)
	auto exceptType = (_MSVC_CatchableType*)_alloca(sizeof(_MSVC_CatchableType));
	fillCatchableType(exceptType);
	auto idName = mangleObjcObject();
	_MSVC_TypeDescriptor *ty;
	CREATE_TYPE_DESCRIPTOR(ty, idName);
	exceptType->type = IMAGE_RELATIVE(ty, &x);
	exceptTypes->types[curTypeIndex++] = IMAGE_RELATIVE(exceptType, &x);

	_MSVC_ThrowInfo ti = {
		0, // attributes
		0, // pfnUnwind
		0, // pfnForwardCompat
		IMAGE_RELATIVE(exceptTypes, &x) // pCatchableTypeArray
	};
#	define EH_EXCEPTION_NUMBER ('msc' | 0xE0000000)
#	define EH_MAGIC_NUMBER1 0x19930520
#	define EXCEPTION_NONCONTINUABLE 0x1
	EXCEPTION_RECORD  exception;
	exception.ExceptionCode = EH_EXCEPTION_NUMBER;
	exception.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
	exception.ExceptionRecord = nullptr;
	exception.ExceptionAddress = nullptr;
	// The fourth parameter is the base address of the image (for us, this stack
	// frame), but we only use image-relative 32-bit addresses on 64-bit
	// platforms.  On 32-bit platforms, we use 32-bit absolute addresses.
	exception.NumberParameters = sizeof(void*) == 4 ? 3 : 4;
	exception.ExceptionInformation[0] = EH_MAGIC_NUMBER1;
	exception.ExceptionInformation[1] = reinterpret_cast<ULONG_PTR>(&object);
	exception.ExceptionInformation[2] = reinterpret_cast<ULONG_PTR>(&ti);
	exception.ExceptionInformation[3] = reinterpret_cast<ULONG_PTR>(&x);

#ifdef _WIN64
 	RtlRaiseException(&exception);
#else
	RaiseException(exception.ExceptionCode,
		exception.ExceptionFlags,
		exception.NumberParameters,
		exception.ExceptionInformation);
#endif
	__builtin_unreachable();
}

PUBLIC extern "C" void objc_exception_rethrow(void* exc)
{
	_CxxThrowException(nullptr, nullptr);
	__builtin_unreachable();
}

<|endoftext|>