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__
Generated for Crystal Space 2.0 by doxygen 1.6.1
