cssysdef.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

cssysdef.h
Go to the documentation of this file.

    00001 /*
    00002     Copyright (C) 1998-2008 by Jorrit Tyberghein
    00003     Written by Andrew Zabolotny <bit@eltech.ru>
    00004
    00005     This library is free software; you can redistribute it and/or
    00006     modify it under the terms of the GNU Library General Public
    00007     License as published by the Free Software Foundation; either
    00008     version 2 of the License, or (at your option) any later version.
    00009
    00010     This library is distributed in the hope that it will be useful,
    00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013     Library General Public License for more details.
    00014
    00015     You should have received a copy of the GNU Library General Public
    00016     License along with this library; if not, write to the Free
    00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00018 */
    00019
    00020 #ifndef __CS_CSSYSDEF_H__
    00021 #define __CS_CSSYSDEF_H__
    00022
    00023 #define CSDEF_FRIEND
    00024 #include "csdef.h"
    00025 #undef CSDEF_FRIEND
    00026
    00036 /* Check whether shared or static libs should be used.
    00037    Relevant defines are CS_USE_SHARED_LIBS, CS_USE_STATIC_LIBS and
    00038    CS_BUILD_SHARED_LIBS. While building CS they indicate whether CS is built
    00039    with shared or static libs; while building external applications they
    00040    indicate whether the used CS was built with shared or static libs.
    00041
    00042    The reason for this multitude of defines is historical: first, there was
    00043    CS_BUILD_SHARED_LIBS (default being absent). However, the name is not very
    00044    clear when seen in the context of external projects (as CS isn't built there,
    00045    and it doesn't control the building of the external project). Hence,
    00046    the somewhat clearer CS_USE_SHARED_LIBS was added. CS_USE_STATIC_LIBS was
    00047    added to provide an orthogonal definition to make clear static libs are
    00048    used.
    00049    Lastly, the defaults have changed: if none of the macros are defined the
    00050    default is CS_USE_SHARED_LIBS. The reason is that, nowadays, shared libs
    00051    are the default on most platforms anyway. (Especially on MSVC people tend
    00052    to overlook to set the CS_BUILD_SHARED_LIBS define for an external project
    00053    and experience build errors.)
    00054  */
    00055
    00056 /* CS_USE_ defines have first control over shared lib building, override
    00057    legacy CS_BUILD_SHARED_LIBS accordingly */
    00058 #if defined(CS_USE_SHARED_LIBS)
    00059 #  if !defined(CS_BUILD_SHARED_LIBS)
    00060 #    define CS_BUILD_SHARED_LIBS
    00061 #  endif
    00062 #elif defined(CS_USE_STATIC_LIBS)
    00063 #  if defined(CS_BUILD_SHARED_LIBS)
    00064 #    undef CS_BUILD_SHARED_LIBS
    00065 #  endif
    00066 #endif
    00067 /* If no CS_USE_ macro is defined and no CS_BUILD_SHARED_LIBS either, default
    00068    to CS_USE_SHARED_LIBS */
    00069 #if !defined(CS_USE_SHARED_LIBS) && !defined(CS_USE_STATIC_LIBS)
    00070 #  if !defined(CS_BUILD_SHARED_LIBS)
    00071 #    define CS_BUILD_SHARED_LIBS
    00072 #  endif
    00073 #  define CS_USE_SHARED_LIBS
    00074 #endif
    00075 // Sanity check
    00076 #if defined(CS_USE_SHARED_LIBS) && defined(CS_USE_STATIC_LIBS)
    00077 #  error Both CS_USE_SHARED_LIBS and CS_USE_STATIC_LIBS defined, please pick one!
    00078 #endif
    00079
    00080 /*
    00081  * Pull in platform-specific overrides of the requested functionality.
    00082  */
    00083 #include "csutil/csosdefs.h"
    00084
    00085 // Defaults for platforms that do not define their own.
    00086 #ifndef CS_VISIBILITY_DEFAULT
    00087 #  define CS_VISIBILITY_DEFAULT
    00088 #endif
    00089 #ifndef CS_VISIBILITY_HIDDEN
    00090 #  define CS_VISIBILITY_HIDDEN
    00091 #endif
    00092 #ifndef CS_EXPORT_SYM_DLL
    00093 #  define CS_EXPORT_SYM_DLL CS_VISIBILITY_DEFAULT
    00094 #endif
    00095 #ifndef CS_IMPORT_SYM_DLL
    00096 #  define CS_IMPORT_SYM_DLL extern
    00097 #endif
    00098 #ifndef CS_EXPORT_SYM
    00099 #  if defined(CS_USE_SHARED_LIBS)
    00100 #    define CS_EXPORT_SYM CS_VISIBILITY_DEFAULT
    00101 #  else
    00102 #    define CS_EXPORT_SYM
    00103 #  endif
    00104 #endif
    00105 #ifndef CS_IMPORT_SYM
    00106 #  define CS_IMPORT_SYM
    00107 #endif
    00108
    00109 #include "csextern.h"
    00110
    00111 /* On MinGW, with some versions of the MinGW runtime (3.15 and above), using
    00112    the STL together with -ansi is broken: the C runtime functions swprintf()
    00113    and vswprintf() are not declared, but an STL header (<cwchar>)
    00114    unconditionally references it via 'using'.
    00115    To work around the problem provide our own dummy declarations of these
    00116    functions. */
    00117 #if defined(__STRICT_ANSI__) && \
    00118     (defined(CS_ANSI_BREAKS_SWPRINTF) || defined(CS_ANSI_BREAKS_VSWPRINTF))
    00119 #if defined(CS_ANSI_BREAKS_SWPRINTF)
    00120 int swprintf ();
    00121 #endif
    00122 #if defined(CS_ANSI_BREAKS_VSWPRINTF)
    00123 int vswprintf ();
    00124 #endif
    00125 #include <cwchar>
    00126 #endif
    00127
    00128 /*
    00129  * Default definitions for requested functionality.  Platform-specific
    00130  * configuration files may override these.
    00131  */
    00132
    00133 #ifndef CS_FORCEINLINE
    00134 # ifdef CS_COMPILER_GCC
    00135 #  define CS_FORCEINLINE inline __attribute__((always_inline))
    00136 #  if (__GNUC__ == 3) && (__GNUC_MINOR__ == 4)
    00137     // Work around a gcc 3.4 issue where forcing inline doesn't always work
    00138 #   define CS_FORCEINLINE_TEMPLATEMETHOD inline
    00139 #  endif
    00140 # else
    00141 #  define CS_FORCEINLINE inline
    00142 # endif
    00143 #endif
    00144 #ifndef CS_FORCEINLINE_TEMPLATEMETHOD
    00145 # define CS_FORCEINLINE_TEMPLATEMETHOD CS_FORCEINLINE
    00146 #endif
    00147
    00152 #ifndef CS_ATTRIBUTE_MALLOC
    00153 # define CS_ATTRIBUTE_MALLOC
    00154 #endif
    00155
    00159 #ifndef CS_ATTRIBUTE_INIT_PRIORITY
    00160 # define CS_ATTRIBUTE_INIT_PRIORITY(PRI)
    00161 #endif
    00162
    00163 // Set up deprecation macros
    00164 #ifdef CS_COMPILER_GCC
    00165 #  define CS_DEPRECATED_METHOD    CS_ATTRIBUTE_DEPRECATED
    00166 #  define CS_DEPRECATED_TYPE      CS_ATTRIBUTE_DEPRECATED
    00167 #  define CS_DEPRECATED_VAR(decl) decl CS_ATTRIBUTE_DEPRECATED
    00168 #  ifdef CS_ATTRIBUTE_DEPRECATED_MSG
    00169 #    define CS_DEPRECATED_METHOD_MSG(msg)       CS_ATTRIBUTE_DEPRECATED_MSG(msg)
    00170 #    define CS_DEPRECATED_TYPE_MSG(msg)         CS_ATTRIBUTE_DEPRECATED_MSG(msg)
    00171 #    define CS_DEPRECATED_VAR_MSG(msg, decl)    decl CS_ATTRIBUTE_DEPRECATED_MSG(msg)
    00172 #  endif
    00173 #endif
    00174
    00186 #if !defined(CS_DEPRECATED_METHOD) || defined(DOXYGEN_RUN)
    00187 #  if defined(CS_COMPILER_MSVC)
    00188 #    define CS_DEPRECATED_METHOD        __declspec(deprecated)
    00189       /* Unfortunately, MSVC is overzealous with warnings; it even emits one
    00190          when a deprecated method is overridden, e.g. when implementing an
    00191          interface method.
    00192          To work around this, use msvc_deprecated_warn_off.h/
    00193          msvc_deprecated_warn_on.h. */
    00194 #  else
    00195 #    define CS_DEPRECATED_METHOD
    00196 #  endif
    00197 #endif
    00198
    00203 #if !defined(CS_DEPRECATED_METHOD_MSG) || defined(DOXYGEN_RUN)
    00204 #  if defined(CS_COMPILER_MSVC) && _MSC_VER >= 1400
    00205 #    define CS_DEPRECATED_METHOD_MSG(msg) __declspec(deprecated(msg))
    00206 #  else
    00207 #    define CS_DEPRECATED_METHOD_MSG(msg) CS_DEPRECATED_METHOD
    00208 #  endif
    00209 #endif
    00210
    00221 #if !defined(CS_DEPRECATED_TYPE) || defined(DOXYGEN_RUN)
    00222 #  if defined(CS_COMPILER_MSVC)
    00223 #    define CS_DEPRECATED_TYPE __declspec(deprecated)
    00224 #  else
    00225 #    define CS_DEPRECATED_TYPE
    00226 #  endif
    00227 #endif
    00228
    00233 #if !defined(CS_DEPRECATED_TYPE_MSG) || defined(DOXYGEN_RUN)
    00234 #  if defined(CS_COMPILER_MSVC) && _MSC_VER >= 1400
    00235 #    define CS_DEPRECATED_TYPE_MSG(msg) __declspec(deprecated(msg))
    00236 #  else
    00237 #    define CS_DEPRECATED_TYPE_MSG(msg) CS_DEPRECATED_TYPE
    00238 #  endif
    00239 #endif
    00240
    00254 #if !defined(CS_DEPRECATED_VAR) || defined(DOXYGEN_RUN)
    00255 #  if defined(CS_COMPILER_MSVC)
    00256 #    define CS_DEPRECATED_VAR(decl) __declspec(deprecated) decl
    00257 #  else
    00258 #    define CS_DEPRECATED_VAR(decl) decl
    00259 #  endif
    00260 #endif
    00261
    00266 #if !defined(CS_DEPRECATED_VAR_MSG) || defined(DOXYGEN_RUN)
    00267 #  if defined(CS_COMPILER_MSVC) && _MSC_VER >= 1400
    00268 #    define CS_DEPRECATED_VAR_MSG(msg, decl) __declspec(deprecated(msg)) decl
    00269 #  else
    00270 #    define CS_DEPRECATED_VAR_MSG(msg, decl) CS_DEPRECATED_VAR(decl)
    00271 #  endif
    00272 #endif
    00273
    00278 #if defined(CS_COMPILER_MSVC)
    00279   #include <exception>
    00280   #if !_HAS_EXCEPTIONS
    00281     #define CS_NO_EXCEPTIONS
    00282   #endif
    00283 #elif defined(CS_COMPILER_GCC) && !defined(__EXCEPTIONS)
    00284   #define CS_NO_EXCEPTIONS
    00285 #endif
    00286
    00291 #ifndef CS_MAXPATHLEN
    00292 #define CS_MAXPATHLEN 1024
    00293 #endif
    00294 #include <stdio.h>
    00295 #ifdef CS_HAVE_SYS_PARAM_H
    00296 #include <sys/param.h>
    00297 #endif
    00298
    00305 #if defined(CS_COMPILER_GCC) && !defined(__STRICT_ANSI__)
    00306 // In GCC we are able to declare stack vars of dynamic size directly
    00307 #  define CS_ALLOC_STACK_ARRAY(type, var, size) \
    00308      type var [size]
    00309 #else
    00310 #  include <stdlib.h>
    00311 #  define CS_ALLOC_STACK_ARRAY(type, var, size) \
    00312      type *var = (type *)alloca ((size) * sizeof (type))
    00313 #  if defined(CS_COMPILER_GCC) && defined(__STRICT_ANSI__) && !defined(alloca)
    00314 #    define alloca(x) __builtin_alloca(x)
    00315 #  endif
    00316 #endif
    00317
    00318
    00342 #define CS_HEADER_GLOBAL(X,Y) CS_HEADER_GLOBAL_COMPOSE(X,Y)
    00343 #define CS_HEADER_GLOBAL_COMPOSE(X,Y) <X/Y>
    00344
    00357 #define CS_HEADER_LOCAL(X,Y) CS_HEADER_LOCAL_COMPOSE1(X,Y)
    00358 #define CS_HEADER_LOCAL_COMPOSE1(X,Y) CS_HEADER_LOCAL_COMPOSE2(X/Y)
    00359 #define CS_HEADER_LOCAL_COMPOSE2(X) #X
    00360
    00361
    00367 #if !defined(CS_EXPORTED_FUNCTION)
    00368 #  if defined(CS_STATIC_LINKED)
    00369 #    define CS_EXPORTED_FUNCTION extern "C"
    00370 #  else
    00371 #    define CS_EXPORTED_FUNCTION extern "C" CS_EXPORT_SYM_DLL
    00372 #  endif
    00373 #endif
    00374
    00386 #if !defined(CS_EXPORTED_NAME)
    00387 #  define CS_EXPORTED_NAME(Prefix, Suffix) Prefix ## Suffix
    00388 #endif
    00389
    00390 #ifndef CS_IMPLEMENT_PLATFORM_PLUGIN
    00391 #  define CS_IMPLEMENT_PLATFORM_PLUGIN
    00392 #endif
    00393
    00394 #ifndef CS_IMPLEMENT_PLATFORM_APPLICATION
    00395 #  define CS_IMPLEMENT_PLATFORM_APPLICATION
    00396 #endif
    00397
    00404 #ifndef CS_INITIALIZE_PLATFORM_APPLICATION
    00405 #  define CS_INITIALIZE_PLATFORM_APPLICATION /* */
    00406 /*
    00407   This definition may seem odd, but it's here for doxygen's sake, which
    00408   apparently fails to document empty macro definitions.
    00409  */
    00410 #endif
    00411
    00412 typedef void (*csStaticVarCleanupFN) (void (*p)());
    00413 extern csStaticVarCleanupFN csStaticVarCleanup;
    00414
    00415 #include "csutil/threading/atomicops.h"
    00416 #include "csutil/threading/mutex.h"
    00417
    00418 #define CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION_A(Name, FuncAttr)    \
    00419 static CS::Threading::Mutex Name_ ## staticVarLock;                    \
    00420 FuncAttr void Name (void (*p)())                                       \
    00421 {                                                                      \
    00422   CS::Threading::MutexScopedLock lock (Name_ ## staticVarLock);        \
    00423   static void (**a)() = 0;                                             \
    00424   static int lastEntry = 0;                                            \
    00425   static int maxEntries = 0;                                           \
    00426                                                                        \
    00427   if (p != 0)                                                          \
    00428   {                                                                    \
    00429     if (lastEntry >= maxEntries)                                       \
    00430     {                                                                  \
    00431       maxEntries += 10;                                                \
    00432       if (a == 0)                                                      \
    00433         a = (void (**)())malloc(maxEntries * sizeof(void*));           \
    00434       else                                                             \
    00435         a = (void (**)())realloc(a, maxEntries * sizeof(void*));       \
    00436     }                                                                  \
    00437     a[lastEntry++] = p;                                                \
    00438   }                                                                    \
    00439   else if (a != 0)                                                     \
    00440   {                                                                    \
    00441     for (int i = lastEntry - 1; i >= 0; i--)                           \
    00442       a[i] ();                                                         \
    00443     free (a);                                                          \
    00444     a = 0;                                                             \
    00445     lastEntry = 0;                                                     \
    00446     maxEntries = 0;                                                    \
    00447   }                                                                    \
    00448 }
    00449 #ifndef CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION
    00450 #  define CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION(Name)              \
    00451       CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION_A(Name, )
    00452 #endif
    00453
    00454 #ifndef CS_DEFINE_STATIC_VARIABLE_REGISTRATION
    00455 #  define CS_DEFINE_STATIC_VARIABLE_REGISTRATION(func) \
    00456     csStaticVarCleanupFN csStaticVarCleanup = &func
    00457 #endif
    00458
    00459 #ifndef CS_DECLARE_STATIC_VARIABLE_REGISTRATION
    00460 #  define CS_DECLARE_STATIC_VARIABLE_REGISTRATION(func) \
    00461     void func (void (*p)())
    00462 #endif
    00463
    00464 #ifndef CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION
    00465 #  define CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION               \
    00466     CS_CRYSTALSPACE_EXPORT                                              \
    00467     CS_DECLARE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_csutil);
    00468 #endif
    00469
    00470 #if defined(CS_EXTENSIVE_MEMDEBUG) || defined(CS_MEMORY_TRACKER)
    00471 #  define CS_DEFINE_MEMTRACKER_MODULE             \
    00472   class csMemTrackerModule;                       \
    00473   namespace CS                                    \
    00474   {                                               \
    00475     namespace Debug                               \
    00476     {                                             \
    00477       namespace MemTracker                        \
    00478       {                                           \
    00479         namespace Impl                            \
    00480         {                                         \
    00481           csMemTrackerModule* thisModule = 0;     \
    00482         }                                         \
    00483       }                                           \
    00484     }                                             \
    00485   }
    00486 #else
    00487 #  define CS_DEFINE_MEMTRACKER_MODULE
    00488 #endif
    00489
    00509 #ifndef CS_IMPLEMENT_FOREIGN_DLL
    00510 #  if defined(CS_BUILD_SHARED_LIBS)
    00511 #    define CS_IMPLEMENT_FOREIGN_DLL                                        \
    00512        CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION(csStaticVarCleanup_local); \
    00513        CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_local);   \
    00514        CS_DEFINE_MEMTRACKER_MODULE
    00515 #  else
    00516 #    define CS_IMPLEMENT_FOREIGN_DLL                                        \
    00517        CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION                      \
    00518        CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_csutil);  \
    00519        CS_DEFINE_MEMTRACKER_MODULE
    00520 #  endif
    00521 #endif
    00522
    00531 #if defined(CS_STATIC_LINKED)
    00532
    00533 #  ifndef CS_IMPLEMENT_PLUGIN
    00534 #  define CS_IMPLEMENT_PLUGIN                                           \
    00535           CS_IMPLEMENT_PLATFORM_PLUGIN
    00536 #  endif
    00537
    00538 #elif !defined(CS_BUILD_SHARED_LIBS)
    00539
    00540 #  ifndef CS_IMPLEMENT_PLUGIN
    00541 #  define CS_IMPLEMENT_PLUGIN                                           \
    00542           CS_IMPLEMENT_PLATFORM_PLUGIN                                  \
    00543           CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION               \
    00544           CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_csutil);   \
    00545           CS_DEFINE_MEMTRACKER_MODULE
    00546 #  endif
    00547
    00548 #else
    00549
    00550 #  ifndef CS_IMPLEMENT_PLUGIN
    00551 #  define CS_IMPLEMENT_PLUGIN                                           \
    00552    CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION(csStaticVarCleanup_local)  \
    00553    CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_local);   \
    00554    CS_IMPLEMENT_PLATFORM_PLUGIN                                         \
    00555    CS_DEFINE_MEMTRACKER_MODULE
    00556 #  endif
    00557
    00558 #endif
    00559
    00568 #ifndef CS_IMPLEMENT_APPLICATION
    00569 #  define CS_IMPLEMENT_APPLICATION                                      \
    00570   CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION                       \
    00571   CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_csutil);   \
    00572   CS_IMPLEMENT_PLATFORM_APPLICATION                                     \
    00573   CS_DEFINE_MEMTRACKER_MODULE
    00574 #endif
    00575
    00579 #ifndef CS_REGISTER_STATIC_FOR_DESTRUCTION
    00580 #define CS_REGISTER_STATIC_FOR_DESTRUCTION(getterFunc)\
    00581         csStaticVarCleanup (getterFunc);
    00582 #endif
    00583
    00587 #ifndef CS_STATIC_VARIABLE_CLEANUP
    00588 #define CS_STATIC_VARIABLE_CLEANUP  \
    00589         csStaticVarCleanup (0);
    00590 #endif
    00591
    00592 /* Body of getter function, mostly the same across different CS_STATIC_VAR_*
    00593   variants.
    00594   'Ptr' is a variable of type 'Type*' that receives the value of 'Val' (where
    00595   the actual object is stored). See CS_IMPLEMENT_STATIC_VAR for explanation
    00596   of initParam and kill_how.
    00597
    00598   'Val' is read atomically. If it's 0, a new object is created. If another
    00599   thread concurrently requests the value, it's ensured that the value is
    00600   consistent (both the returned and stored value).
    00601 */
    00602 #define CS_STATIC_VAR_GETTER_COMMON(Type, Ptr, initParam, Val, kill_how)\
    00603   while (true)                                                          \
    00604   {                                                                     \
    00605     Ptr = reinterpret_cast<Type*> (                                     \
    00606       CS::Threading::AtomicOperations::Read (                           \
    00607         reinterpret_cast<void**> (&Val)));                              \
    00608     if (Ptr != 0) break;                                                \
    00609     Ptr = new Type initParam;                                           \
    00610     if (CS::Threading::AtomicOperations::CompareAndSet (                \
    00611         reinterpret_cast<void**> (&Val), Ptr, 0) != 0)                  \
    00612     {                                                                   \
    00613       delete Ptr;                                                       \
    00614     }                                                                   \
    00615     else                                                                \
    00616     {                                                                   \
    00617       csStaticVarCleanup (kill_how);                                    \
    00618       break;                                                            \
    00619     }                                                                   \
    00620   }
    00621
    00634 #ifndef CS_IMPLEMENT_STATIC_VAR_EXT
    00635 #define CS_IMPLEMENT_STATIC_VAR_EXT(getterFunc,Type,initParam,kill_how) \
    00636 namespace {                                                             \
    00637 static Type* getterFunc ## _v = 0;                                      \
    00638 static Type* getterFunc ();                                             \
    00639 static void getterFunc ## _kill ();                                     \
    00640 static void getterFunc ## _kill_array ();                               \
    00641 void getterFunc ## _kill ()                                             \
    00642 {                                                                       \
    00643   (void)(&getterFunc ## _kill_array);                                   \
    00644   delete getterFunc ## _v;                                              \
    00645   getterFunc ## _v = 0;                                                 \
    00646 }                                                                       \
    00647 void getterFunc ## _kill_array ()                                       \
    00648 {                                                                       \
    00649   (void)(&getterFunc ## _kill);                                         \
    00650   delete [] getterFunc ## _v;                                           \
    00651   getterFunc ## _v = 0;                                                 \
    00652 }                                                                       \
    00653 Type* getterFunc ()                                                     \
    00654 {                                                                       \
    00655   Type* p;                                                              \
    00656   CS_STATIC_VAR_GETTER_COMMON(Type, p, initParam, getterFunc ## _v,     \
    00657     getterFunc ## kill_how);                                            \
    00658   return p;                                                             \
    00659 }                                                                       \
    00660 }
    00661 #endif
    00662
    00663 #ifndef CS_IMPLEMENT_STATIC_VAR
    00664 #define CS_IMPLEMENT_STATIC_VAR(getterFunc,Type,initParam) \
    00665  CS_IMPLEMENT_STATIC_VAR_EXT(getterFunc,Type,initParam,_kill)
    00666 #endif
    00667
    00668 #ifndef CS_IMPLEMENT_STATIC_VAR_ARRAY
    00669 #define CS_IMPLEMENT_STATIC_VAR_ARRAY(getterFunc,Type,initParam) \
    00670  CS_IMPLEMENT_STATIC_VAR_EXT(getterFunc,Type,initParam,_kill_array)
    00671 #endif
    00672
    00680 #ifndef CS_DECLARE_STATIC_CLASSVAR
    00681 #define CS_DECLARE_STATIC_CLASSVAR(var,getterFunc,Type)       \
    00682 static Type *var;                                             \
    00683 static Type *getterFunc ();                                   \
    00684 static void getterFunc ## _kill ();                           \
    00685 static void getterFunc ## _kill_array ();
    00686 #endif
    00687
    00688 #ifndef CS_DECLARE_STATIC_CLASSVAR_REF
    00689 #define CS_DECLARE_STATIC_CLASSVAR_REF(var,getterFunc,Type)   \
    00690 static Type *var;                                             \
    00691 static Type &getterFunc ();                                   \
    00692 static void getterFunc ## _kill ();                           \
    00693 static void getterFunc ## _kill_array ();
    00694 #endif
    00695
    00706 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_EXT
    00707 #define CS_IMPLEMENT_STATIC_CLASSVAR_EXT(Class,var,getterFunc,Type,initParam,\
    00708   kill_how)                                                     \
    00709 Type* Class::var = 0;                                           \
    00710 void Class::getterFunc ## _kill ()                              \
    00711 {                                                               \
    00712   delete getterFunc ();                                         \
    00713   var = 0;                                                      \
    00714 }                                                               \
    00715 void Class::getterFunc ## _kill_array ()                        \
    00716 {                                                               \
    00717   delete [] getterFunc ();                                      \
    00718   var = 0;                                                      \
    00719 }                                                               \
    00720 Type* Class::getterFunc ()                                      \
    00721 {                                                               \
    00722   Type* p;                                                      \
    00723   CS_STATIC_VAR_GETTER_COMMON(Type, p, initParam, var,          \
    00724     getterFunc ## kill_how);                                    \
    00725   return p;                                                     \
    00726 }
    00727 #endif
    00728
    00729 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR
    00730 #define CS_IMPLEMENT_STATIC_CLASSVAR(Class,var,getterFunc,Type,initParam) \
    00731   CS_IMPLEMENT_STATIC_CLASSVAR_EXT(Class,var,getterFunc,Type,initParam,_kill)
    00732 #endif
    00733
    00734 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_ARRAY
    00735 #define CS_IMPLEMENT_STATIC_CLASSVAR_ARRAY(Class,var,getterFunc,Type,\
    00736   initParam) \
    00737   CS_IMPLEMENT_STATIC_CLASSVAR_EXT(Class,var,getterFunc,Type,initParam,\
    00738     _kill_array)
    00739 #endif
    00740
    00741 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_REF_EXT
    00742 #define CS_IMPLEMENT_STATIC_CLASSVAR_REF_EXT(Class,var,getterFunc,Type,\
    00743   initParam,kill_how) \
    00744 Type *Class::var = 0;                                          \
    00745 void Class::getterFunc ## _kill ()                             \
    00746 {                                                              \
    00747   delete &getterFunc ();                                       \
    00748   var = 0;                                                     \
    00749 }                                                              \
    00750   void Class::getterFunc ## _kill_array ()                     \
    00751 {                                                              \
    00752   delete [] &getterFunc ();                                    \
    00753   var = 0;                                                     \
    00754 }                                                              \
    00755 Type &Class::getterFunc ()                                     \
    00756 {                                                              \
    00757   Type* p;                                                      \
    00758   CS_STATIC_VAR_GETTER_COMMON(Type, p, initParam, var,          \
    00759     getterFunc ## kill_how);                                    \
    00760   return *p;                                                    \
    00761 }
    00762 #endif
    00763
    00764 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_REF
    00765 #define CS_IMPLEMENT_STATIC_CLASSVAR_REF(Class,var,getterFunc,Type,initParam)\
    00766   CS_IMPLEMENT_STATIC_CLASSVAR_REF_EXT(Class,var,getterFunc,Type,\
    00767     initParam,_kill)
    00768 #endif
    00769
    00770 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_REF_ARRAY
    00771 #define CS_IMPLEMENT_STATIC_CLASSVAR_REF_ARRAY(Class,var,getterFunc,Type,\
    00772   initParam) \
    00773   CS_IMPLEMENT_STATIC_CLASSVAR_REF_EXT(Class,var,getterFunc,Type,initParam,\
    00774     _kill_array)
    00775 #endif
    00776
    00781 #if defined(CS_COMPILER_GCC)
    00782 #  define CS_FUNCTION_NAME              __PRETTY_FUNCTION__
    00783 #elif defined(__FUNCTION__)
    00784 #  define CS_FUNCTION_NAME              __FUNCTION__
    00785 #else
    00786 #  define CS_FUNCTION_NAME              "<?\?\?>"
    00787 #endif
    00788
    00789 #include <stdlib.h>
    00790 #ifdef CS_HAVE_MALLOC_H
    00791 #include <malloc.h>
    00792 #endif
    00793 #include <new>
    00794
    00795 #ifndef CS_NO_PTMALLOC
    00796
    00797
    00801 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc (size_t n);
    00802 extern CS_CRYSTALSPACE_EXPORT void ptfree (void* p);
    00803 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc (void* p, size_t n);
    00804 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc (size_t n,
    00805   size_t s);
    00807
    00809
    00813 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc_sentinel (
    00814   size_t n);
    00815 extern CS_CRYSTALSPACE_EXPORT void ptfree_sentinel (void* p);
    00816 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc_sentinel (void* p, size_t n);
    00817 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc_sentinel (
    00818   size_t n, size_t s);
    00820
    00822
    00826 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc_located (
    00827   size_t n);
    00828 extern CS_CRYSTALSPACE_EXPORT void ptfree_located (void* p);
    00829 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc_located (void* p, size_t n);
    00830 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc_located (
    00831   size_t n, size_t s);
    00833
    00835
    00839 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc_checking (
    00840   size_t n);
    00841 extern CS_CRYSTALSPACE_EXPORT void ptfree_checking (void* p);
    00842 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc_checking (void* p, size_t n);
    00843 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc_checking (
    00844   size_t n, size_t s);
    00846
    00847 #ifndef CS_DEBUG
    00848 #  undef CS_EXTENSIVE_MEMDEBUG
    00849 #  undef CS_REF_TRACKER
    00850 #else
    00851 #  if defined(CS_EXTENSIVE_MEMDEBUG) && defined(CS_MEMORY_TRACKER)
    00852 #    error Do not use CS_EXTENSIVE_MEMDEBUG and CS_MEMORY_TRACKER together!
    00853 #  endif
    00854 #endif
    00855
    00856 #endif // CS_NO_PTMALLOC
    00857
    00863 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* cs_malloc (size_t n);
    00864 extern CS_CRYSTALSPACE_EXPORT void cs_free (void* p);
    00865 extern CS_CRYSTALSPACE_EXPORT void* cs_realloc (void* p, size_t n);
    00866 extern CS_CRYSTALSPACE_EXPORT void* cs_calloc (size_t n, size_t s);
    00868
    00869 namespace CS
    00870 {
    00871   template <class T>
    00872   class StackArrayHelper
    00873   {
    00874   private:
    00875     void* memory;
    00876     bool deleteme;
    00877
    00878   public:
    00879     StackArrayHelper (void* memory, bool deleteme)
    00880       : memory (memory), deleteme (deleteme) { }
    00881     ~StackArrayHelper () { if (deleteme) cs_free (memory); }
    00882   };
    00883 }
    00884
    00894 #define CS_ALLOC_STACK_ARRAY_FALLBACK(Type, Name, Size, Thresshold) \
    00895   Type* Name = ((Size) > (Thresshold)) ? \
    00896         (Type*)cs_malloc((Size)*sizeof(Type)) : \
    00897         (Type*)alloca((Size)*sizeof(Type)); \
    00898   CS::StackArrayHelper<Type> Name##Del (Name, ((Size) > (Thresshold)));
    00899
    00900
    00901 #ifdef CS_USE_CUSTOM_ISDIR
    00902 static inline bool isdir (const char *path, struct dirent *de)
    00903 {
    00904   int pathlen = strlen (path);
    00905   char* fullname = new char[pathlen + 2 + strlen (de->d_name)];
    00906   memcpy (fullname, path, pathlen + 1);
    00907   if ((pathlen) && (fullname[pathlen-1] != CS_PATH_SEPARATOR))
    00908   {
    00909     fullname[pathlen++] = CS_PATH_SEPARATOR;
    00910     fullname[pathlen] = 0;
    00911   }
    00912   strcat (&fullname [pathlen], de->d_name);
    00913   struct stat st;
    00914   stat (fullname, &st);
    00915   delete[] fullname;
    00916   return ((st.st_mode & S_IFMT) == S_IFDIR);
    00917 }
    00918 #endif
    00919
    00920
    00921 // The following define should only be enabled if you have defined
    00922 // a special version of overloaded new that accepts two additional
    00923 // parameters: a (void*) pointing to the filename and an int with the
    00924 // line number. This is typically used for memory debugging.
    00925 // In csutil/memdebug.cpp there is a memory debugger which can (optionally)
    00926 // use this feature. Note that if CS_EXTENSIVE_MEMDEBUG is enabled while
    00927 // the memory debugger is not the memory debugger will still provide the
    00928 // needed overloaded operators so you can leave CS_EXTENSIVE_MEMDEBUG on in
    00929 // that case and the only overhead will be a little more arguments to 'new'.
    00930 // Do not enable CS_EXTENSIVE_MEMDEBUG if your platform or your own code
    00931 // defines its own 'new' operator, since this version will interfere with your
    00932 // own.
    00933 // CS_MEMORY_TRACKER is treated like CS_EXTENSIVE_MEMDEBUG here.
    00934 #if defined(CS_EXTENSIVE_MEMDEBUG) || defined(CS_MEMORY_TRACKER)
    00935 extern CS_CRYSTALSPACE_EXPORT void operator delete (void* p);
    00936 extern CS_CRYSTALSPACE_EXPORT void operator delete[] (void* p);
    00937
    00938 extern CS_CRYSTALSPACE_EXPORT void* operator new (size_t s,
    00939   void* filename, int line);
    00940 inline void operator delete (void* p, void*, int) { operator delete (p); }
    00941 extern CS_CRYSTALSPACE_EXPORT void* operator new[] (size_t s,
    00942   void* filename, int line);
    00943 inline void operator delete[] (void* p, void*, int) { operator delete[] (p); }
    00944
    00945 inline void* operator new (size_t s)
    00946 { return operator new (s, (void*)__FILE__, 0); }
    00947 inline void* operator new[] (size_t s)
    00948 { return operator new (s, (void*)__FILE__, 0); }
    00949
    00950 #define CS_EXTENSIVE_MEMDEBUG_NEW new ((void*)CS_FUNCTION_NAME, __LINE__)
    00951 #define new CS_EXTENSIVE_MEMDEBUG_NEW
    00952 #endif
    00953
    00954 namespace CS
    00955 {
    00956   namespace Debug
    00957   {
    00958     extern void CS_CRYSTALSPACE_EXPORT AssertMessage (const char* expr,
    00959       const char* filename, int line, const char* msg = 0);
    00960
    00967     static inline void DebugBreak ()
    00968     {
    00969     #  if defined (CS_PLATFORM_WIN32)
    00970       ::DebugBreak();
    00971     #  else
    00972       raise (SIGTRAP);
    00973     #  endif
    00974     }
    00975
    00981     extern bool CS_CRYSTALSPACE_EXPORT VerifyAllMemory ();
    00986     extern void CS_CRYSTALSPACE_EXPORT DumpAllocateMemoryBlocks ();
    00987   } // namespace Debug
    00988 } // namespace CS
    00989
    00990 #if defined(CS_DEBUG) || defined(CS_WITH_ASSERTIONS)
    00991 #  define CS_DEBUG_BREAK        CS::Debug::DebugBreak()
    00992 #  if !defined (CS_ASSERT_MSG)
    00993 #   define CS_ASSERT_MSG(msg,x)                                         \
    00994       if (!(x)) CS::Debug::AssertMessage (#x, __FILE__, __LINE__, msg);
    00995 #  endif
    00996 #  if !defined (CS_ASSERT)
    00997 #    define CS_ASSERT(x)        CS_ASSERT_MSG(0, x)
    00998 #  endif
    00999 #else
    01000 #  undef  CS_DEBUG_BREAK
    01001 #  define CS_DEBUG_BREAK
    01002 #  undef  CS_ASSERT
    01003 #  define CS_ASSERT(x)          (void)0
    01004 #  undef  CS_ASSERT_MSG
    01005 #  define CS_ASSERT_MSG(m,x)    (void)0
    01006 #endif
    01007
    01023 // Check if the csosdefs.h defined either CS_LITTLE_ENDIAN or CS_BIG_ENDIAN
    01024 #if !defined (CS_LITTLE_ENDIAN) && !defined (CS_BIG_ENDIAN)
    01025 #  error No CS_XXX_ENDIAN macro defined in your OS-specific csosdefs.h!
    01026 #endif
    01027
    01028 /*
    01029  * This is a bit of overkill but if you're sure your CPU doesn't require
    01030  * strict alignment add your CPU to the !defined below to get slightly
    01031  * smaller and faster code in some cases.
    01032  *
    01033  * \todo In the future, this should be moved to csconfig.h and determined as
    01034  * part of the configuration process.
    01035  */
    01036 #if defined (CS_PROCESSOR_SPARC)
    01037 #  define CS_STRICT_ALIGNMENT
    01038 #endif
    01039
    01040 // Adjust some definitions contained in csconfig.h
    01041 #if !defined (CS_PROCESSOR_X86) || !defined (CS_HAVE_NASM)
    01042 #  undef CS_HAVE_MMX
    01043 #  undef CS_HAVE_NASM
    01044 #endif
    01045
    01046 // Use special knowledge of IEEE float format in some cases for CPU's that are
    01047 // known to support it
    01048 #if !defined (CS_IEEE_DOUBLE_FORMAT)
    01049 #  if defined (CS_PROCESSOR_X86) || \
    01050       defined (CS_PROCESSOR_POWERPC) || \
    01051       defined (CS_PROCESSOR_MIPS) || \
    01052       defined (CS_PROCESSOR_SPARC) || \
    01053       defined (CS_PROCESSOR_ALPHA) || \
    01054       defined (CS_PROCESSOR_M68K) || \
    01055       defined (CS_PROCESSOR_ARM)
    01056 #    define CS_IEEE_DOUBLE_FORMAT
    01057 #  endif
    01058 #endif
    01059
    01060 // gcc can perform usefull checking for printf/scanf format strings, just add
    01061 // this define at the end of the function declaration
    01062 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
    01063 /* Newer GCCs know different 'archetypes' of format string styles.
    01064  * CS format strings are on the level of the GNU C library, so use that
    01065  * archetype. */
    01066 #  define CS_GNUC_PRINTF(format_idx, arg_idx) \
    01067      __attribute__((format (gnu_printf, format_idx, arg_idx)))
    01068 #  define CS_GNUC_SCANF(format_idx, arg_idx) \
    01069      __attribute__((format (gnu_scanf, format_idx, arg_idx)))
    01070 // Unfortunately, gcc doesn't support format argument checking for wide strings
    01071 #  define CS_GNUC_WPRINTF(format_idx, arg_idx) \
    01072      /*__attribute__((format (__wprintf__, format_idx, arg_idx)))*/
    01073 #  define CS_GNUC_WSCANF(format_idx, arg_idx) \
    01074      /*__attribute__((format (__wscanf__, format_idx, arg_idx)))*/
    01075 #elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
    01076 // Use default archetype for older versions.
    01077 #  define CS_GNUC_PRINTF(format_idx, arg_idx) \
    01078      __attribute__((format (__printf__, format_idx, arg_idx)))
    01079 #  define CS_GNUC_SCANF(format_idx, arg_idx) \
    01080      __attribute__((format (__scanf__, format_idx, arg_idx)))
    01081 // Unfortunately, gcc doesn't support format argument checking for wide strings
    01082 #  define CS_GNUC_WPRINTF(format_idx, arg_idx) \
    01083      /*__attribute__((format (__wprintf__, format_idx, arg_idx)))*/
    01084 #  define CS_GNUC_WSCANF(format_idx, arg_idx) \
    01085      /*__attribute__((format (__wscanf__, format_idx, arg_idx)))*/
    01086 #else
    01087 #  define CS_GNUC_PRINTF(format_idx, arg_idx)
    01088 #  define CS_GNUC_SCANF(format_idx, arg_idx)
    01089 #  define CS_GNUC_WPRINTF(format_idx, arg_idx)
    01090 #  define CS_GNUC_WSCANF(format_idx, arg_idx)
    01091 #endif
    01092
    01093 // Remove __attribute__ on non GNUC compilers.
    01094 #ifndef __GNUC__
    01095 #define __attribute__(x)
    01096 #endif
    01097
    01098 // Support for alignment and packing of structures.
    01099 #if !defined(CS_STRUCT_ALIGN_4BYTE_BEGIN)
    01100 #  if defined(__GNUC__) && defined(CS_STRICT_ALIGNMENT)
    01101 #    define CS_STRUCT_ALIGN_4BYTE_BEGIN
    01102 #    define CS_STRUCT_ALIGN_4BYTE_END __attribute__ ((aligned(4)))
    01103 #  else
    01104 #    define CS_STRUCT_ALIGN_4BYTE_BEGIN
    01105 #    define CS_STRUCT_ALIGN_4BYTE_END
    01106 #  endif
    01107 #endif
    01108
    01109 #if defined(CS_COMPILER_MSVC)
    01110   #define CS_ALIGNED_MEMBER(Member, Align)                              \
    01111     __declspec(align(Align)) Member
    01112   #define CS_ALIGNED_STRUCT(Kind, Align)                                \
    01113     __declspec(align(Align)) Kind
    01114 #elif defined(CS_COMPILER_GCC)
    01115
    01127   #define CS_ALIGNED_MEMBER(Member, Align)                              \
    01128     Member __attribute__((aligned(Align)))
    01129
    01140   #define CS_ALIGNED_STRUCT(Kind, Align)                                \
    01141     Kind __attribute__((aligned(Align)))
    01142 #else
    01143   #define CS_ALIGNED_MEMBER(Member, Align)      Member
    01144   #define CS_ALIGNED_STRUCT(Kind, Align)                Kind
    01145 #endif
    01146
    01147 // Macro used to define static implicit pointer conversion function.
    01148 // Only use within a class declaration.
    01149 #ifndef _CS_IMPLICITPTRCAST_NAME
    01150 #  define _CS_IMPLICITPTRCAST_NAME __ImplicitPtrCast
    01151 #endif
    01152
    01174 #define CS_IMPLEMENT_IMPLICIT_PTR_CAST(classname) \
    01175   inline static classname* _CS_IMPLICITPTRCAST_NAME (classname* ptr) \
    01176   { \
    01177     return ptr;\
    01178   }
    01179
    01188 #define CS_IMPLICIT_PTR_CAST(classname, ptr) \
    01189   (classname::_CS_IMPLICITPTRCAST_NAME(ptr))
    01190
    01194 #ifdef CS_HAVE_VA_COPY
    01195 #  define CS_VA_COPY(dest, src)         va_copy(dest, src)
    01196 #else
    01197 #  ifdef CS_HAVE___VA_COPY
    01198 #    define CS_VA_COPY(dest, src)       __va_copy(dest, src)
    01199 #  else
    01200 #    define CS_VA_COPY(dest, src)       dest = src;
    01201 #  endif
    01202 #endif
    01203
    01204 #define CS_STRING_TO_WIDE_(x)   L ## x
    01205
    01212 #define CS_STRING_TO_WIDE(x)    CS_STRING_TO_WIDE_(x)
    01213
    01214 #ifdef PACKAGE_NAME
    01215 # define CS_NAMESPACE_PACKAGE_NAME       PACKAGE_NAME
    01216 #else
    01217 # define CS_NAMESPACE_PACKAGE_NAME       CS
    01218 #endif
    01219
    01243 #define CS_PLUGIN_NAMESPACE_BEGIN(name)                                     \
    01244   namespace CS_NAMESPACE_PACKAGE_NAME { namespace Plugin { namespace name
    01245 #define CS_PLUGIN_NAMESPACE_END(name)                                       \
    01246   } }
    01247 #define CS_PLUGIN_NAMESPACE_NAME(name)                                      \
    01248   CS_NAMESPACE_PACKAGE_NAME::Plugin::name
    01249
    01262 #if defined(CS_COMPILER_GCC) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1))
    01263 # define CS_DEPRECATION_WARNINGS_DISABLE        \
    01264   _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
    01265 # define CS_DEPRECATION_WARNINGS_ENABLE \
    01266   _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"")
    01267 #else
    01268 # define CS_DEPRECATION_WARNINGS_DISABLE
    01269 # define CS_DEPRECATION_WARNINGS_ENABLE
    01270 #endif
    01271
    01272 namespace CS
    01273 {
    01274   namespace deprecated
    01275   {
    01276     CS_DEPRECATED_METHOD_MSG("Use CS::Platform::CreateDirectory() instead")
    01277     CS_CRYSTALSPACE_EXPORT int CS_MKDIR (const char* path);
    01278   } // namespace deprecated
    01279 } // namespace CS
    01280
    01281 #define CS_MKDIR(path)    CS::deprecated::CS_MKDIR(path)
    01282
    01283 // Include nullptr fallback (for convenience).
    01284 #include "csutil/nullptr.h"
    01285
    01286 #endif // __CS_CSSYSDEF_H__