<commit_before>//===--------------------- Unwind_AppleExtras.cpp -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//

#include "config.h"
#include "DwarfParser.hpp"
#include "unwind_ext.h"

// private keymgr stuff
#define KEYMGR_GCC3_DW2_OBJ_LIST 302
extern "C" {
 extern void _keymgr_set_and_unlock_processwide_ptr(int key, void *ptr);
 extern void *_keymgr_get_and_lock_processwide_ptr(int key);
}

// undocumented libgcc "struct object"
struct libgcc_object {
  void          *start;
  void          *unused1;
  void          *unused2;
  void          *fde;
  unsigned long  encoding;
  void          *fde_end;
  libgcc_object *next;
};

// undocumented libgcc "struct km_object_info" referenced by
// KEYMGR_GCC3_DW2_OBJ_LIST
struct libgcc_object_info {
  libgcc_object   *seen_objects;
  libgcc_object   *unseen_objects;
  unsigned         spare[2];
};

// static linker symbols to prevent wrong two level namespace for _Unwind symbols
#if __arm__
   #define NOT_HERE_BEFORE_5_0(sym)     \
       extern const char sym##_tmp30 __asm("$ld$hide$os3.0$_" #sym ); \
       __attribute__((visibility("default"))) const char sym##_tmp30 = 0; \
       extern const char sym##_tmp31 __asm("$ld$hide$os3.1$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp31 = 0; \
       extern const char sym##_tmp32 __asm("$ld$hide$os3.2$_" #sym );\
           __attribute__((visibility("default"))) const char sym##_tmp32 = 0; \
       extern const char sym##_tmp40 __asm("$ld$hide$os4.0$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp40 = 0; \
       extern const char sym##_tmp41 __asm("$ld$hide$os4.1$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp41 = 0; \
       extern const char sym##_tmp42 __asm("$ld$hide$os4.2$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp42 = 0; \
       extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp43 = 0;
#elif __arm64__
  #define NOT_HERE_BEFORE_10_6(sym)
  #define NEVER_HERE(sym)
#else
  #define NOT_HERE_BEFORE_10_6(sym) \
    extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
    extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
  #define NEVER_HERE(sym) \
    extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
    extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp5 = 0; \
    extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp6 = 0;
#endif

#if _LIBUNWIND_BUILD_ZERO_COST_APIS

//
// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in
// earlier versions
//
NOT_HERE_BEFORE_10_6(_Unwind_DeleteException)
NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE)
NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind)
NOT_HERE_BEFORE_10_6(_Unwind_GetGR)
NOT_HERE_BEFORE_10_6(_Unwind_GetIP)
NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData)
NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart)
NOT_HERE_BEFORE_10_6(_Unwind_RaiseException)
NOT_HERE_BEFORE_10_6(_Unwind_Resume)
NOT_HERE_BEFORE_10_6(_Unwind_SetGR)
NOT_HERE_BEFORE_10_6(_Unwind_SetIP)
NOT_HERE_BEFORE_10_6(_Unwind_Backtrace)
NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction)
NOT_HERE_BEFORE_10_6(_Unwind_GetCFA)
NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase)
NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase)
NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow)
NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo)
NOT_HERE_BEFORE_10_6(__register_frame)
NOT_HERE_BEFORE_10_6(__deregister_frame)

//
// symbols in libSystem.dylib for compatibility, but we don't want any new code
// using them
//
NEVER_HERE(__register_frame_info_bases)
NEVER_HERE(__register_frame_info)
NEVER_HERE(__register_frame_info_table_bases)
NEVER_HERE(__register_frame_info_table)
NEVER_HERE(__register_frame_table)
NEVER_HERE(__deregister_frame_info)
NEVER_HERE(__deregister_frame_info_bases)

#endif // _LIBUNWIND_BUILD_ZERO_COST_APIS

#if _LIBUNWIND_BUILD_SJLJ_APIS
//
// symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in
// earlier versions
//
NOT_HERE_BEFORE_5_0(_Unwind_GetLanguageSpecificData)
NOT_HERE_BEFORE_5_0(_Unwind_GetRegionStart)
NOT_HERE_BEFORE_5_0(_Unwind_GetIP)
NOT_HERE_BEFORE_5_0(_Unwind_SetGR)
NOT_HERE_BEFORE_5_0(_Unwind_SetIP)
NOT_HERE_BEFORE_5_0(_Unwind_DeleteException)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Register)
NOT_HERE_BEFORE_5_0(_Unwind_GetGR)
NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo)
NOT_HERE_BEFORE_5_0(_Unwind_GetCFA)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister)

#endif // _LIBUNWIND_BUILD_SJLJ_APIS

namespace libunwind {

_LIBUNWIND_HIDDEN
bool checkKeyMgrRegisteredFDEs(uintptr_t pc, void *&fde) {
#if __MAC_OS_X_VERSION_MIN_REQUIRED
  // lastly check for old style keymgr registration of dynamically generated
  // FDEs acquire exclusive access to libgcc_object_info
  libgcc_object_info *head = (libgcc_object_info *)
                _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST);
  if (head != NULL) {
    // look at each FDE in keymgr
    for (libgcc_object *ob = head->unseen_objects; ob != NULL; ob = ob->next) {
      CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
      CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
      const char *msg = CFI_Parser<LocalAddressSpace>::decodeFDE(
                                      LocalAddressSpace::sThisAddressSpace,
                                      (uintptr_t)ob->fde, &fdeInfo, &cieInfo);
      if (msg == NULL) {
        // Check if this FDE is for a function that includes the pc
        if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
          fde = (void*)fdeInfo.pcStart;
          _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST,
                                                 head);
          return true;
        }
      }
    }
  }
  // release libgcc_object_info
  _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, head);
#else
  (void)pc;
  (void)fde;
#endif
  return false;
}

}

#if !FOR_DYLD

#include <System/pthread_machdep.h>

_LIBUNWIND_HIDDEN
struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() {
  return (struct _Unwind_FunctionContext *)
    _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key);
}

_LIBUNWIND_HIDDEN
void __Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext *fc) {
  _pthread_setspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key, fc);
}
#endif

<commit_msg>Fix conditionals on __Unwind_SjLj_* functions to only build for SJLJ based architectures<commit_after>//===--------------------- Unwind_AppleExtras.cpp -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//

#include "config.h"
#include "DwarfParser.hpp"
#include "unwind_ext.h"

// private keymgr stuff
#define KEYMGR_GCC3_DW2_OBJ_LIST 302
extern "C" {
 extern void _keymgr_set_and_unlock_processwide_ptr(int key, void *ptr);
 extern void *_keymgr_get_and_lock_processwide_ptr(int key);
}

// undocumented libgcc "struct object"
struct libgcc_object {
  void          *start;
  void          *unused1;
  void          *unused2;
  void          *fde;
  unsigned long  encoding;
  void          *fde_end;
  libgcc_object *next;
};

// undocumented libgcc "struct km_object_info" referenced by
// KEYMGR_GCC3_DW2_OBJ_LIST
struct libgcc_object_info {
  libgcc_object   *seen_objects;
  libgcc_object   *unseen_objects;
  unsigned         spare[2];
};

// static linker symbols to prevent wrong two level namespace for _Unwind symbols
#if __arm__
   #define NOT_HERE_BEFORE_5_0(sym)     \
       extern const char sym##_tmp30 __asm("$ld$hide$os3.0$_" #sym ); \
       __attribute__((visibility("default"))) const char sym##_tmp30 = 0; \
       extern const char sym##_tmp31 __asm("$ld$hide$os3.1$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp31 = 0; \
       extern const char sym##_tmp32 __asm("$ld$hide$os3.2$_" #sym );\
           __attribute__((visibility("default"))) const char sym##_tmp32 = 0; \
       extern const char sym##_tmp40 __asm("$ld$hide$os4.0$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp40 = 0; \
       extern const char sym##_tmp41 __asm("$ld$hide$os4.1$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp41 = 0; \
       extern const char sym##_tmp42 __asm("$ld$hide$os4.2$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp42 = 0; \
       extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp43 = 0;
#elif __arm64__
  #define NOT_HERE_BEFORE_10_6(sym)
  #define NEVER_HERE(sym)
#else
  #define NOT_HERE_BEFORE_10_6(sym) \
    extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
    extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
  #define NEVER_HERE(sym) \
    extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
    extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp5 = 0; \
    extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp6 = 0;
#endif

#if _LIBUNWIND_BUILD_ZERO_COST_APIS

//
// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in
// earlier versions
//
NOT_HERE_BEFORE_10_6(_Unwind_DeleteException)
NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE)
NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind)
NOT_HERE_BEFORE_10_6(_Unwind_GetGR)
NOT_HERE_BEFORE_10_6(_Unwind_GetIP)
NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData)
NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart)
NOT_HERE_BEFORE_10_6(_Unwind_RaiseException)
NOT_HERE_BEFORE_10_6(_Unwind_Resume)
NOT_HERE_BEFORE_10_6(_Unwind_SetGR)
NOT_HERE_BEFORE_10_6(_Unwind_SetIP)
NOT_HERE_BEFORE_10_6(_Unwind_Backtrace)
NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction)
NOT_HERE_BEFORE_10_6(_Unwind_GetCFA)
NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase)
NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase)
NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow)
NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo)
NOT_HERE_BEFORE_10_6(__register_frame)
NOT_HERE_BEFORE_10_6(__deregister_frame)

//
// symbols in libSystem.dylib for compatibility, but we don't want any new code
// using them
//
NEVER_HERE(__register_frame_info_bases)
NEVER_HERE(__register_frame_info)
NEVER_HERE(__register_frame_info_table_bases)
NEVER_HERE(__register_frame_info_table)
NEVER_HERE(__register_frame_table)
NEVER_HERE(__deregister_frame_info)
NEVER_HERE(__deregister_frame_info_bases)

#endif // _LIBUNWIND_BUILD_ZERO_COST_APIS

#if _LIBUNWIND_BUILD_SJLJ_APIS
//
// symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in
// earlier versions
//
NOT_HERE_BEFORE_5_0(_Unwind_GetLanguageSpecificData)
NOT_HERE_BEFORE_5_0(_Unwind_GetRegionStart)
NOT_HERE_BEFORE_5_0(_Unwind_GetIP)
NOT_HERE_BEFORE_5_0(_Unwind_SetGR)
NOT_HERE_BEFORE_5_0(_Unwind_SetIP)
NOT_HERE_BEFORE_5_0(_Unwind_DeleteException)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Register)
NOT_HERE_BEFORE_5_0(_Unwind_GetGR)
NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo)
NOT_HERE_BEFORE_5_0(_Unwind_GetCFA)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister)

#endif // _LIBUNWIND_BUILD_SJLJ_APIS

namespace libunwind {

_LIBUNWIND_HIDDEN
bool checkKeyMgrRegisteredFDEs(uintptr_t pc, void *&fde) {
#if __MAC_OS_X_VERSION_MIN_REQUIRED
  // lastly check for old style keymgr registration of dynamically generated
  // FDEs acquire exclusive access to libgcc_object_info
  libgcc_object_info *head = (libgcc_object_info *)
                _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST);
  if (head != NULL) {
    // look at each FDE in keymgr
    for (libgcc_object *ob = head->unseen_objects; ob != NULL; ob = ob->next) {
      CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
      CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
      const char *msg = CFI_Parser<LocalAddressSpace>::decodeFDE(
                                      LocalAddressSpace::sThisAddressSpace,
                                      (uintptr_t)ob->fde, &fdeInfo, &cieInfo);
      if (msg == NULL) {
        // Check if this FDE is for a function that includes the pc
        if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
          fde = (void*)fdeInfo.pcStart;
          _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST,
                                                 head);
          return true;
        }
      }
    }
  }
  // release libgcc_object_info
  _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, head);
#else
  (void)pc;
  (void)fde;
#endif
  return false;
}

}

#if !FOR_DYLD && _LIBUNWIND_BUILD_SJLJ_APIS

#include <System/pthread_machdep.h>

// Accessors to get get/set linked list of frames for sjlj based execeptions.
_LIBUNWIND_HIDDEN
struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() {
  return (struct _Unwind_FunctionContext *)
    _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key);
}

_LIBUNWIND_HIDDEN
void __Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext *fc) {
  _pthread_setspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key, fc);
}
#endif

<|endoftext|>


<commit_before>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "bsecxxutils.hh"
#include "bsecxxbase.hh"
#include "bsecategories.hh"
#include <list>
using namespace std;    // FIXME

namespace Bse {

struct TypeRegistry::TypeEntry {
  guint               instance_size;
  const gchar        *name;
  const gchar        *parent;
  const ClassInfo    *cinfo;
  GBaseInitFunc       binit;
  GClassInitFunc      cinit;
  GInstanceInitFunc   iinit;
  TypeRegistry::Flags flags;
  TypeRegistry       *reg;
  /*Con*/ TypeEntry (guint               instance_size,
                     const gchar        *name,
                     const gchar        *parent,
                     const ClassInfo    *cinfo,
                     GBaseInitFunc       binit,
                     GClassInitFunc      cinit,
                     GInstanceInitFunc   iinit,
                     TypeRegistry::Flags flags)
    : reg (NULL)
  {
    this->instance_size = instance_size;
    this->name = name;
    this->parent = parent;
    this->cinfo = cinfo;
    this->binit = binit;
    this->cinit = cinit;
    this->iinit = iinit;
    this->flags = flags;
  }
};

static list<TypeRegistry::TypeEntry> *type_entries = NULL;

TypeRegistry::TypeRegistry (guint             instance_size,
                            const gchar      *name,
                            const gchar      *parent,
                            const ClassInfo  *cinfo,
                            GBaseInitFunc     binit,
                            void            (*class_init) (CxxBaseClass*),
                            GInstanceInitFunc iinit,
                            Flags             flags)
  : gtype_id (0)
{
  TypeEntry entry (instance_size, name, parent, cinfo, binit,
                   (GClassInitFunc) class_init,
                   iinit, flags);
  entry.reg = this;

  if (!type_entries)
    type_entries = new list<TypeEntry>();

  list<TypeEntry>::iterator li;
  for (li = type_entries->begin(); li != type_entries->end(); li++)
    if (strcmp (li->name, parent) == 0)
      break;
  if (li != type_entries->end())
    type_entries->insert (++li, entry);
  else  // parent not found in list
    type_entries->push_front (entry);
}

void
TypeRegistry::init_types()
{
  for (list<TypeEntry>::iterator li = type_entries->begin (); li != type_entries->end (); li++)
    {
      TypeRegistry *self = li->reg;
      GTypeInfo info = { 0, };

      info.class_size = BSE_CXX_COMMON_CLASS_SIZE;
      info.base_init = li->binit;
      info.class_init = li->cinit;
      info.instance_size = BSE_CXX_INSTANCE_OFFSET + li->instance_size;
      info.instance_init = li->iinit;
      self->gtype_id = g_type_register_static (g_type_from_name (li->parent),
                                               li->name, &info, (GTypeFlags) li->flags);
      if (li->cinfo)
        {
          if (li->cinfo->category)
            bse_categories_register (li->cinfo->category, NULL, self->gtype_id, NULL);
          if (li->cinfo->blurb)
            bse_type_add_blurb (self->gtype_id, li->cinfo->blurb, li->cinfo->file, li->cinfo->line);
        }
    }
  delete type_entries;
  type_entries = NULL;
}

extern "C" void
bse_cxx_init (void)  // prototyped in bseutils.hh
{
  // FIXME: delete: init_exception_handler ();
  Bse::TypeRegistry::init_types();
}

} // Bse
<commit_msg>BSE: fix bse_cxx_init namespace<commit_after>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "bsecxxutils.hh"
#include "bsecxxbase.hh"
#include "bsecategories.hh"
#include <list>
using namespace std;    // FIXME

namespace Bse {

struct TypeRegistry::TypeEntry {
  guint               instance_size;
  const gchar        *name;
  const gchar        *parent;
  const ClassInfo    *cinfo;
  GBaseInitFunc       binit;
  GClassInitFunc      cinit;
  GInstanceInitFunc   iinit;
  TypeRegistry::Flags flags;
  TypeRegistry       *reg;
  /*Con*/ TypeEntry (guint               instance_size,
                     const gchar        *name,
                     const gchar        *parent,
                     const ClassInfo    *cinfo,
                     GBaseInitFunc       binit,
                     GClassInitFunc      cinit,
                     GInstanceInitFunc   iinit,
                     TypeRegistry::Flags flags)
    : reg (NULL)
  {
    this->instance_size = instance_size;
    this->name = name;
    this->parent = parent;
    this->cinfo = cinfo;
    this->binit = binit;
    this->cinit = cinit;
    this->iinit = iinit;
    this->flags = flags;
  }
};

static list<TypeRegistry::TypeEntry> *type_entries = NULL;

TypeRegistry::TypeRegistry (guint             instance_size,
                            const gchar      *name,
                            const gchar      *parent,
                            const ClassInfo  *cinfo,
                            GBaseInitFunc     binit,
                            void            (*class_init) (CxxBaseClass*),
                            GInstanceInitFunc iinit,
                            Flags             flags)
  : gtype_id (0)
{
  TypeEntry entry (instance_size, name, parent, cinfo, binit,
                   (GClassInitFunc) class_init,
                   iinit, flags);
  entry.reg = this;

  if (!type_entries)
    type_entries = new list<TypeEntry>();

  list<TypeEntry>::iterator li;
  for (li = type_entries->begin(); li != type_entries->end(); li++)
    if (strcmp (li->name, parent) == 0)
      break;
  if (li != type_entries->end())
    type_entries->insert (++li, entry);
  else  // parent not found in list
    type_entries->push_front (entry);
}

void
TypeRegistry::init_types()
{
  for (list<TypeEntry>::iterator li = type_entries->begin (); li != type_entries->end (); li++)
    {
      TypeRegistry *self = li->reg;
      GTypeInfo info = { 0, };

      info.class_size = BSE_CXX_COMMON_CLASS_SIZE;
      info.base_init = li->binit;
      info.class_init = li->cinit;
      info.instance_size = BSE_CXX_INSTANCE_OFFSET + li->instance_size;
      info.instance_init = li->iinit;
      self->gtype_id = g_type_register_static (g_type_from_name (li->parent),
                                               li->name, &info, (GTypeFlags) li->flags);
      if (li->cinfo)
        {
          if (li->cinfo->category)
            bse_categories_register (li->cinfo->category, NULL, self->gtype_id, NULL);
          if (li->cinfo->blurb)
            bse_type_add_blurb (self->gtype_id, li->cinfo->blurb, li->cinfo->file, li->cinfo->line);
        }
    }
  delete type_entries;
  type_entries = NULL;
}

} // Bse

extern "C" void
bse_cxx_init (void)  // prototyped in bseutils.hh
{
  // FIXME: delete: init_exception_handler ();
  Bse::TypeRegistry::init_types();
}
<|endoftext|>


<commit_before>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#ifndef __BSE_CXX_UTILS_H__
#define __BSE_CXX_UTILS_H__
#include <bse/bseutils.hh>
#include <sfi/sficxx.hh>
#include <vector>
#include <algorithm>
namespace Bse {

/// The Procedure namespace contains procedure/IDL helpers.
namespace Procedure {
typedef SfiBool     Bool;
typedef SfiInt      Int;
typedef SfiNum      Num;
typedef SfiTime     Time;
typedef SfiNote     Note;
typedef SfiReal     Real;
typedef SfiChoice   Choice;
typedef std::string String;
typedef SfiBBlock   BBlock;
typedef SfiFBlock   FBlock;
typedef SfiSeq      Seq;
typedef SfiRec      Rec;
typedef SfiProxy    Proxy;
};

/* --- type alias frequently used standard lib things --- */
typedef std::string String;

/* --- generally useful templates --- */
template<class Data> static void
delete_this (Data *d)
{
  delete d;
}
/* check derivation of Derived from Base */
template<class Derived, class Base>     // ex: EnforceDerivedFrom<Child, Base> assertion;
struct EnforceDerivedFrom {
  EnforceDerivedFrom (Derived *derived = 0,
                      Base    *base = 0)
  {
    base = derived;
  }
};
/* check derivation of Derived* from Base* */
template<class Derived, class Base>     // ex: EnforceDerivedFrom<Child*, Base*> assertion;
struct EnforceDerivedFrom<Derived*, Base*> {
  EnforceDerivedFrom (Derived *derived = 0,
                      Base    *base = 0)
  {
    base = derived;
  }
};
/* check derivation through EnforceDerivedFrom<>; */
template<class Derived, class Base> void
assert_derived_from (void)
{
  EnforceDerivedFrom<Derived, Base> assertion;
}

/* --- exceptions --- */
struct Exception : std::exception {
  explicit Exception (const char *_where) : loc (_where) {};
  virtual const char* where() { return loc; }
private:
  const char *loc;
};
struct InvalidArgument2 : Exception {
  const char *item;
  InvalidArgument2 (const char *where, const char *item) : Exception (where), item (item) {};
  const char* what() const throw() { return g_intern_strconcat ("invalid argument: ", item, NULL); }
};
#define InvalidArgument(WHAT)   InvalidArgument2 (__func__, #WHAT)
struct WrongTypeGValue : Exception {
  WrongTypeGValue (const char *where) : Exception (where) {};
  const char* what() const throw() { return "GValue contains wrong type for this kind of use"; }
};
struct DontReach : Exception {
  DontReach (const char *where) : Exception (where) {};
  const char* what() const throw() { return "Code section should not be reached"; }
};
struct InvalidConnection : Exception {
  InvalidConnection (const char *where) : Exception (where) {};
  const char* what() const throw() { return "Function to be connected has invalid signature"; }
};

/* --- records & sequences --- */
class Record {
  Record&          operator= (const Record&);
  explicit         Record    (const Record&);
public:
  explicit         Record    ();
  virtual SfiRec*  to_rec    ();
  virtual         ~Record    ();
};

/* --- class registration --- */
#define BSE_CXX_TYPE_REGISTER(ObjectType, parent, class_info)          \
          BSE_CXX_TYPE_REGISTER_INITIALIZED (ObjectType, parent, class_info, NULL, TypeRegistry::NONE)
#define BSE_CXX_TYPE_REGISTER_ABSTRACT(ObjectType, parent, class_info) \
          BSE_CXX_TYPE_REGISTER_INTERN (ObjectType, parent, class_info, NULL, NULL, TypeRegistry::ABSTRACT)

/* --- class information --- */
struct ClassInfo
{
  const char *category;
  const char *blurb;
  const char *file;
  int         line;
  ClassInfo (const char *category,
             const char *blurb,
             const char *file,
             int         line)
  {
    this->category = category;
    this->blurb = blurb;
    this->file = file;
    this->line = line;
  }
};

/* --- type registration internals --- */
struct CxxBaseClass;
class TypeRegistry
{
  GType gtype_id;
public:
  enum Flags {
    NONE        = 0,
    ABSTRACT    = G_TYPE_FLAG_ABSTRACT
  };
  TypeRegistry (guint             instance_size,
                const gchar      *name,
                const gchar      *parent,
                const ClassInfo  *cinfo,
                GBaseInitFunc     binit,
                void            (*class_init) (CxxBaseClass*),
                GInstanceInitFunc iinit,
                Flags             flags);
  const GType
  get_type () const
  {
    return gtype_id;
  }
  static void
  init_types ();
  struct TypeEntry;
};

template<class C> const GType
bse_type_id_wrapper (const char *type_name)
{
  static GType type = 0;
  if (!type)
    {
      type = g_type_from_name (type_name);
      RAPICORN_ASSERT (type);
    }
  return type;
}

#define BSE_CXX_TYPE_GET_REGISTERED(NameSpace, ObjectType) \
  (::Bse::bse_type_id_wrapper<ObjectType> (#NameSpace #ObjectType))
#define BSE_CXX_TYPE_REGISTER_INITIALIZED(ObjectType, parent, cinfo, binit, flags) \
  BSE_CXX_TYPE_REGISTER_INTERN (ObjectType, parent, cinfo, binit,                  \
                                ::Bse::cxx_instance_init_trampoline<ObjectType>, flags)
#define BSE_CXX_TYPE_REGISTER_INTERN(ObjectType, parent, cinfo, binit, iinit, flags) \
  static Bse::TypeRegistry                                                      \
    ObjectType ## _type_keeper (sizeof (ObjectType), "Bse" #ObjectType, parent, \
                                cinfo, binit,                                   \
                                ::Bse::cxx_class_init_trampoline<ObjectType>,   \
                                iinit, flags);
#define BSE_CXX_UTILS_ALIGNMENT         (2 * sizeof (gsize))
#define BSE_CXX_UTILS_ALIGN(offset)     ((offset + BSE_CXX_UTILS_ALIGNMENT - 1) & -BSE_CXX_UTILS_ALIGNMENT)
#define BSE_CXX_SIZEOF(Class)           BSE_CXX_UTILS_ALIGN (sizeof (Class))
#define BSE_CXX_COMMON_CLASS_SIZE       sizeof (CxxBaseClass)

} // Bse

#endif /* __BSE_CXX_UTILS_H__ */
<commit_msg>BSE: use noexcept instead of dynamic exception specifications<commit_after>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#ifndef __BSE_CXX_UTILS_H__
#define __BSE_CXX_UTILS_H__
#include <bse/bseutils.hh>
#include <sfi/sficxx.hh>
#include <vector>
#include <algorithm>
namespace Bse {

/// The Procedure namespace contains procedure/IDL helpers.
namespace Procedure {
typedef SfiBool     Bool;
typedef SfiInt      Int;
typedef SfiNum      Num;
typedef SfiTime     Time;
typedef SfiNote     Note;
typedef SfiReal     Real;
typedef SfiChoice   Choice;
typedef std::string String;
typedef SfiBBlock   BBlock;
typedef SfiFBlock   FBlock;
typedef SfiSeq      Seq;
typedef SfiRec      Rec;
typedef SfiProxy    Proxy;
};

/* --- type alias frequently used standard lib things --- */
typedef std::string String;

/* --- generally useful templates --- */
template<class Data> static void
delete_this (Data *d)
{
  delete d;
}
/* check derivation of Derived from Base */
template<class Derived, class Base>     // ex: EnforceDerivedFrom<Child, Base> assertion;
struct EnforceDerivedFrom {
  EnforceDerivedFrom (Derived *derived = 0,
                      Base    *base = 0)
  {
    base = derived;
  }
};
/* check derivation of Derived* from Base* */
template<class Derived, class Base>     // ex: EnforceDerivedFrom<Child*, Base*> assertion;
struct EnforceDerivedFrom<Derived*, Base*> {
  EnforceDerivedFrom (Derived *derived = 0,
                      Base    *base = 0)
  {
    base = derived;
  }
};
/* check derivation through EnforceDerivedFrom<>; */
template<class Derived, class Base> void
assert_derived_from (void)
{
  EnforceDerivedFrom<Derived, Base> assertion;
}

/* --- exceptions --- */
struct Exception : std::exception {
  explicit Exception (const char *_where) : loc (_where) {};
  virtual const char* where() { return loc; }
private:
  const char *loc;
};
struct InvalidArgument2 : Exception {
  const char *item;
  InvalidArgument2 (const char *where, const char *item) : Exception (where), item (item) {};
  const char* what() const noexcept { return g_intern_strconcat ("invalid argument: ", item, NULL); }
};
#define InvalidArgument(WHAT)   InvalidArgument2 (__func__, #WHAT)
struct WrongTypeGValue : Exception {
  WrongTypeGValue (const char *where) : Exception (where) {};
  const char* what() const noexcept { return "GValue contains wrong type for this kind of use"; }
};
struct DontReach : Exception {
  DontReach (const char *where) : Exception (where) {};
  const char* what() const noexcept { return "Code section should not be reached"; }
};
struct InvalidConnection : Exception {
  InvalidConnection (const char *where) : Exception (where) {};
  const char* what() const noexcept { return "Function to be connected has invalid signature"; }
};

/* --- records & sequences --- */
class Record {
  Record&          operator= (const Record&);
  explicit         Record    (const Record&);
public:
  explicit         Record    ();
  virtual SfiRec*  to_rec    ();
  virtual         ~Record    ();
};

/* --- class registration --- */
#define BSE_CXX_TYPE_REGISTER(ObjectType, parent, class_info)          \
          BSE_CXX_TYPE_REGISTER_INITIALIZED (ObjectType, parent, class_info, NULL, TypeRegistry::NONE)
#define BSE_CXX_TYPE_REGISTER_ABSTRACT(ObjectType, parent, class_info) \
          BSE_CXX_TYPE_REGISTER_INTERN (ObjectType, parent, class_info, NULL, NULL, TypeRegistry::ABSTRACT)

/* --- class information --- */
struct ClassInfo
{
  const char *category;
  const char *blurb;
  const char *file;
  int         line;
  ClassInfo (const char *category,
             const char *blurb,
             const char *file,
             int         line)
  {
    this->category = category;
    this->blurb = blurb;
    this->file = file;
    this->line = line;
  }
};

/* --- type registration internals --- */
struct CxxBaseClass;
class TypeRegistry
{
  GType gtype_id;
public:
  enum Flags {
    NONE        = 0,
    ABSTRACT    = G_TYPE_FLAG_ABSTRACT
  };
  TypeRegistry (guint             instance_size,
                const gchar      *name,
                const gchar      *parent,
                const ClassInfo  *cinfo,
                GBaseInitFunc     binit,
                void            (*class_init) (CxxBaseClass*),
                GInstanceInitFunc iinit,
                Flags             flags);
  const GType
  get_type () const
  {
    return gtype_id;
  }
  static void
  init_types ();
  struct TypeEntry;
};

template<class C> const GType
bse_type_id_wrapper (const char *type_name)
{
  static GType type = 0;
  if (!type)
    {
      type = g_type_from_name (type_name);
      RAPICORN_ASSERT (type);
    }
  return type;
}

#define BSE_CXX_TYPE_GET_REGISTERED(NameSpace, ObjectType) \
  (::Bse::bse_type_id_wrapper<ObjectType> (#NameSpace #ObjectType))
#define BSE_CXX_TYPE_REGISTER_INITIALIZED(ObjectType, parent, cinfo, binit, flags) \
  BSE_CXX_TYPE_REGISTER_INTERN (ObjectType, parent, cinfo, binit,                  \
                                ::Bse::cxx_instance_init_trampoline<ObjectType>, flags)
#define BSE_CXX_TYPE_REGISTER_INTERN(ObjectType, parent, cinfo, binit, iinit, flags) \
  static Bse::TypeRegistry                                                      \
    ObjectType ## _type_keeper (sizeof (ObjectType), "Bse" #ObjectType, parent, \
                                cinfo, binit,                                   \
                                ::Bse::cxx_class_init_trampoline<ObjectType>,   \
                                iinit, flags);
#define BSE_CXX_UTILS_ALIGNMENT         (2 * sizeof (gsize))
#define BSE_CXX_UTILS_ALIGN(offset)     ((offset + BSE_CXX_UTILS_ALIGNMENT - 1) & -BSE_CXX_UTILS_ALIGNMENT)
#define BSE_CXX_SIZEOF(Class)           BSE_CXX_UTILS_ALIGN (sizeof (Class))
#define BSE_CXX_COMMON_CLASS_SIZE       sizeof (CxxBaseClass)

} // Bse

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


<commit_before>#include <utils.h>
#include "command.h"
#include "../CommandHandler.h"
#include "../option.h"
#include "../stringparse.h"

/* full name of the command */
_CMDNAME("delrec");
/* description of the command */
_CMDDESCR("delete a recurring message");
/* command usage synopsis */
_CMDUSAGE("$delrec ID");

/* delrec: delete a recurring message */
std::string CommandHandler::delrec(char *out, struct command *c)
{
	int opt, all;
	size_t i;
	int64_t id;
	static struct option long_opts[] = {
		{ "all", NO_ARG, 'a' },
		{ "help", NO_ARG, 'h' },
		{ 0, 0, 0 }
	};

	if (!P_ALMOD(c->privileges)) {
		PERM_DENIED(out, c->nick, c->argv[0]);
		return "";
	}

	opt_init();
	all = 0;
	while ((opt = getopt_long(c->argc, c->argv, "a", long_opts)) != EOF) {
		switch (opt) {
		case 'a':
			all = 1;
			break;
		case 'h':
			_HELPMSG(out, _CMDNAME, _CMDUSAGE, _CMDDESCR);
			return "";
		case '?':
			_sprintf(out, MAX_MSG, "%s", opterr());
			return "";
		default:
			return "";
		}
	}

	if (all) {
		if (optind != c->argc) {
			_USAGEMSG(out, _CMDNAME, _CMDUSAGE);
			return "";
		}
		for (i = 0; i < m_evtp->messages()->size(); ++i)
			m_evtp->delMessage(1);
		_sprintf(out, MAX_MSG, "@%s, all recurring message deleted",
				c->nick);
		return "";
	}

	if ((optind != c->argc - 1)) {
		_USAGEMSG(out, _CMDNAME, _CMDUSAGE);
		return "";
	}

	if (!parsenum(c->argv[optind], &id)) {
		_sprintf(out, MAX_MSG, "%s: invalid number: %s",
				c->argv[0], c->argv[optind]);
		return "";
	}

	if (!m_evtp->delMessage(id))
		_sprintf(out, MAX_MSG, "%s: invalid ID provided", c->argv[0]);
	else
		_sprintf(out, MAX_MSG, "@%s, recurring message %ld deleted.",
				c->nick, id);
	return "";
}
<commit_msg>delrec all fix<commit_after>#include <utils.h>
#include "command.h"
#include "../CommandHandler.h"
#include "../option.h"
#include "../stringparse.h"

/* full name of the command */
_CMDNAME("delrec");
/* description of the command */
_CMDDESCR("delete a recurring message");
/* command usage synopsis */
_CMDUSAGE("$delrec ID");

/* delrec: delete a recurring message */
std::string CommandHandler::delrec(char *out, struct command *c)
{
	int opt, all;
	size_t i;
	int64_t id;
	static struct option long_opts[] = {
		{ "all", NO_ARG, 'a' },
		{ "help", NO_ARG, 'h' },
		{ 0, 0, 0 }
	};

	if (!P_ALMOD(c->privileges)) {
		PERM_DENIED(out, c->nick, c->argv[0]);
		return "";
	}

	opt_init();
	all = 0;
	while ((opt = getopt_long(c->argc, c->argv, "a", long_opts)) != EOF) {
		switch (opt) {
		case 'a':
			all = 1;
			break;
		case 'h':
			_HELPMSG(out, _CMDNAME, _CMDUSAGE, _CMDDESCR);
			return "";
		case '?':
			_sprintf(out, MAX_MSG, "%s", opterr());
			return "";
		default:
			return "";
		}
	}

	if (all) {
		if (optind != c->argc) {
			_USAGEMSG(out, _CMDNAME, _CMDUSAGE);
			return "";
		}
		while (!m_evtp->messages()->empty())
			m_evtp->delMessage(1);
		_sprintf(out, MAX_MSG, "@%s, all recurring message deleted",
				c->nick);
		return "";
	}

	if ((optind != c->argc - 1)) {
		_USAGEMSG(out, _CMDNAME, _CMDUSAGE);
		return "";
	}

	if (!parsenum(c->argv[optind], &id)) {
		_sprintf(out, MAX_MSG, "%s: invalid number: %s",
				c->argv[0], c->argv[optind]);
		return "";
	}

	if (!m_evtp->delMessage(id))
		_sprintf(out, MAX_MSG, "%s: invalid ID provided", c->argv[0]);
	else
		_sprintf(out, MAX_MSG, "@%s, recurring message %ld deleted.",
				c->nick, id);
	return "";
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 - 2013 Leap Motion. All rights reserved. Proprietary and confidential.
#include "stdafx.h"
#include "CoreThread.h"
#include <Windows.h>

typedef struct tagTHREADNAME_INFO
{
   DWORD dwType; // must be 0x1000
   LPCSTR szName; // pointer to name (in user addr space)
   DWORD dwThreadID; // thread ID (-1=caller thread)
   DWORD dwFlags; // reserved for future use, must be zero
} THREADNAME_INFO;

void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
{
  THREADNAME_INFO info;
  info.dwType = 0x1000;
  info.szName = szThreadName;
  info.dwThreadID = dwThreadID;
  info.dwFlags = 0;

  __try
  {
    // Magic exception which informs the OS of this thread's name
    RaiseException(0x406D1388, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR*)&info);
  }
  __except(EXCEPTION_CONTINUE_EXECUTION)
  {
  }
}

void CoreThread::SetCurrentThreadName(void) const {
#if IS_INTERNAL_BUILD
  ::SetThreadName(
    GetCurrentThreadId(),
    m_name
  );
#endif
}
<commit_msg>Adding pack guards to try to get thread naming working in 64-bit<commit_after>// Copyright (c) 2010 - 2013 Leap Motion. All rights reserved. Proprietary and confidential.
#include "stdafx.h"
#include "CoreThread.h"
#include <Windows.h>

#pragma pack(push, 8)
typedef struct tagTHREADNAME_INFO
{
   DWORD dwType; // must be 0x1000
   LPCSTR szName; // pointer to name (in user addr space)
   DWORD dwThreadID; // thread ID (-1=caller thread)
   DWORD dwFlags; // reserved for future use, must be zero
} THREADNAME_INFO;
#pragma pack(pop)

void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
{
  THREADNAME_INFO info;
  info.dwType = 0x1000;
  info.szName = szThreadName;
  info.dwThreadID = dwThreadID;
  info.dwFlags = 0;

  __try
  {
    // Magic exception which informs the OS of this thread's name
    RaiseException(0x406D1388, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR*)&info);
  }
  __except(EXCEPTION_CONTINUE_EXECUTION)
  {
  }
}

void CoreThread::SetCurrentThreadName(void) const {
#if IS_INTERNAL_BUILD
  ::SetThreadName(
    GetCurrentThreadId(),
    m_name
  );
#endif
}
<|endoftext|>


<commit_before>#include "Daemon.h"

#ifndef _WIN32

#include <signal.h>
#include <stdlib.h>
#include <thread>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "Config.h"
#include "FS.h"
#include "Log.h"

void handle_signal(int sig)
{
	switch (sig)
	{
		case SIGHUP:
			LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening log...");
			i2p::log::Logger().Reopen ();
		break;
		case SIGINT:
			Daemon.gracefullShutdownInterval = 10*60; // 10 minutes
			LogPrint(eLogInfo, "Graceful shutdown after ", Daemon.gracefullShutdownInterval, " seconds");
		break;
		case SIGABRT:
		case SIGTERM:
			Daemon.running = 0; // Exit loop
		break;
	}
}

namespace i2p
{
	namespace util
	{
		bool DaemonLinux::start()
		{
			if (isDaemon == 1)
			{
				pid_t pid;
				pid = fork();
				if (pid > 0) // parent
					::exit (EXIT_SUCCESS);

				if (pid < 0) // error
				{
					LogPrint(eLogError, "Daemon: could not fork: ", strerror(errno));
					return false;
				}

				// child
				umask(S_IWGRP | S_IRWXO); // 0027
				int sid = setsid();
				if (sid < 0)
				{
					LogPrint(eLogError, "Daemon: could not create process group.");
					return false;
				}
				std::string d = i2p::fs::GetDataDir();
				if (chdir(d.c_str()) != 0)
				{
					LogPrint(eLogError, "Daemon: could not chdir: ", strerror(errno));
					return false;
				}

				// close stdin/stdout/stderr descriptors
				freopen("/dev/null", "r", stdin);
				freopen("/dev/null", "w", stdout);
				freopen("/dev/null", "w", stderr);
			}

			// Pidfile
			// this code is c-styled and a bit ugly, but we need fd for locking pidfile
			std::string pidfile; i2p::config::GetOption("pidfile", pidfile);
			if (pidfile == "") {
				pidfile = i2p::fs::DataDirPath("i2pd.pid");
			}
			if (pidfile != "") {
				pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600);
				if (pidFH < 0)
				{
					LogPrint(eLogError, "Daemon: could not create pid file ", pidfile, ": ", strerror(errno));
					return false;
				}
				if (lockf(pidFH, F_TLOCK, 0) != 0)
				{
					LogPrint(eLogError, "Daemon: could not lock pid file ", pidfile, ": ", strerror(errno));
					return false;
				}
				char pid[10];
				sprintf(pid, "%d\n", getpid());
				ftruncate(pidFH, 0);
				if (write(pidFH, pid, strlen(pid)) < 0)
				{
					LogPrint(eLogError, "Daemon: could not write pidfile: ", strerror(errno));
					return false;
				}
			}
			gracefullShutdownInterval = 0; // not specified

			// Signal handler
			struct sigaction sa;
			sa.sa_handler = handle_signal;
			sigemptyset(&sa.sa_mask);
			sa.sa_flags = SA_RESTART;
			sigaction(SIGHUP, &sa, 0);
			sigaction(SIGABRT, &sa, 0);
			sigaction(SIGTERM, &sa, 0);
			sigaction(SIGINT, &sa, 0);

			return Daemon_Singleton::start();
		}

		bool DaemonLinux::stop()
		{
			i2p::fs::Remove(pidfile);

			return Daemon_Singleton::stop();
		}

		void DaemonLinux::run ()
		{
			while (running)
			{
				std::this_thread::sleep_for (std::chrono::seconds(1));
				if (gracefullShutdownInterval)
				{
					gracefullShutdownInterval--; // - 1 second
					if (gracefullShutdownInterval <= 0)
					{
						LogPrint(eLogInfo, "Graceful shutdown");
						return;
					}
				}
			}
		}
	}
}

#endif
<commit_msg>graceful shutdown by SIGINT<commit_after>#include "Daemon.h"

#ifndef _WIN32

#include <signal.h>
#include <stdlib.h>
#include <thread>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#include "Config.h"
#include "FS.h"
#include "Log.h"
#include "RouterContext.h"

void handle_signal(int sig)
{
	switch (sig)
	{
		case SIGHUP:
			LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening log...");
			i2p::log::Logger().Reopen ();
		break;
		case SIGINT:
			i2p::context.SetAcceptsTunnels (false);
			Daemon.gracefullShutdownInterval = 10*60; // 10 minutes
			LogPrint(eLogInfo, "Graceful shutdown after ", Daemon.gracefullShutdownInterval, " seconds");
		break;
		case SIGABRT:
		case SIGTERM:
			Daemon.running = 0; // Exit loop
		break;
	}
}

namespace i2p
{
	namespace util
	{
		bool DaemonLinux::start()
		{
			if (isDaemon == 1)
			{
				pid_t pid;
				pid = fork();
				if (pid > 0) // parent
					::exit (EXIT_SUCCESS);

				if (pid < 0) // error
				{
					LogPrint(eLogError, "Daemon: could not fork: ", strerror(errno));
					return false;
				}

				// child
				umask(S_IWGRP | S_IRWXO); // 0027
				int sid = setsid();
				if (sid < 0)
				{
					LogPrint(eLogError, "Daemon: could not create process group.");
					return false;
				}
				std::string d = i2p::fs::GetDataDir();
				if (chdir(d.c_str()) != 0)
				{
					LogPrint(eLogError, "Daemon: could not chdir: ", strerror(errno));
					return false;
				}

				// close stdin/stdout/stderr descriptors
				freopen("/dev/null", "r", stdin);
				freopen("/dev/null", "w", stdout);
				freopen("/dev/null", "w", stderr);
			}

			// Pidfile
			// this code is c-styled and a bit ugly, but we need fd for locking pidfile
			std::string pidfile; i2p::config::GetOption("pidfile", pidfile);
			if (pidfile == "") {
				pidfile = i2p::fs::DataDirPath("i2pd.pid");
			}
			if (pidfile != "") {
				pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600);
				if (pidFH < 0)
				{
					LogPrint(eLogError, "Daemon: could not create pid file ", pidfile, ": ", strerror(errno));
					return false;
				}
				if (lockf(pidFH, F_TLOCK, 0) != 0)
				{
					LogPrint(eLogError, "Daemon: could not lock pid file ", pidfile, ": ", strerror(errno));
					return false;
				}
				char pid[10];
				sprintf(pid, "%d\n", getpid());
				ftruncate(pidFH, 0);
				if (write(pidFH, pid, strlen(pid)) < 0)
				{
					LogPrint(eLogError, "Daemon: could not write pidfile: ", strerror(errno));
					return false;
				}
			}
			gracefullShutdownInterval = 0; // not specified

			// Signal handler
			struct sigaction sa;
			sa.sa_handler = handle_signal;
			sigemptyset(&sa.sa_mask);
			sa.sa_flags = SA_RESTART;
			sigaction(SIGHUP, &sa, 0);
			sigaction(SIGABRT, &sa, 0);
			sigaction(SIGTERM, &sa, 0);
			sigaction(SIGINT, &sa, 0);

			return Daemon_Singleton::start();
		}

		bool DaemonLinux::stop()
		{
			i2p::fs::Remove(pidfile);

			return Daemon_Singleton::stop();
		}

		void DaemonLinux::run ()
		{
			while (running)
			{
				std::this_thread::sleep_for (std::chrono::seconds(1));
				if (gracefullShutdownInterval)
				{
					gracefullShutdownInterval--; // - 1 second
					if (gracefullShutdownInterval <= 0)
					{
						LogPrint(eLogInfo, "Graceful shutdown");
						return;
					}
				}
			}
		}
	}
}

#endif
<|endoftext|>


<commit_before>#include "Device_HM10.h"

void DeviceHM10::serialPrintf(const char *format, ...) {

  va_list args;
  char buffer[100];

  va_start (args, format);
  vsnprintf (buffer, sizeof(buffer), format, args);
  buffer[sizeof(buffer) - 1] = '\0';

  serial->print(buffer);
}

void DeviceHM10::removeBytes(int bLen) {

  buffer->removeBytes(bLen);
  checkConnectionStatus();
}

unsigned char DeviceHM10::getByte(unsigned int pos) {

  return buffer->getByte(pos);
}

unsigned char * DeviceHM10::getPayload() {

  return buffer->getPayload();
}

void DeviceHM10::dump(const char * msg, const unsigned char * payload, size_t len) {

  Serial.print(msg);

  for (unsigned int i = 0; i < len; i++) {
    char buf[4];
    snprintf(buf, sizeof(buf), "%.2X", payload[i]);
    Serial.print(buf);
  }

  Serial.println("");
}

bool DeviceHM10::isDeviceConnected() {

  return status == STATUS_CONNECTED || status == STATUS_DISCONNECTING;
}

bool DeviceHM10::checkConnectionStatus() {

  bool connectionStatus = DeviceHM10::isDeviceConnected();

  if (buffer->getLen() < 3) {
    int count = serial->readBytes(buffer->getPayload() + buffer->getLen(), 3);
    buffer->addByteCount(count);
    if (count < 3) {
      return connectionStatus;
    }
  }

  unsigned char * payload = buffer->getPayload();
  // OK+CONNX / OK+LOST
  if (payload[0] != 'O' || payload[1] != 'K' || payload[2] != '+') {
    return connectionStatus;
  }

  if (buffer->getLen() < 7) {
    int need = 8 - buffer->getLen();
    int count = serial->readBytes(buffer->getPayload() + buffer->getLen(), need);
    buffer->addByteCount(count);
    if (buffer->getLen() < 7) {
      return connectionStatus;
    }
  }

  if (buffer->getLen() > 7) {
    if ( memcmp(buffer->getPayload(), "OK+CONNE", 8) == 0 ||
         memcmp(buffer->getPayload(), "OK+CONNF", 8) == 0
       ) {

      if (status == STATUS_CONNECTING) {
        status = STATUS_INITIALIZING;
      }
      else {
        status = STATUS_DISCONNECTED;
      }
      buffer->removeBytes(8);
      return connectionStatus;
    }

    if (memcmp(buffer->getPayload(), "OK+CONNA", 8) == 0) {
      buffer->removeBytes(8);
      return connectionStatus;
    }
  }

  if (memcmp(buffer->getPayload(), "OK+CONN", 7) == 0) {
    buffer->removeBytes(7);
    newConnection = true;
    status = STATUS_CONNECTED;
    Serial.println("device connected");
    return true;
  }

  // BAD: assuming it is OK+LOST
  return reset("device disconnected");
}

bool DeviceHM10::hasBytes(unsigned int bytes) {

  if (buffer->hasBytes(bytes)) {
    return true;
  }

  int bAvailable = bytes - buffer->getLen();

  // do not loop - try to keep the buffer data queue small
  if (serial->available()) {
    if (bAvailable > buffer->getFreeLen()) {
      bAvailable = buffer->getFreeLen();
    }

    int total = serial->readBytes(buffer->getPayload() + buffer->getLen(), bAvailable);
    if (total > 0) {
      buffer->addByteCount(total);
    }
  }

  if (!checkConnectionStatus()) {
    return false;
  }

  if (buffer->hasBytes(bytes)) {
    return true;
  }

  return false;
}

void DeviceHM10::write(const unsigned char *payload, int len) {

  if (status != STATUS_CONNECTED) {
    return;
  }

  serial->write(payload, len);
}

bool DeviceHM10::reset(const char * message) {

  Serial.println(message);

  if (status == STATUS_DISCONNECTING) {
    status = STATUS_DISCONNECTED;
  }
  else {
    status = STATUS_INITIALIZING;
  }

  newConnection = false;
  serial->flush();
  buffer->reset();

  // purge serial buffer
  while (serial->available()) {
    int val = serial->read();
  }

  return false;
}

bool DeviceHM10::isNewConnection() {

  if (newConnection == true) {
    newConnection = false;
    return true;
  }

  return false;
}

bool DeviceHM10::isConnected() {

  if (status == STATUS_CONNECTED) {
    return true;
  }
  else if (status == STATUS_DISCONNECTED) {
    return false;
  }

  if (status == STATUS_INITIALIZING) {
    if (!sendCommand("CON", mac)) return false;
    status = STATUS_CONNECTING;
  }

  if (status == STATUS_DISCONNECTING) {
    // Empty AT command disconnects the device
    serial->print("AT");
  }

  return checkConnectionStatus();
}

bool DeviceHM10::sendCommand(const char *cmd, const char *value) {

  char buffer[40];
  char expected[40];
  int count = 0;

  while (count < 5) {
    delay(count * 100);
    count++;

    // purge serial buffer
    while (serial->available()) {
      int val = serial->read();
    }

    if (cmd == NULL || strlen(cmd) == 0) {
      serialPrintf("AT");
      snprintf(expected, sizeof(expected), "OK");
    }
    else {
      serialPrintf("AT+%s%s", cmd, value);

      if (value == NULL || strlen(value) == 0) {
        snprintf(expected, sizeof(expected), "OK+%s", cmd);
      }
      else if (cmd == "CON") {
        return true;
        //snprintf(expected, sizeof(expected), "OK+CONNA");
      }
      else {
        snprintf(expected, sizeof(expected), "OK+Set:%s", value);
      }
    }

    int total = serial->readBytes(buffer, strlen(expected));

    if (total >= 0) {
      // read extra bytes still in buffer
      while (serial->available() && (total < sizeof(buffer))) {
        buffer[total++] = serial->read();
      }

      buffer[total] = '\0';
    }

    if (total <= 0) {
      continue;
    }

    if (strcmp(buffer, expected) != 0) {
      Serial.print("command ");
      Serial.print(cmd);
      Serial.print(" failed: ");
      Serial.println(buffer);
      Serial.print("expected: ");
      Serial.println(expected);

      return false;
    }

    return true;
  }

  Serial.print("failed to get answer for command ");
  Serial.println(cmd);

  return false;
}

void DeviceHM10::connect() {

  if (status == STATUS_CONNECTED || status == STATUS_INITIALIZING || status == STATUS_CONNECTING) {
    return;
  }

  status = STATUS_INITIALIZING;
  // TODO: Do discovery
}

void DeviceHM10::disconnect() {

  if (status == STATUS_DISCONNECTED) {
    return;
  }

  status = STATUS_DISCONNECTING;
}

boolean DeviceHM10::initDevice() {
    if (!sendCommand("", "")) return false;
    if (!sendCommand("RENEW", "")) return false;
    if (!sendCommand("IMME", "1")) return false;
    if (!sendCommand("MODE", "1")) return false;
    if (!sendCommand("COMP", "1")) return false;
    if (!sendCommand("NOTI", "1")) return false;
    if (!sendCommand("UUID", "0x1800")) return false;
    if (!sendCommand("CHAR", "0x2A80")) return false;
    if (!sendCommand("ROLE", "1")) return false;
    delay(1000);

    return true;
}

void DeviceHM10::init() {

#if defined(HAVE_HWSERIAL1)
  serial = &Serial1;
#else
  //serial = new SoftwareSerial(TX_PIN, RX_PIN);
  serial = new AltSoftSerial(TX_PIN, RX_PIN);
#endif

  serial->begin(9600);

  while (!initDevice()) {
  }
}

DeviceHM10::DeviceHM10() {

  buffer = new Buffer();
  newConnection = false;
  status = STATUS_DISCONNECTED;
}

DeviceHM10::~DeviceHM10() {

  delete(buffer);
}

<commit_msg>Fix Arduino connect/disconnect<commit_after>#include "Device_HM10.h"

void DeviceHM10::serialPrintf(const char *format, ...) {

  va_list args;
  char buffer[100];

  va_start (args, format);
  vsnprintf (buffer, sizeof(buffer), format, args);
  buffer[sizeof(buffer) - 1] = '\0';

  serial->print(buffer);
}

void DeviceHM10::removeBytes(int bLen) {

  buffer->removeBytes(bLen);
  checkConnectionStatus();
}

unsigned char DeviceHM10::getByte(unsigned int pos) {

  return buffer->getByte(pos);
}

unsigned char * DeviceHM10::getPayload() {

  return buffer->getPayload();
}

void DeviceHM10::dump(const char * msg, const unsigned char * payload, size_t len) {

  Serial.print(msg);

  for (unsigned int i = 0; i < len; i++) {
    char buf[4];
    snprintf(buf, sizeof(buf), "%.2X", payload[i]);
    Serial.print(buf);
  }

  Serial.println("");
}

bool DeviceHM10::isDeviceConnected() {

  return status == STATUS_CONNECTED || status == STATUS_DISCONNECTING;
}

bool DeviceHM10::checkConnectionStatus() {

  bool connectionStatus = DeviceHM10::isDeviceConnected();

  if (buffer->getLen() < 3) {
    int count = serial->readBytes(buffer->getPayload() + buffer->getLen(), 3);
    buffer->addByteCount(count);
    if (count < 3) {
      return connectionStatus;
    }
  }

  unsigned char * payload = buffer->getPayload();
  // OK+CONNX / OK+LOST
  if (payload[0] != 'O' || payload[1] != 'K' || payload[2] != '+') {
    return connectionStatus;
  }

  if (buffer->getLen() < 7) {
    int need = 8 - buffer->getLen();
    int count = serial->readBytes(buffer->getPayload() + buffer->getLen(), need);
    buffer->addByteCount(count);
    if (buffer->getLen() < 7) {
      return connectionStatus;
    }
  }

  if (buffer->getLen() > 7) {
    if ( memcmp(buffer->getPayload(), "OK+CONNE", 8) == 0 ||
         memcmp(buffer->getPayload(), "OK+CONNF", 8) == 0
       ) {

      if (status == STATUS_CONNECTING) {
        status = STATUS_INITIALIZING;
      }
      else {
        status = STATUS_DISCONNECTED;
      }
      buffer->removeBytes(8);
      return connectionStatus;
    }

    if (memcmp(buffer->getPayload(), "OK+CONNA", 8) == 0) {
      buffer->removeBytes(8);
      return connectionStatus;
    }
  }

  if (memcmp(buffer->getPayload(), "OK+CONN", 7) == 0) {
    buffer->removeBytes(7);
    newConnection = true;
    status = STATUS_CONNECTED;
    Serial.println("device connected");
    return true;
  }

  // BAD: assuming it is OK+LOST
  return reset("device disconnected");
}

bool DeviceHM10::hasBytes(unsigned int bytes) {

  if (buffer->hasBytes(bytes)) {
    return true;
  }

  int bAvailable = bytes - buffer->getLen();

  // do not loop - try to keep the buffer data queue small
  if (serial->available()) {
    if (bAvailable > buffer->getFreeLen()) {
      bAvailable = buffer->getFreeLen();
    }

    int total = serial->readBytes(buffer->getPayload() + buffer->getLen(), bAvailable);
    if (total > 0) {
      buffer->addByteCount(total);
    }
  }

  if (!checkConnectionStatus()) {
    return false;
  }

  if (buffer->hasBytes(bytes)) {
    return true;
  }

  return false;
}

void DeviceHM10::write(const unsigned char *payload, int len) {

  if (status != STATUS_CONNECTED) {
    return;
  }

  serial->write(payload, len);
}

bool DeviceHM10::reset(const char * message) {

  Serial.println(message);

  if (status == STATUS_DISCONNECTING) {
    status = STATUS_DISCONNECTED;
  }
  else {
    status = STATUS_INITIALIZING;
  }

  newConnection = false;
  serial->flush();
  buffer->reset();

  // purge serial buffer
  while (serial->available()) {
    int val = serial->read();
  }

  return false;
}

bool DeviceHM10::isNewConnection() {

  if (newConnection == true) {
    newConnection = false;
    return true;
  }

  return false;
}

bool DeviceHM10::isConnected() {

  if (status == STATUS_CONNECTED) {
    return true;
  }
  else if (status == STATUS_DISCONNECTED) {
    return false;
  }

  if (status == STATUS_INITIALIZING) {
    if (!sendCommand("CON", mac)) return false;
    status = STATUS_CONNECTING;
  }

  if (status == STATUS_DISCONNECTING) {
    // Empty AT command disconnects the device
    serial->print("AT");
  }

  return checkConnectionStatus();
}

bool DeviceHM10::sendCommand(const char *cmd, const char *value) {

  char buffer[40];
  char expected[40];
  int count = 0;

  while (count < 5) {
    delay(count * 100);
    count++;

    // purge serial buffer
    while (serial->available()) {
      int val = serial->read();
    }

    if (cmd == NULL || strlen(cmd) == 0) {
      serialPrintf("AT");
      snprintf(expected, sizeof(expected), "OK");
    }
    else {
      serialPrintf("AT+%s%s", cmd, value);

      if (value == NULL || strlen(value) == 0) {
        snprintf(expected, sizeof(expected), "OK+%s", cmd);
      }
      else if (cmd == "CON") {
        return true;
        //snprintf(expected, sizeof(expected), "OK+CONNA");
      }
      else {
        snprintf(expected, sizeof(expected), "OK+Set:%s", value);
      }
    }

    int total = serial->readBytes(buffer, strlen(expected));

    if (total >= 0) {
      // read extra bytes still in buffer
      while (serial->available() && (total < sizeof(buffer))) {
        buffer[total++] = serial->read();
      }

      buffer[total] = '\0';
    }

    if (total <= 0) {
      continue;
    }

    if (strcmp(buffer, expected) != 0) {
      Serial.print("command ");
      Serial.print(cmd);
      Serial.print(" failed: ");
      Serial.println(buffer);
      Serial.print("expected: ");
      Serial.println(expected);

      return false;
    }

    return true;
  }

  Serial.print("failed to get answer for command ");
  Serial.println(cmd);

  return false;
}

void DeviceHM10::connect() {

  if (status == STATUS_CONNECTED || status == STATUS_INITIALIZING || status == STATUS_CONNECTING) {
    return;
  }

  status = STATUS_INITIALIZING;
  // TODO: Do discovery
}

void DeviceHM10::disconnect() {

  if (status == STATUS_DISCONNECTED) {
    return;
  }

  if (status == STATUS_INITIALIZING) {
    status = STATUS_DISCONNECTED;
    return;
  }

  status = STATUS_DISCONNECTING;
}

boolean DeviceHM10::initDevice() {
    if (!sendCommand("", "")) return false;
    if (!sendCommand("RENEW", "")) return false;
    if (!sendCommand("IMME", "1")) return false;
    if (!sendCommand("MODE", "1")) return false;
    if (!sendCommand("COMP", "1")) return false;
    if (!sendCommand("NOTI", "1")) return false;
    if (!sendCommand("UUID", "0x1800")) return false;
    if (!sendCommand("CHAR", "0x2A80")) return false;
    if (!sendCommand("ROLE", "1")) return false;
    delay(1000);

    return true;
}

void DeviceHM10::init() {

#if defined(HAVE_HWSERIAL1)
  serial = &Serial1;
#else
  //serial = new SoftwareSerial(TX_PIN, RX_PIN);
  serial = new AltSoftSerial(TX_PIN, RX_PIN);
#endif

  serial->begin(9600);

  while (!initDevice()) {
  }
}

DeviceHM10::DeviceHM10() {

  buffer = new Buffer();
  newConnection = false;
  status = STATUS_DISCONNECTED;
}

DeviceHM10::~DeviceHM10() {

  delete(buffer);
}

<|endoftext|>


<commit_before>#ifdef PKMDS_CMAKE_USED
//#include <pkmds/pkmds_sql.h>
#include <pkmds/pkmds_gba.h>
#else
//#include "..\\..\\include\\pkmds\\pkmds_sql.h"
#include "..\\..\\include\\pkmds\\pkmds_gba.h"
#endif
//#include <string>
//#include <locale>
using namespace std;
string outputpath = "C:\\Users\\Michael Bond\\Downloads\\GBA PKM DUMPED\\";
int main(int argc, char* argv[])
{
	string savefile;
	//savefile = "C:\\Users\\Michael Bond\\Dropbox\\Saves\\pokemon_emerald_version - Copy2.sav";
	savefile = "C:\\Users\\Michael Bond\\Dropbox\\Saves\\Pokemon - Fire Red GBA_MODIFIED.sav";
	const char * pkmfile = "C:\\Users\\Michael Bond\\Dropbox\\Saves\\Gengar_heart.3gpkm";
	gbasavefilepacked* savin = new gbasavefilepacked();
	gbasavefile* sav = new gbasavefile();
	pokemon_gen3* gbapkm = new pokemon_gen3();
	pokemon_obj * pkm = new pokemon_obj();
	read(savefile.c_str(),savin);
	buildgbasave(savin,sav);
	opendb("C:\\Users\\Michael Bond\\Dropbox\\PKMDS Databases\\veekun-pokedex.sqlite");

	//read(pkmfile,gbapkm);
	//dostuff(gbapkm);

	for(int box = 0; box < 14; box++)
	{
		for(int slot = 0; slot < 30; slot++)
		{
			gbapkm = &(sav->pcstorage.pcstorage[box][slot]);
			decryptgbapkm(gbapkm);
			shufflegbapkm(gbapkm,true);
			if(gbapkm->data.species != GBASpecies::NOTHING)
			{
				//if(gbapkm->data.species == GBASpecies::squirtle)
				//{
				//uint32 * ribbons = reinterpret_cast<uint32*>(&(gbapkm->data.ribbons));
				//if(*ribbons != 0)
				//{
				if((box == 0) & (slot == 0))
				{
					//dostuff(gbapkm);
					convertgen3pkmtogen5(gbapkm,pkm);
				}
				//}
				//}
			}
		}
	}
	closedb();
	cout << "\nEND\n";
	string test;
	//cin >> test;
	return 0;
}
<commit_msg>Update gen-3-test.cpp<commit_after>#ifdef PKMDS_CMAKE_USED
#include <pkmds/pkmds_gba.h>
#else
//#include "..\\..\\include\\pkmds\\pkmds_sql.h"
#include "..\\..\\include\\pkmds\\pkmds_gba.h"
#endif
using namespace std;
int main(int argc, char* argv[])
{
	if(argc > 1)
	{
	string savefile = argv[1];
	gbasavefilepacked* savin = new gbasavefilepacked();
	gbasavefile* sav = new gbasavefile();
	pokemon_gen3* gbapkm = new pokemon_gen3();
	pokemon_obj * pkm = new pokemon_obj();
	read(savefile.c_str(),savin);
	buildgbasave(savin,sav);
	opendb("C:\\Users\\Michael Bond\\Dropbox\\PKMDS Databases\\veekun-pokedex.sqlite");
	for(int box = 0; box < 14; box++)
	{
		for(int slot = 0; slot < 30; slot++)
		{
			gbapkm = &(sav->pcstorage.pcstorage[box][slot]);
			decryptgbapkm(gbapkm);
			shufflegbapkm(gbapkm,true);
			if(gbapkm->data.species != GBASpecies::NOTHING)
			{
				if((box == 0) & (slot == 0))
				{
					convertgen3pkmtogen5(gbapkm,pkm);
					cout << lookuppkmname(pkm) << "\n";
				}
			}
		}
	}
	closedb();
	cout << "\nEND\n";
	}
	return 0;
}
<|endoftext|>


<commit_before><commit_msg>document that these are references to mozilla bugs<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: xlfd_smpl.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2004-05-18 13:49:24 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef XLFD_ATTRIBUTE_HXX
#include "xlfd_attr.hxx"
#endif
#ifndef XLFD_SIMPLE_HXX
#include "xlfd_smpl.hxx"
#endif

// --------------------------------------------------------------------------
//
//
// broken down structure equivalent to a Xlfd string
//
//
// --------------------------------------------------------------------------

Xlfd::Xlfd()
{
}

// XlfdCompare abi has to be qsort(3) compatible, the sorting result must
// guarantee that fonts with SameFontoutline() are successive
// XlfdCompare relies on vFrom->mpFactory eq vTo->mpFactory. Since comparing
// Xlfd's is done by comparing attributes there is no way around this.
extern "C" int
XlfdCompare( const void *vFrom, const void *vTo )
{
    const Xlfd *pFrom = (Xlfd*)vFrom;
    const Xlfd *pTo   = (Xlfd*)vTo;

    // Compare outline description
    if ( pFrom->mnFoundry != pTo->mnFoundry )
        return (int)pFrom->mnFoundry - (int)pTo->mnFoundry;
    if ( pFrom->mnFamily != pTo->mnFamily )
        return (int)pFrom->mnFamily - (int)pTo->mnFamily;
    if ( pFrom->mnWeight != pTo->mnWeight )
        return (int)pFrom->mnWeight - (int)pTo->mnWeight;
    if ( pFrom->mnSlant != pTo->mnSlant )
        return (int)pFrom->mnSlant - (int)pTo->mnSlant;
    if ( pFrom->mnSetwidth != pTo->mnSetwidth )
        return (int)pFrom->mnSetwidth - (int)pTo->mnSetwidth;

    // Addstyle name is futile tricky. it may contain encoding information
    // (like "ansi_1251") which Compares equal, or it may contain style
    // information (like "serif") which Compares unequal, anyway if the font
    // is "interface user" or "interface system" then compare equal anyway to
    // build fontsets as large as possible
    if ( pFrom->mnAddstyle == pTo->mnAddstyle )
        return 0;

    AttributeProvider *pFactory = pFrom->mpFactory;
    Attribute *pFamily = pFactory->RetrieveFamily( pFrom->mnFamily );
    if ( pFamily->HasFeature(XLFD_FEATURE_APPLICATION_FONT) )
        return 0;

    Attribute *pFromAddStyle = pFactory->RetrieveAddstyle( pFrom->mnAddstyle );
    Attribute *pToAddStyle   = pFactory->RetrieveAddstyle( pTo->mnAddstyle );

    // if both addstyles denote encodings or if one denotes an
    // encoding and the other denotes a style which really
    // duplicates weight and slant information

    int nFromCompare =     (pFromAddStyle->GetValue() != RTL_TEXTENCODING_DONTKNOW)
                        || (pFromAddStyle->HasFeature(XLFD_FEATURE_REDUNDANTSTYLE)) ?
                         -1 : pFrom->mnAddstyle;
    int nToCompare   =     (pToAddStyle->GetValue()   != RTL_TEXTENCODING_DONTKNOW)
                        || (pToAddStyle->HasFeature(XLFD_FEATURE_REDUNDANTSTYLE))   ?
                        -1 : pTo->mnAddstyle;

    return nFromCompare - nToCompare;
}

// check whether two fonts are identical as appearance is concerned
// this does not Compare the actual scaling of two fonts
Bool
Xlfd::SameFontoutline( const Xlfd* pComparedTo ) const
{
    void* pThis = (void*)this;
    return XlfdCompare( (void*)pThis, (void*)pComparedTo ) == 0 ;
}

unsigned short
Xlfd::GetEncoding() const
{
    Attribute *pAddstyle = mpFactory->RetrieveAddstyle( mnAddstyle );
    if ( pAddstyle->GetValue() != RTL_TEXTENCODING_DONTKNOW )
        return pAddstyle->GetValue();

    Attribute *pEncoding = mpFactory->RetrieveCharset( mnCharset );
    return pEncoding->GetValue();
}

XlfdFonttype
Xlfd::Fonttype() const
{
    if ( (mnAverageWidth == 0) && (mnPixelSize == 0) && (mnPointSize == 0) )
    {
        return     (mnResolutionX == 0)
                && (mnResolutionY == 0) ? eTypeScalable : eTypeScalableBitmap;
    }

    return eTypeBitmap;
}

void
Advance( const char** pFrom, const char** pTo )
{
    const char *pTmp = *pTo;

    for( ; (*pTmp != '\0') && (*pTmp++ != '-'); )
        {}
    *pFrom = *pTo;
    *pTo   = pTmp;
}

Bool
Xlfd::IsConformant (const char* pXlfd) const
{
    // X FontNameRegistry prefix "-"
    if (*pXlfd++ != '-')
        return False;

    // All Xlfd FontName fields are defined
    int nNumFields = 1;
    while (*pXlfd != '\0')
    {
        if (*pXlfd++ == '-')
            nNumFields++;
    }
    // enough entries ?
    if (nNumFields != 14)
        return False;
    // and the last one is not empty as well ?
    if (*(pXlfd - 1) == '-')
        return False;

    return True;
}

// this is the real workhorse function. Since this is called for every font
// in the fontpath it has to be as fast a possible
Bool
Xlfd::FromString( const char* pXlfdstring, AttributeProvider *pFactory )
{
    if (!IsConformant(pXlfdstring))
        return False;

    const char* pFrom = pXlfdstring + 1;
    const char* pTo   = pFrom;
    mpFactory         = pFactory;

    Advance( &pFrom, &pTo ); //-foundry-*
    mnFoundry = mpFactory->InsertFoundry( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); // -*-family-*
    mnFamily = mpFactory->InsertFamily( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); // -*-*-weight-*
    mnWeight = mpFactory->InsertWeight( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); //-*-*-*-slant-*
    mnSlant = mpFactory->InsertSlant( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); //-*-*-*-*-setwidth-*
    mnSetwidth = mpFactory->InsertSetwidth( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-Addstyle-*
    mnAddstyle = mpFactory->InsertAddstyle( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-height-*
    mnPixelSize = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-pt height-*
    mnPointSize = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-x resolution-*
    mnResolutionX = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-y resolution-*
    mnResolutionY = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-spacing-*
    mcSpacing = pFrom == pTo ? '\0' : *pFrom;

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-*-average-*
    mnAverageWidth = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-*-*-registry-encoding
    const char* pTmp = pFrom;
    Advance( &pTmp, &pTo );
    mnCharset = mpFactory->InsertCharset( pFrom, pTo - pFrom );

    // sanity check whether we have really found a valid XLFD, if not
    // throw away the whole font, since we have no idea what parts of
    // the XLFD contains the error.
    if ( !(pTo > pFrom) )
        return False;

     // a non-empty family name is essential, since otherwise the font
    // would match the "default font" #52299#
    Attribute*  pFamily     = mpFactory->RetrieveFamily( mnFamily );
    const char* pFamilyName = pFamily->GetName();
    if ( pFamilyName[0] == '\0' )
        return False;

    // well done
    return True;
}

#if OSL_DEBUG_LEVEL > 1
// pure debug for now: this is only to inspect/pretty print a Xlfd struct
const char*
Xlfd::ToString( ByteString &rString ) const
{
    AppendAttribute( mpFactory->RetrieveFoundry(mnFoundry),   rString );
    AppendAttribute( mpFactory->RetrieveFamily(mnFamily),     rString );
    AppendAttribute( mpFactory->RetrieveWeight(mnWeight),     rString );
    AppendAttribute( mpFactory->RetrieveSlant(mnSlant),       rString );
    AppendAttribute( mpFactory->RetrieveSetwidth(mnSetwidth), rString );
    AppendAttribute( mpFactory->RetrieveAddstyle(mnAddstyle), rString );

    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnPixelSize ) );
    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnPointSize ) );
    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnResolutionX ) );
    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnResolutionY ) );
    rString.Append("-"); rString.Append( (char)mcSpacing );
    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnAverageWidth ) );

    AppendAttribute( mpFactory->RetrieveCharset(mnCharset), rString );

    return rString.GetBuffer() ;
}

void
Xlfd::Dump() const
{
    ByteString aString;
    fprintf(stderr, "Xlfd: %s\n", ToString(aString) );
}
#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.7.446); FILE MERGED 2005/09/05 14:45:47 rt 1.7.446.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xlfd_smpl.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 13:10:11 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef XLFD_ATTRIBUTE_HXX
#include "xlfd_attr.hxx"
#endif
#ifndef XLFD_SIMPLE_HXX
#include "xlfd_smpl.hxx"
#endif

// --------------------------------------------------------------------------
//
//
// broken down structure equivalent to a Xlfd string
//
//
// --------------------------------------------------------------------------

Xlfd::Xlfd()
{
}

// XlfdCompare abi has to be qsort(3) compatible, the sorting result must
// guarantee that fonts with SameFontoutline() are successive
// XlfdCompare relies on vFrom->mpFactory eq vTo->mpFactory. Since comparing
// Xlfd's is done by comparing attributes there is no way around this.
extern "C" int
XlfdCompare( const void *vFrom, const void *vTo )
{
    const Xlfd *pFrom = (Xlfd*)vFrom;
    const Xlfd *pTo   = (Xlfd*)vTo;

    // Compare outline description
    if ( pFrom->mnFoundry != pTo->mnFoundry )
        return (int)pFrom->mnFoundry - (int)pTo->mnFoundry;
    if ( pFrom->mnFamily != pTo->mnFamily )
        return (int)pFrom->mnFamily - (int)pTo->mnFamily;
    if ( pFrom->mnWeight != pTo->mnWeight )
        return (int)pFrom->mnWeight - (int)pTo->mnWeight;
    if ( pFrom->mnSlant != pTo->mnSlant )
        return (int)pFrom->mnSlant - (int)pTo->mnSlant;
    if ( pFrom->mnSetwidth != pTo->mnSetwidth )
        return (int)pFrom->mnSetwidth - (int)pTo->mnSetwidth;

    // Addstyle name is futile tricky. it may contain encoding information
    // (like "ansi_1251") which Compares equal, or it may contain style
    // information (like "serif") which Compares unequal, anyway if the font
    // is "interface user" or "interface system" then compare equal anyway to
    // build fontsets as large as possible
    if ( pFrom->mnAddstyle == pTo->mnAddstyle )
        return 0;

    AttributeProvider *pFactory = pFrom->mpFactory;
    Attribute *pFamily = pFactory->RetrieveFamily( pFrom->mnFamily );
    if ( pFamily->HasFeature(XLFD_FEATURE_APPLICATION_FONT) )
        return 0;

    Attribute *pFromAddStyle = pFactory->RetrieveAddstyle( pFrom->mnAddstyle );
    Attribute *pToAddStyle   = pFactory->RetrieveAddstyle( pTo->mnAddstyle );

    // if both addstyles denote encodings or if one denotes an
    // encoding and the other denotes a style which really
    // duplicates weight and slant information

    int nFromCompare =     (pFromAddStyle->GetValue() != RTL_TEXTENCODING_DONTKNOW)
                        || (pFromAddStyle->HasFeature(XLFD_FEATURE_REDUNDANTSTYLE)) ?
                         -1 : pFrom->mnAddstyle;
    int nToCompare   =     (pToAddStyle->GetValue()   != RTL_TEXTENCODING_DONTKNOW)
                        || (pToAddStyle->HasFeature(XLFD_FEATURE_REDUNDANTSTYLE))   ?
                        -1 : pTo->mnAddstyle;

    return nFromCompare - nToCompare;
}

// check whether two fonts are identical as appearance is concerned
// this does not Compare the actual scaling of two fonts
Bool
Xlfd::SameFontoutline( const Xlfd* pComparedTo ) const
{
    void* pThis = (void*)this;
    return XlfdCompare( (void*)pThis, (void*)pComparedTo ) == 0 ;
}

unsigned short
Xlfd::GetEncoding() const
{
    Attribute *pAddstyle = mpFactory->RetrieveAddstyle( mnAddstyle );
    if ( pAddstyle->GetValue() != RTL_TEXTENCODING_DONTKNOW )
        return pAddstyle->GetValue();

    Attribute *pEncoding = mpFactory->RetrieveCharset( mnCharset );
    return pEncoding->GetValue();
}

XlfdFonttype
Xlfd::Fonttype() const
{
    if ( (mnAverageWidth == 0) && (mnPixelSize == 0) && (mnPointSize == 0) )
    {
        return     (mnResolutionX == 0)
                && (mnResolutionY == 0) ? eTypeScalable : eTypeScalableBitmap;
    }

    return eTypeBitmap;
}

void
Advance( const char** pFrom, const char** pTo )
{
    const char *pTmp = *pTo;

    for( ; (*pTmp != '\0') && (*pTmp++ != '-'); )
        {}
    *pFrom = *pTo;
    *pTo   = pTmp;
}

Bool
Xlfd::IsConformant (const char* pXlfd) const
{
    // X FontNameRegistry prefix "-"
    if (*pXlfd++ != '-')
        return False;

    // All Xlfd FontName fields are defined
    int nNumFields = 1;
    while (*pXlfd != '\0')
    {
        if (*pXlfd++ == '-')
            nNumFields++;
    }
    // enough entries ?
    if (nNumFields != 14)
        return False;
    // and the last one is not empty as well ?
    if (*(pXlfd - 1) == '-')
        return False;

    return True;
}

// this is the real workhorse function. Since this is called for every font
// in the fontpath it has to be as fast a possible
Bool
Xlfd::FromString( const char* pXlfdstring, AttributeProvider *pFactory )
{
    if (!IsConformant(pXlfdstring))
        return False;

    const char* pFrom = pXlfdstring + 1;
    const char* pTo   = pFrom;
    mpFactory         = pFactory;

    Advance( &pFrom, &pTo ); //-foundry-*
    mnFoundry = mpFactory->InsertFoundry( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); // -*-family-*
    mnFamily = mpFactory->InsertFamily( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); // -*-*-weight-*
    mnWeight = mpFactory->InsertWeight( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); //-*-*-*-slant-*
    mnSlant = mpFactory->InsertSlant( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); //-*-*-*-*-setwidth-*
    mnSetwidth = mpFactory->InsertSetwidth( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-Addstyle-*
    mnAddstyle = mpFactory->InsertAddstyle( pFrom, pTo - pFrom - 1 );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-height-*
    mnPixelSize = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-pt height-*
    mnPointSize = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-x resolution-*
    mnResolutionX = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-y resolution-*
    mnResolutionY = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-spacing-*
    mcSpacing = pFrom == pTo ? '\0' : *pFrom;

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-*-average-*
    mnAverageWidth = atoi( pFrom );

    Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-*-*-registry-encoding
    const char* pTmp = pFrom;
    Advance( &pTmp, &pTo );
    mnCharset = mpFactory->InsertCharset( pFrom, pTo - pFrom );

    // sanity check whether we have really found a valid XLFD, if not
    // throw away the whole font, since we have no idea what parts of
    // the XLFD contains the error.
    if ( !(pTo > pFrom) )
        return False;

     // a non-empty family name is essential, since otherwise the font
    // would match the "default font" #52299#
    Attribute*  pFamily     = mpFactory->RetrieveFamily( mnFamily );
    const char* pFamilyName = pFamily->GetName();
    if ( pFamilyName[0] == '\0' )
        return False;

    // well done
    return True;
}

#if OSL_DEBUG_LEVEL > 1
// pure debug for now: this is only to inspect/pretty print a Xlfd struct
const char*
Xlfd::ToString( ByteString &rString ) const
{
    AppendAttribute( mpFactory->RetrieveFoundry(mnFoundry),   rString );
    AppendAttribute( mpFactory->RetrieveFamily(mnFamily),     rString );
    AppendAttribute( mpFactory->RetrieveWeight(mnWeight),     rString );
    AppendAttribute( mpFactory->RetrieveSlant(mnSlant),       rString );
    AppendAttribute( mpFactory->RetrieveSetwidth(mnSetwidth), rString );
    AppendAttribute( mpFactory->RetrieveAddstyle(mnAddstyle), rString );

    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnPixelSize ) );
    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnPointSize ) );
    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnResolutionX ) );
    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnResolutionY ) );
    rString.Append("-"); rString.Append( (char)mcSpacing );
    rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnAverageWidth ) );

    AppendAttribute( mpFactory->RetrieveCharset(mnCharset), rString );

    return rString.GetBuffer() ;
}

void
Xlfd::Dump() const
{
    ByteString aString;
    fprintf(stderr, "Xlfd: %s\n", ToString(aString) );
}
#endif

<|endoftext|>