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 00302 #if defined(CS_COMPILER_GCC) && !defined(__STRICT_ANSI__) 00303 // In GCC we are able to declare stack vars of dynamic size directly 00304 # define CS_ALLOC_STACK_ARRAY(type, var, size) \ 00305 type var [size] 00306 #else 00307 # include <stdlib.h> 00308 # define CS_ALLOC_STACK_ARRAY(type, var, size) \ 00309 type *var = (type *)alloca ((size) * sizeof (type)) 00310 # if defined(CS_COMPILER_GCC) && defined(__STRICT_ANSI__) && !defined(alloca) 00311 # define alloca(x) __builtin_alloca(x) 00312 # endif 00313 #endif 00314 00315 00339 #define CS_HEADER_GLOBAL(X,Y) CS_HEADER_GLOBAL_COMPOSE(X,Y) 00340 #define CS_HEADER_GLOBAL_COMPOSE(X,Y) <X/Y> 00341 00354 #define CS_HEADER_LOCAL(X,Y) CS_HEADER_LOCAL_COMPOSE1(X,Y) 00355 #define CS_HEADER_LOCAL_COMPOSE1(X,Y) CS_HEADER_LOCAL_COMPOSE2(X/Y) 00356 #define CS_HEADER_LOCAL_COMPOSE2(X) #X 00357 00358 00364 #if !defined(CS_EXPORTED_FUNCTION) 00365 # if defined(CS_STATIC_LINKED) 00366 # define CS_EXPORTED_FUNCTION extern "C" 00367 # else 00368 # define CS_EXPORTED_FUNCTION extern "C" CS_EXPORT_SYM_DLL 00369 # endif 00370 #endif 00371 00383 #if !defined(CS_EXPORTED_NAME) 00384 # define CS_EXPORTED_NAME(Prefix, Suffix) Prefix ## Suffix 00385 #endif 00386 00387 #ifndef CS_IMPLEMENT_PLATFORM_PLUGIN 00388 # define CS_IMPLEMENT_PLATFORM_PLUGIN 00389 #endif 00390 00391 #ifndef CS_IMPLEMENT_PLATFORM_APPLICATION 00392 # define CS_IMPLEMENT_PLATFORM_APPLICATION 00393 #endif 00394 00401 #ifndef CS_INITIALIZE_PLATFORM_APPLICATION 00402 # define CS_INITIALIZE_PLATFORM_APPLICATION /* */ 00403 /* 00404 This definition may seem odd, but it's here for doxygen's sake, which 00405 apparently fails to document empty macro definitions. 00406 */ 00407 #endif 00408 00409 typedef void (*csStaticVarCleanupFN) (void (*p)()); 00410 extern csStaticVarCleanupFN csStaticVarCleanup; 00411 00412 #include "csutil/threading/atomicops.h" 00413 #include "csutil/threading/mutex.h" 00414 00415 #define CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION_A(Name, FuncAttr) \ 00416 static CS::Threading::Mutex Name_ ## staticVarLock; \ 00417 FuncAttr void Name (void (*p)()) \ 00418 { \ 00419 CS::Threading::MutexScopedLock lock (Name_ ## staticVarLock); \ 00420 static void (**a)() = 0; \ 00421 static int lastEntry = 0; \ 00422 static int maxEntries = 0; \ 00423 \ 00424 if (p != 0) \ 00425 { \ 00426 if (lastEntry >= maxEntries) \ 00427 { \ 00428 maxEntries += 10; \ 00429 if (a == 0) \ 00430 a = (void (**)())malloc(maxEntries * sizeof(void*)); \ 00431 else \ 00432 a = (void (**)())realloc(a, maxEntries * sizeof(void*)); \ 00433 } \ 00434 a[lastEntry++] = p; \ 00435 } \ 00436 else if (a != 0) \ 00437 { \ 00438 for (int i = lastEntry - 1; i >= 0; i--) \ 00439 a[i] (); \ 00440 free (a); \ 00441 a = 0; \ 00442 lastEntry = 0; \ 00443 maxEntries = 0; \ 00444 } \ 00445 } 00446 #ifndef CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION 00447 # define CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION(Name) \ 00448 CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION_A(Name, ) 00449 #endif 00450 00451 #ifndef CS_DEFINE_STATIC_VARIABLE_REGISTRATION 00452 # define CS_DEFINE_STATIC_VARIABLE_REGISTRATION(func) \ 00453 csStaticVarCleanupFN csStaticVarCleanup = &func 00454 #endif 00455 00456 #ifndef CS_DECLARE_STATIC_VARIABLE_REGISTRATION 00457 # define CS_DECLARE_STATIC_VARIABLE_REGISTRATION(func) \ 00458 void func (void (*p)()) 00459 #endif 00460 00461 #ifndef CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION 00462 # define CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION \ 00463 CS_CRYSTALSPACE_EXPORT \ 00464 CS_DECLARE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_csutil); 00465 #endif 00466 00467 #if defined(CS_EXTENSIVE_MEMDEBUG) || defined(CS_MEMORY_TRACKER) 00468 # define CS_DEFINE_MEMTRACKER_MODULE \ 00469 class csMemTrackerModule; \ 00470 namespace CS \ 00471 { \ 00472 namespace Debug \ 00473 { \ 00474 namespace MemTracker \ 00475 { \ 00476 namespace Impl \ 00477 { \ 00478 csMemTrackerModule* thisModule = 0; \ 00479 } \ 00480 } \ 00481 } \ 00482 } 00483 #else 00484 # define CS_DEFINE_MEMTRACKER_MODULE 00485 #endif 00486 00506 #ifndef CS_IMPLEMENT_FOREIGN_DLL 00507 # if defined(CS_BUILD_SHARED_LIBS) 00508 # define CS_IMPLEMENT_FOREIGN_DLL \ 00509 CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION(csStaticVarCleanup_local); \ 00510 CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_local); \ 00511 CS_DEFINE_MEMTRACKER_MODULE 00512 # else 00513 # define CS_IMPLEMENT_FOREIGN_DLL \ 00514 CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION \ 00515 CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_csutil); \ 00516 CS_DEFINE_MEMTRACKER_MODULE 00517 # endif 00518 #endif 00519 00528 #if defined(CS_STATIC_LINKED) 00529 00530 # ifndef CS_IMPLEMENT_PLUGIN 00531 # define CS_IMPLEMENT_PLUGIN \ 00532 CS_IMPLEMENT_PLATFORM_PLUGIN 00533 # endif 00534 00535 #elif !defined(CS_BUILD_SHARED_LIBS) 00536 00537 # ifndef CS_IMPLEMENT_PLUGIN 00538 # define CS_IMPLEMENT_PLUGIN \ 00539 CS_IMPLEMENT_PLATFORM_PLUGIN \ 00540 CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION \ 00541 CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_csutil); \ 00542 CS_DEFINE_MEMTRACKER_MODULE 00543 # endif 00544 00545 #else 00546 00547 # ifndef CS_IMPLEMENT_PLUGIN 00548 # define CS_IMPLEMENT_PLUGIN \ 00549 CS_IMPLEMENT_STATIC_VARIABLE_REGISTRATION(csStaticVarCleanup_local) \ 00550 CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_local); \ 00551 CS_IMPLEMENT_PLATFORM_PLUGIN \ 00552 CS_DEFINE_MEMTRACKER_MODULE 00553 # endif 00554 00555 #endif 00556 00565 #ifndef CS_IMPLEMENT_APPLICATION 00566 # define CS_IMPLEMENT_APPLICATION \ 00567 CS_DECLARE_DEFAULT_STATIC_VARIABLE_REGISTRATION \ 00568 CS_DEFINE_STATIC_VARIABLE_REGISTRATION (csStaticVarCleanup_csutil); \ 00569 CS_IMPLEMENT_PLATFORM_APPLICATION \ 00570 CS_DEFINE_MEMTRACKER_MODULE 00571 #endif 00572 00576 #ifndef CS_REGISTER_STATIC_FOR_DESTRUCTION 00577 #define CS_REGISTER_STATIC_FOR_DESTRUCTION(getterFunc)\ 00578 csStaticVarCleanup (getterFunc); 00579 #endif 00580 00584 #ifndef CS_STATIC_VARIABLE_CLEANUP 00585 #define CS_STATIC_VARIABLE_CLEANUP \ 00586 csStaticVarCleanup (0); 00587 #endif 00588 00589 /* Body of getter function, mostly the same across different CS_STATIC_VAR_* 00590 variants. 00591 'Ptr' is a variable of type 'Type*' that receives the value of 'Val' (where 00592 the actual object is stored). See CS_IMPLEMENT_STATIC_VAR for explanation 00593 of initParam and kill_how. 00594 00595 'Val' is read atomically. If it's 0, a new object is created. If another 00596 thread concurrently requests the value, it's ensured that the value is 00597 consistent (both the returned and stored value). 00598 */ 00599 #define CS_STATIC_VAR_GETTER_COMMON(Type, Ptr, initParam, Val, kill_how)\ 00600 while (true) \ 00601 { \ 00602 Ptr = reinterpret_cast<Type*> ( \ 00603 CS::Threading::AtomicOperations::Read ( \ 00604 reinterpret_cast<void**> (&Val))); \ 00605 if (Ptr != 0) break; \ 00606 Ptr = new Type initParam; \ 00607 if (CS::Threading::AtomicOperations::CompareAndSet ( \ 00608 reinterpret_cast<void**> (&Val), Ptr, 0) != 0) \ 00609 { \ 00610 delete Ptr; \ 00611 } \ 00612 else \ 00613 { \ 00614 csStaticVarCleanup (kill_how); \ 00615 break; \ 00616 } \ 00617 } 00618 00631 #ifndef CS_IMPLEMENT_STATIC_VAR_EXT 00632 #define CS_IMPLEMENT_STATIC_VAR_EXT(getterFunc,Type,initParam,kill_how) \ 00633 namespace { \ 00634 static Type* getterFunc ## _v = 0; \ 00635 static Type* getterFunc (); \ 00636 static void getterFunc ## _kill (); \ 00637 static void getterFunc ## _kill_array (); \ 00638 void getterFunc ## _kill () \ 00639 { \ 00640 (void)(&getterFunc ## _kill_array); \ 00641 delete getterFunc ## _v; \ 00642 getterFunc ## _v = 0; \ 00643 } \ 00644 void getterFunc ## _kill_array () \ 00645 { \ 00646 (void)(&getterFunc ## _kill); \ 00647 delete [] getterFunc ## _v; \ 00648 getterFunc ## _v = 0; \ 00649 } \ 00650 Type* getterFunc () \ 00651 { \ 00652 Type* p; \ 00653 CS_STATIC_VAR_GETTER_COMMON(Type, p, initParam, getterFunc ## _v, \ 00654 getterFunc ## kill_how); \ 00655 return p; \ 00656 } \ 00657 } 00658 #endif 00659 00660 #ifndef CS_IMPLEMENT_STATIC_VAR 00661 #define CS_IMPLEMENT_STATIC_VAR(getterFunc,Type,initParam) \ 00662 CS_IMPLEMENT_STATIC_VAR_EXT(getterFunc,Type,initParam,_kill) 00663 #endif 00664 00665 #ifndef CS_IMPLEMENT_STATIC_VAR_ARRAY 00666 #define CS_IMPLEMENT_STATIC_VAR_ARRAY(getterFunc,Type,initParam) \ 00667 CS_IMPLEMENT_STATIC_VAR_EXT(getterFunc,Type,initParam,_kill_array) 00668 #endif 00669 00677 #ifndef CS_DECLARE_STATIC_CLASSVAR 00678 #define CS_DECLARE_STATIC_CLASSVAR(var,getterFunc,Type) \ 00679 static Type *var; \ 00680 static Type *getterFunc (); \ 00681 static void getterFunc ## _kill (); \ 00682 static void getterFunc ## _kill_array (); 00683 #endif 00684 00685 #ifndef CS_DECLARE_STATIC_CLASSVAR_REF 00686 #define CS_DECLARE_STATIC_CLASSVAR_REF(var,getterFunc,Type) \ 00687 static Type *var; \ 00688 static Type &getterFunc (); \ 00689 static void getterFunc ## _kill (); \ 00690 static void getterFunc ## _kill_array (); 00691 #endif 00692 00703 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_EXT 00704 #define CS_IMPLEMENT_STATIC_CLASSVAR_EXT(Class,var,getterFunc,Type,initParam,\ 00705 kill_how) \ 00706 Type* Class::var = 0; \ 00707 void Class::getterFunc ## _kill () \ 00708 { \ 00709 delete getterFunc (); \ 00710 var = 0; \ 00711 } \ 00712 void Class::getterFunc ## _kill_array () \ 00713 { \ 00714 delete [] getterFunc (); \ 00715 var = 0; \ 00716 } \ 00717 Type* Class::getterFunc () \ 00718 { \ 00719 Type* p; \ 00720 CS_STATIC_VAR_GETTER_COMMON(Type, p, initParam, var, \ 00721 getterFunc ## kill_how); \ 00722 return p; \ 00723 } 00724 #endif 00725 00726 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR 00727 #define CS_IMPLEMENT_STATIC_CLASSVAR(Class,var,getterFunc,Type,initParam) \ 00728 CS_IMPLEMENT_STATIC_CLASSVAR_EXT(Class,var,getterFunc,Type,initParam,_kill) 00729 #endif 00730 00731 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_ARRAY 00732 #define CS_IMPLEMENT_STATIC_CLASSVAR_ARRAY(Class,var,getterFunc,Type,\ 00733 initParam) \ 00734 CS_IMPLEMENT_STATIC_CLASSVAR_EXT(Class,var,getterFunc,Type,initParam,\ 00735 _kill_array) 00736 #endif 00737 00738 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_REF_EXT 00739 #define CS_IMPLEMENT_STATIC_CLASSVAR_REF_EXT(Class,var,getterFunc,Type,\ 00740 initParam,kill_how) \ 00741 Type *Class::var = 0; \ 00742 void Class::getterFunc ## _kill () \ 00743 { \ 00744 delete &getterFunc (); \ 00745 var = 0; \ 00746 } \ 00747 void Class::getterFunc ## _kill_array () \ 00748 { \ 00749 delete [] &getterFunc (); \ 00750 var = 0; \ 00751 } \ 00752 Type &Class::getterFunc () \ 00753 { \ 00754 Type* p; \ 00755 CS_STATIC_VAR_GETTER_COMMON(Type, p, initParam, var, \ 00756 getterFunc ## kill_how); \ 00757 return *p; \ 00758 } 00759 #endif 00760 00761 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_REF 00762 #define CS_IMPLEMENT_STATIC_CLASSVAR_REF(Class,var,getterFunc,Type,initParam)\ 00763 CS_IMPLEMENT_STATIC_CLASSVAR_REF_EXT(Class,var,getterFunc,Type,\ 00764 initParam,_kill) 00765 #endif 00766 00767 #ifndef CS_IMPLEMENT_STATIC_CLASSVAR_REF_ARRAY 00768 #define CS_IMPLEMENT_STATIC_CLASSVAR_REF_ARRAY(Class,var,getterFunc,Type,\ 00769 initParam) \ 00770 CS_IMPLEMENT_STATIC_CLASSVAR_REF_EXT(Class,var,getterFunc,Type,initParam,\ 00771 _kill_array) 00772 #endif 00773 00778 #if defined(CS_COMPILER_GCC) 00779 # define CS_FUNCTION_NAME __PRETTY_FUNCTION__ 00780 #elif defined( __FUNCSIG__ ) 00781 # define CS_FUNCTION_NAME __FUNCSIG__ 00782 #elif defined(__FUNCTION__) 00783 # define CS_FUNCTION_NAME __FUNCTION__ 00784 #else 00785 # define CS_FUNCTION_NAME "<?\?\?>" 00786 #endif 00787 00788 #include <stdlib.h> 00789 #ifdef CS_HAVE_MALLOC_H 00790 #include <malloc.h> 00791 #endif 00792 #include <new> 00793 00794 #ifndef CS_NO_PTMALLOC 00795 00796 00800 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc (size_t n); 00801 extern CS_CRYSTALSPACE_EXPORT void ptfree (void* p); 00802 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc (void* p, size_t n); 00803 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc (size_t n, 00804 size_t s); 00806 00808 00812 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc_sentinel ( 00813 size_t n); 00814 extern CS_CRYSTALSPACE_EXPORT void ptfree_sentinel (void* p); 00815 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc_sentinel (void* p, size_t n); 00816 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc_sentinel ( 00817 size_t n, size_t s); 00819 00821 00825 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc_located ( 00826 size_t n); 00827 extern CS_CRYSTALSPACE_EXPORT void ptfree_located (void* p); 00828 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc_located (void* p, size_t n); 00829 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc_located ( 00830 size_t n, size_t s); 00832 00834 00838 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc_checking ( 00839 size_t n); 00840 extern CS_CRYSTALSPACE_EXPORT void ptfree_checking (void* p); 00841 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc_checking (void* p, size_t n); 00842 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc_checking ( 00843 size_t n, size_t s); 00845 00846 #ifndef CS_DEBUG 00847 # undef CS_EXTENSIVE_MEMDEBUG 00848 # undef CS_REF_TRACKER 00849 #else 00850 # if defined(CS_EXTENSIVE_MEMDEBUG) && defined(CS_MEMORY_TRACKER) 00851 # error Do not use CS_EXTENSIVE_MEMDEBUG and CS_MEMORY_TRACKER together! 00852 # endif 00853 #endif 00854 00855 #endif // CS_NO_PTMALLOC 00856 00862 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* cs_malloc (size_t n); 00863 extern CS_CRYSTALSPACE_EXPORT void cs_free (void* p); 00864 extern CS_CRYSTALSPACE_EXPORT void* cs_realloc (void* p, size_t n); 00865 extern CS_CRYSTALSPACE_EXPORT void* cs_calloc (size_t n, size_t s); 00867 00868 namespace CS 00869 { 00870 template <class T> 00871 class StackArrayHelper 00872 { 00873 private: 00874 void* memory; 00875 bool deleteme; 00876 00877 public: 00878 StackArrayHelper (void* memory, bool deleteme) 00879 : memory (memory), deleteme (deleteme) { } 00880 ~StackArrayHelper () { if (deleteme) cs_free (memory); } 00881 }; 00882 } 00883 00893 #define CS_ALLOC_STACK_ARRAY_FALLBACK(Type, Name, Size, Thresshold) \ 00894 Type* Name = ((Size) > (Thresshold)) ? \ 00895 (Type*)cs_malloc((Size)*sizeof(Type)) : \ 00896 (Type*)alloca((Size)*sizeof(Type)); \ 00897 CS::StackArrayHelper<Type> Name##Del (Name, ((Size) > (Thresshold))); 00898 00899 00900 #ifdef CS_USE_CUSTOM_ISDIR 00901 static inline bool isdir (const char *path, struct dirent *de) 00902 { 00903 int pathlen = strlen (path); 00904 char* fullname = new char[pathlen + 2 + strlen (de->d_name)]; 00905 memcpy (fullname, path, pathlen + 1); 00906 if ((pathlen) && (fullname[pathlen-1] != CS_PATH_SEPARATOR)) 00907 { 00908 fullname[pathlen++] = CS_PATH_SEPARATOR; 00909 fullname[pathlen] = 0; 00910 } 00911 strcat (&fullname [pathlen], de->d_name); 00912 struct stat st; 00913 stat (fullname, &st); 00914 delete[] fullname; 00915 return ((st.st_mode & S_IFMT) == S_IFDIR); 00916 } 00917 #endif 00918 00919 00920 // The following define should only be enabled if you have defined 00921 // a special version of overloaded new that accepts two additional 00922 // parameters: a (void*) pointing to the filename and an int with the 00923 // line number. This is typically used for memory debugging. 00924 // In csutil/memdebug.cpp there is a memory debugger which can (optionally) 00925 // use this feature. Note that if CS_EXTENSIVE_MEMDEBUG is enabled while 00926 // the memory debugger is not the memory debugger will still provide the 00927 // needed overloaded operators so you can leave CS_EXTENSIVE_MEMDEBUG on in 00928 // that case and the only overhead will be a little more arguments to 'new'. 00929 // Do not enable CS_EXTENSIVE_MEMDEBUG if your platform or your own code 00930 // defines its own 'new' operator, since this version will interfere with your 00931 // own. 00932 // CS_MEMORY_TRACKER is treated like CS_EXTENSIVE_MEMDEBUG here. 00933 #if defined(CS_EXTENSIVE_MEMDEBUG) || defined(CS_MEMORY_TRACKER) 00934 extern CS_CRYSTALSPACE_EXPORT void operator delete (void* p); 00935 extern CS_CRYSTALSPACE_EXPORT void operator delete[] (void* p); 00936 00937 extern CS_CRYSTALSPACE_EXPORT void* operator new (size_t s, 00938 void* filename, int line); 00939 inline void operator delete (void* p, void*, int) { operator delete (p); } 00940 extern CS_CRYSTALSPACE_EXPORT void* operator new[] (size_t s, 00941 void* filename, int line); 00942 inline void operator delete[] (void* p, void*, int) { operator delete[] (p); } 00943 00944 inline void* operator new (size_t s) 00945 { return operator new (s, (void*)__FILE__, 0); } 00946 inline void* operator new[] (size_t s) 00947 { return operator new (s, (void*)__FILE__, 0); } 00948 00949 #define CS_EXTENSIVE_MEMDEBUG_NEW new ((void*)CS_FUNCTION_NAME, __LINE__) 00950 #define new CS_EXTENSIVE_MEMDEBUG_NEW 00951 #endif 00952 00953 namespace CS 00954 { 00955 namespace Debug 00956 { 00957 extern void CS_CRYSTALSPACE_EXPORT AssertMessage (const char* expr, 00958 const char* filename, int line, const char* msg = 0); 00959 00966 static inline void DebugBreak () 00967 { 00968 # if defined (CS_PLATFORM_WIN32) 00969 ::DebugBreak(); 00970 # else 00971 raise (SIGTRAP); 00972 # endif 00973 } 00974 00980 extern bool CS_CRYSTALSPACE_EXPORT VerifyAllMemory (); 00985 extern void CS_CRYSTALSPACE_EXPORT DumpAllocateMemoryBlocks (); 00986 } // namespace Debug 00987 } // namespace CS 00988 00989 #if defined(CS_DEBUG) || defined(CS_WITH_ASSERTIONS) 00990 # define CS_DEBUG_BREAK CS::Debug::DebugBreak() 00991 # if !defined (CS_ASSERT_MSG) 00992 # define CS_ASSERT_MSG(msg,x) \ 00993 if (!(x)) CS::Debug::AssertMessage (#x, __FILE__, __LINE__, msg); 00994 # endif 00995 # if !defined (CS_ASSERT) 00996 # define CS_ASSERT(x) CS_ASSERT_MSG(0, x) 00997 # endif 00998 #else 00999 # undef CS_DEBUG_BREAK 01000 # define CS_DEBUG_BREAK 01001 # undef CS_ASSERT 01002 # define CS_ASSERT(x) (void)0 01003 # undef CS_ASSERT_MSG 01004 # define CS_ASSERT_MSG(m,x) (void)0 01005 #endif 01006 01022 // Check if the csosdefs.h defined either CS_LITTLE_ENDIAN or CS_BIG_ENDIAN 01023 #if !defined (CS_LITTLE_ENDIAN) && !defined (CS_BIG_ENDIAN) 01024 # error No CS_XXX_ENDIAN macro defined in your OS-specific csosdefs.h! 01025 #endif 01026 01027 /* 01028 * This is a bit of overkill but if you're sure your CPU doesn't require 01029 * strict alignment add your CPU to the !defined below to get slightly 01030 * smaller and faster code in some cases. 01031 * 01032 * \todo In the future, this should be moved to csconfig.h and determined as 01033 * part of the configuration process. 01034 */ 01035 #if defined (CS_PROCESSOR_SPARC) 01036 # define CS_STRICT_ALIGNMENT 01037 #endif 01038 01039 // Adjust some definitions contained in csconfig.h 01040 #if !defined (CS_PROCESSOR_X86) || !defined (CS_HAVE_NASM) 01041 # undef CS_HAVE_MMX 01042 # undef CS_HAVE_NASM 01043 #endif 01044 01045 // Use special knowledge of IEEE float format in some cases for CPU's that are 01046 // known to support it 01047 #if !defined (CS_IEEE_DOUBLE_FORMAT) 01048 # if defined (CS_PROCESSOR_X86) || \ 01049 defined (CS_PROCESSOR_POWERPC) || \ 01050 defined (CS_PROCESSOR_MIPS) || \ 01051 defined (CS_PROCESSOR_SPARC) || \ 01052 defined (CS_PROCESSOR_ALPHA) || \ 01053 defined (CS_PROCESSOR_M68K) || \ 01054 defined (CS_PROCESSOR_ARM) 01055 # define CS_IEEE_DOUBLE_FORMAT 01056 # endif 01057 #endif 01058 01059 // gcc can perform usefull checking for printf/scanf format strings, just add 01060 // this define at the end of the function declaration 01061 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) 01062 /* Newer GCCs know different 'archetypes' of format string styles. 01063 * CS format strings are on the level of the GNU C library, so use that 01064 * archetype. */ 01065 # define CS_GNUC_PRINTF(format_idx, arg_idx) \ 01066 __attribute__((format (gnu_printf, format_idx, arg_idx))) 01067 # define CS_GNUC_SCANF(format_idx, arg_idx) \ 01068 __attribute__((format (gnu_scanf, format_idx, arg_idx))) 01069 // Unfortunately, gcc doesn't support format argument checking for wide strings 01070 # define CS_GNUC_WPRINTF(format_idx, arg_idx) \ 01071 /*__attribute__((format (__wprintf__, format_idx, arg_idx)))*/ 01072 # define CS_GNUC_WSCANF(format_idx, arg_idx) \ 01073 /*__attribute__((format (__wscanf__, format_idx, arg_idx)))*/ 01074 #elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) 01075 // Use default archetype for older versions. 01076 # define CS_GNUC_PRINTF(format_idx, arg_idx) \ 01077 __attribute__((format (__printf__, format_idx, arg_idx))) 01078 # define CS_GNUC_SCANF(format_idx, arg_idx) \ 01079 __attribute__((format (__scanf__, format_idx, arg_idx))) 01080 // Unfortunately, gcc doesn't support format argument checking for wide strings 01081 # define CS_GNUC_WPRINTF(format_idx, arg_idx) \ 01082 /*__attribute__((format (__wprintf__, format_idx, arg_idx)))*/ 01083 # define CS_GNUC_WSCANF(format_idx, arg_idx) \ 01084 /*__attribute__((format (__wscanf__, format_idx, arg_idx)))*/ 01085 #else 01086 # define CS_GNUC_PRINTF(format_idx, arg_idx) 01087 # define CS_GNUC_SCANF(format_idx, arg_idx) 01088 # define CS_GNUC_WPRINTF(format_idx, arg_idx) 01089 # define CS_GNUC_WSCANF(format_idx, arg_idx) 01090 #endif 01091 01092 // Remove __attribute__ on non GNUC compilers. 01093 #ifndef __GNUC__ 01094 #define __attribute__(x) 01095 #endif 01096 01097 // Support for alignment and packing of structures. 01098 #if !defined(CS_STRUCT_ALIGN_4BYTE_BEGIN) 01099 # if defined(__GNUC__) && defined(CS_STRICT_ALIGNMENT) 01100 # define CS_STRUCT_ALIGN_4BYTE_BEGIN 01101 # define CS_STRUCT_ALIGN_4BYTE_END __attribute__ ((aligned(4))) 01102 # else 01103 # define CS_STRUCT_ALIGN_4BYTE_BEGIN 01104 # define CS_STRUCT_ALIGN_4BYTE_END 01105 # endif 01106 #endif 01107 01108 #if defined(CS_COMPILER_MSVC) 01109 #define CS_ALIGNED_MEMBER(Member, Align) \ 01110 __declspec(align(Align)) Member 01111 #define CS_ALIGNED_STRUCT(Kind, Align) \ 01112 __declspec(align(Align)) Kind 01113 #elif defined(CS_COMPILER_GCC) 01114 01126 #define CS_ALIGNED_MEMBER(Member, Align) \ 01127 Member __attribute__((aligned(Align))) 01128 01139 #define CS_ALIGNED_STRUCT(Kind, Align) \ 01140 Kind __attribute__((aligned(Align))) 01141 #else 01142 #define CS_ALIGNED_MEMBER(Member, Align) Member 01143 #define CS_ALIGNED_STRUCT(Kind, Align) Kind 01144 #endif 01145 01146 // Macro used to define static implicit pointer conversion function. 01147 // Only use within a class declaration. 01148 #ifndef _CS_IMPLICITPTRCAST_NAME 01149 # define _CS_IMPLICITPTRCAST_NAME __ImplicitPtrCast 01150 #endif 01151 01173 #define CS_IMPLEMENT_IMPLICIT_PTR_CAST(classname) \ 01174 inline static classname* _CS_IMPLICITPTRCAST_NAME (classname* ptr) \ 01175 { \ 01176 return ptr;\ 01177 } 01178 01187 #define CS_IMPLICIT_PTR_CAST(classname, ptr) \ 01188 (classname::_CS_IMPLICITPTRCAST_NAME(ptr)) 01189 01193 #ifdef CS_HAVE_VA_COPY 01194 # define CS_VA_COPY(dest, src) va_copy(dest, src) 01195 #else 01196 # ifdef CS_HAVE___VA_COPY 01197 # define CS_VA_COPY(dest, src) __va_copy(dest, src) 01198 # else 01199 # define CS_VA_COPY(dest, src) dest = src; 01200 # endif 01201 #endif 01202 01203 #define CS_STRING_TO_WIDE_(x) L ## x 01204 01211 #define CS_STRING_TO_WIDE(x) CS_STRING_TO_WIDE_(x) 01212 01213 #ifdef PACKAGE_NAME 01214 # define CS_NAMESPACE_PACKAGE_NAME PACKAGE_NAME 01215 #else 01216 # define CS_NAMESPACE_PACKAGE_NAME CS 01217 #endif 01218 01242 #define CS_PLUGIN_NAMESPACE_BEGIN(name) \ 01243 namespace CS_NAMESPACE_PACKAGE_NAME { namespace Plugin { namespace name 01244 #define CS_PLUGIN_NAMESPACE_END(name) \ 01245 } } 01246 #define CS_PLUGIN_NAMESPACE_NAME(name) \ 01247 CS_NAMESPACE_PACKAGE_NAME::Plugin::name 01248 01261 #if defined(CS_COMPILER_GCC) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)) 01262 # define CS_DEPRECATION_WARNINGS_DISABLE \ 01263 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") 01264 # define CS_DEPRECATION_WARNINGS_ENABLE \ 01265 _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"") 01266 #else 01267 # define CS_DEPRECATION_WARNINGS_DISABLE 01268 # define CS_DEPRECATION_WARNINGS_ENABLE 01269 #endif 01270 01271 namespace CS 01272 { 01273 namespace deprecated 01274 { 01275 CS_DEPRECATED_METHOD_MSG("Use CS::Platform::CreateDirectory() instead") 01276 CS_CRYSTALSPACE_EXPORT int CS_MKDIR (const char* path); 01277 } // namespace deprecated 01278 } // namespace CS 01279 01280 #define CS_MKDIR(path) CS::deprecated::CS_MKDIR(path) 01281 01282 // Include nullptr fallback (for convenience). 01283 #include "csutil/nullptr.h" 01284 01285 #endif // __CS_CSSYSDEF_H__
Generated for Crystal Space 2.1 by doxygen 1.6.1
