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(__FUNCTION__) 00781 # define CS_FUNCTION_NAME __FUNCTION__ 00782 #else 00783 # define CS_FUNCTION_NAME "<?\?\?>" 00784 #endif 00785 00786 #include <stdlib.h> 00787 #ifdef CS_HAVE_MALLOC_H 00788 #include <malloc.h> 00789 #endif 00790 #include <new> 00791 00792 #ifndef CS_NO_PTMALLOC 00793 00794 00798 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc (size_t n); 00799 extern CS_CRYSTALSPACE_EXPORT void ptfree (void* p); 00800 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc (void* p, size_t n); 00801 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc (size_t n, 00802 size_t s); 00804 00806 00810 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc_sentinel ( 00811 size_t n); 00812 extern CS_CRYSTALSPACE_EXPORT void ptfree_sentinel (void* p); 00813 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc_sentinel (void* p, size_t n); 00814 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc_sentinel ( 00815 size_t n, size_t s); 00817 00819 00823 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc_located ( 00824 size_t n); 00825 extern CS_CRYSTALSPACE_EXPORT void ptfree_located (void* p); 00826 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc_located (void* p, size_t n); 00827 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc_located ( 00828 size_t n, size_t s); 00830 00832 00836 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptmalloc_checking ( 00837 size_t n); 00838 extern CS_CRYSTALSPACE_EXPORT void ptfree_checking (void* p); 00839 extern CS_CRYSTALSPACE_EXPORT void* ptrealloc_checking (void* p, size_t n); 00840 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* ptcalloc_checking ( 00841 size_t n, size_t s); 00843 00844 #ifndef CS_DEBUG 00845 # undef CS_EXTENSIVE_MEMDEBUG 00846 # undef CS_REF_TRACKER 00847 #else 00848 # if defined(CS_EXTENSIVE_MEMDEBUG) && defined(CS_MEMORY_TRACKER) 00849 # error Do not use CS_EXTENSIVE_MEMDEBUG and CS_MEMORY_TRACKER together! 00850 # endif 00851 #endif 00852 00853 #endif // CS_NO_PTMALLOC 00854 00860 extern CS_CRYSTALSPACE_EXPORT CS_ATTRIBUTE_MALLOC void* cs_malloc (size_t n); 00861 extern CS_CRYSTALSPACE_EXPORT void cs_free (void* p); 00862 extern CS_CRYSTALSPACE_EXPORT void* cs_realloc (void* p, size_t n); 00863 extern CS_CRYSTALSPACE_EXPORT void* cs_calloc (size_t n, size_t s); 00865 00866 namespace CS 00867 { 00868 template <class T> 00869 class StackArrayHelper 00870 { 00871 private: 00872 void* memory; 00873 bool deleteme; 00874 00875 public: 00876 StackArrayHelper (void* memory, bool deleteme) 00877 : memory (memory), deleteme (deleteme) { } 00878 ~StackArrayHelper () { if (deleteme) cs_free (memory); } 00879 }; 00880 } 00881 00891 #define CS_ALLOC_STACK_ARRAY_FALLBACK(Type, Name, Size, Thresshold) \ 00892 Type* Name = ((Size) > (Thresshold)) ? \ 00893 (Type*)cs_malloc((Size)*sizeof(Type)) : \ 00894 (Type*)alloca((Size)*sizeof(Type)); \ 00895 CS::StackArrayHelper<Type> Name##Del (Name, ((Size) > (Thresshold))); 00896 00897 00898 #ifdef CS_USE_CUSTOM_ISDIR 00899 static inline bool isdir (const char *path, struct dirent *de) 00900 { 00901 int pathlen = strlen (path); 00902 char* fullname = new char[pathlen + 2 + strlen (de->d_name)]; 00903 memcpy (fullname, path, pathlen + 1); 00904 if ((pathlen) && (fullname[pathlen-1] != CS_PATH_SEPARATOR)) 00905 { 00906 fullname[pathlen++] = CS_PATH_SEPARATOR; 00907 fullname[pathlen] = 0; 00908 } 00909 strcat (&fullname [pathlen], de->d_name); 00910 struct stat st; 00911 stat (fullname, &st); 00912 delete[] fullname; 00913 return ((st.st_mode & S_IFMT) == S_IFDIR); 00914 } 00915 #endif 00916 00917 00918 // The following define should only be enabled if you have defined 00919 // a special version of overloaded new that accepts two additional 00920 // parameters: a (void*) pointing to the filename and an int with the 00921 // line number. This is typically used for memory debugging. 00922 // In csutil/memdebug.cpp there is a memory debugger which can (optionally) 00923 // use this feature. Note that if CS_EXTENSIVE_MEMDEBUG is enabled while 00924 // the memory debugger is not the memory debugger will still provide the 00925 // needed overloaded operators so you can leave CS_EXTENSIVE_MEMDEBUG on in 00926 // that case and the only overhead will be a little more arguments to 'new'. 00927 // Do not enable CS_EXTENSIVE_MEMDEBUG if your platform or your own code 00928 // defines its own 'new' operator, since this version will interfere with your 00929 // own. 00930 // CS_MEMORY_TRACKER is treated like CS_EXTENSIVE_MEMDEBUG here. 00931 #if defined(CS_EXTENSIVE_MEMDEBUG) || defined(CS_MEMORY_TRACKER) 00932 extern CS_CRYSTALSPACE_EXPORT void operator delete (void* p); 00933 extern CS_CRYSTALSPACE_EXPORT void operator delete[] (void* p); 00934 00935 extern CS_CRYSTALSPACE_EXPORT void* operator new (size_t s, 00936 void* filename, int line); 00937 inline void operator delete (void* p, void*, int) { operator delete (p); } 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 00942 inline void* operator new (size_t s) 00943 { return operator new (s, (void*)__FILE__, 0); } 00944 inline void* operator new[] (size_t s) 00945 { return operator new (s, (void*)__FILE__, 0); } 00946 00947 #define CS_EXTENSIVE_MEMDEBUG_NEW new ((void*)CS_FUNCTION_NAME, __LINE__) 00948 #define new CS_EXTENSIVE_MEMDEBUG_NEW 00949 #endif 00950 00951 namespace CS 00952 { 00953 namespace Debug 00954 { 00955 extern void CS_CRYSTALSPACE_EXPORT AssertMessage (const char* expr, 00956 const char* filename, int line, const char* msg = 0); 00957 00964 static inline void DebugBreak () 00965 { 00966 # if defined (CS_PLATFORM_WIN32) 00967 ::DebugBreak(); 00968 # else 00969 raise (SIGTRAP); 00970 # endif 00971 } 00972 00978 extern bool CS_CRYSTALSPACE_EXPORT VerifyAllMemory (); 00983 extern void CS_CRYSTALSPACE_EXPORT DumpAllocateMemoryBlocks (); 00984 } // namespace Debug 00985 } // namespace CS 00986 00987 #if defined(CS_DEBUG) || defined(CS_WITH_ASSERTIONS) 00988 # define CS_DEBUG_BREAK CS::Debug::DebugBreak() 00989 # if !defined (CS_ASSERT_MSG) 00990 # define CS_ASSERT_MSG(msg,x) \ 00991 if (!(x)) CS::Debug::AssertMessage (#x, __FILE__, __LINE__, msg); 00992 # endif 00993 # if !defined (CS_ASSERT) 00994 # define CS_ASSERT(x) CS_ASSERT_MSG(0, x) 00995 # endif 00996 #else 00997 # undef CS_DEBUG_BREAK 00998 # define CS_DEBUG_BREAK 00999 # undef CS_ASSERT 01000 # define CS_ASSERT(x) (void)0 01001 # undef CS_ASSERT_MSG 01002 # define CS_ASSERT_MSG(m,x) (void)0 01003 #endif 01004 01020 // Check if the csosdefs.h defined either CS_LITTLE_ENDIAN or CS_BIG_ENDIAN 01021 #if !defined (CS_LITTLE_ENDIAN) && !defined (CS_BIG_ENDIAN) 01022 # error No CS_XXX_ENDIAN macro defined in your OS-specific csosdefs.h! 01023 #endif 01024 01025 /* 01026 * This is a bit of overkill but if you're sure your CPU doesn't require 01027 * strict alignment add your CPU to the !defined below to get slightly 01028 * smaller and faster code in some cases. 01029 * 01030 * \todo In the future, this should be moved to csconfig.h and determined as 01031 * part of the configuration process. 01032 */ 01033 #if defined (CS_PROCESSOR_SPARC) 01034 # define CS_STRICT_ALIGNMENT 01035 #endif 01036 01037 // Adjust some definitions contained in csconfig.h 01038 #if !defined (CS_PROCESSOR_X86) || !defined (CS_HAVE_NASM) 01039 # undef CS_HAVE_MMX 01040 # undef CS_HAVE_NASM 01041 #endif 01042 01043 // Use special knowledge of IEEE float format in some cases for CPU's that are 01044 // known to support it 01045 #if !defined (CS_IEEE_DOUBLE_FORMAT) 01046 # if defined (CS_PROCESSOR_X86) || \ 01047 defined (CS_PROCESSOR_POWERPC) || \ 01048 defined (CS_PROCESSOR_MIPS) || \ 01049 defined (CS_PROCESSOR_SPARC) || \ 01050 defined (CS_PROCESSOR_ALPHA) || \ 01051 defined (CS_PROCESSOR_M68K) || \ 01052 defined (CS_PROCESSOR_ARM) 01053 # define CS_IEEE_DOUBLE_FORMAT 01054 # endif 01055 #endif 01056 01057 // gcc can perform usefull checking for printf/scanf format strings, just add 01058 // this define at the end of the function declaration 01059 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) 01060 /* Newer GCCs know different 'archetypes' of format string styles. 01061 * CS format strings are on the level of the GNU C library, so use that 01062 * archetype. */ 01063 # define CS_GNUC_PRINTF(format_idx, arg_idx) \ 01064 __attribute__((format (gnu_printf, format_idx, arg_idx))) 01065 # define CS_GNUC_SCANF(format_idx, arg_idx) \ 01066 __attribute__((format (gnu_scanf, format_idx, arg_idx))) 01067 // Unfortunately, gcc doesn't support format argument checking for wide strings 01068 # define CS_GNUC_WPRINTF(format_idx, arg_idx) \ 01069 /*__attribute__((format (__wprintf__, format_idx, arg_idx)))*/ 01070 # define CS_GNUC_WSCANF(format_idx, arg_idx) \ 01071 /*__attribute__((format (__wscanf__, format_idx, arg_idx)))*/ 01072 #elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) 01073 // Use default archetype for older versions. 01074 # define CS_GNUC_PRINTF(format_idx, arg_idx) \ 01075 __attribute__((format (__printf__, format_idx, arg_idx))) 01076 # define CS_GNUC_SCANF(format_idx, arg_idx) \ 01077 __attribute__((format (__scanf__, format_idx, arg_idx))) 01078 // Unfortunately, gcc doesn't support format argument checking for wide strings 01079 # define CS_GNUC_WPRINTF(format_idx, arg_idx) \ 01080 /*__attribute__((format (__wprintf__, format_idx, arg_idx)))*/ 01081 # define CS_GNUC_WSCANF(format_idx, arg_idx) \ 01082 /*__attribute__((format (__wscanf__, format_idx, arg_idx)))*/ 01083 #else 01084 # define CS_GNUC_PRINTF(format_idx, arg_idx) 01085 # define CS_GNUC_SCANF(format_idx, arg_idx) 01086 # define CS_GNUC_WPRINTF(format_idx, arg_idx) 01087 # define CS_GNUC_WSCANF(format_idx, arg_idx) 01088 #endif 01089 01090 // Remove __attribute__ on non GNUC compilers. 01091 #ifndef __GNUC__ 01092 #define __attribute__(x) 01093 #endif 01094 01095 // Support for alignment and packing of structures. 01096 #if !defined(CS_STRUCT_ALIGN_4BYTE_BEGIN) 01097 # if defined(__GNUC__) && defined(CS_STRICT_ALIGNMENT) 01098 # define CS_STRUCT_ALIGN_4BYTE_BEGIN 01099 # define CS_STRUCT_ALIGN_4BYTE_END __attribute__ ((aligned(4))) 01100 # else 01101 # define CS_STRUCT_ALIGN_4BYTE_BEGIN 01102 # define CS_STRUCT_ALIGN_4BYTE_END 01103 # endif 01104 #endif 01105 01106 #if defined(CS_COMPILER_MSVC) 01107 #define CS_ALIGNED_MEMBER(Member, Align) \ 01108 __declspec(align(Align)) Member 01109 #define CS_ALIGNED_STRUCT(Kind, Align) \ 01110 __declspec(align(Align)) Kind 01111 #elif defined(CS_COMPILER_GCC) 01112 01124 #define CS_ALIGNED_MEMBER(Member, Align) \ 01125 Member __attribute__((aligned(Align))) 01126 01137 #define CS_ALIGNED_STRUCT(Kind, Align) \ 01138 Kind __attribute__((aligned(Align))) 01139 #else 01140 #define CS_ALIGNED_MEMBER(Member, Align) Member 01141 #define CS_ALIGNED_STRUCT(Kind, Align) Kind 01142 #endif 01143 01144 // Macro used to define static implicit pointer conversion function. 01145 // Only use within a class declaration. 01146 #ifndef _CS_IMPLICITPTRCAST_NAME 01147 # define _CS_IMPLICITPTRCAST_NAME __ImplicitPtrCast 01148 #endif 01149 01171 #define CS_IMPLEMENT_IMPLICIT_PTR_CAST(classname) \ 01172 inline static classname* _CS_IMPLICITPTRCAST_NAME (classname* ptr) \ 01173 { \ 01174 return ptr;\ 01175 } 01176 01185 #define CS_IMPLICIT_PTR_CAST(classname, ptr) \ 01186 (classname::_CS_IMPLICITPTRCAST_NAME(ptr)) 01187 01191 #ifdef CS_HAVE_VA_COPY 01192 # define CS_VA_COPY(dest, src) va_copy(dest, src) 01193 #else 01194 # ifdef CS_HAVE___VA_COPY 01195 # define CS_VA_COPY(dest, src) __va_copy(dest, src) 01196 # else 01197 # define CS_VA_COPY(dest, src) dest = src; 01198 # endif 01199 #endif 01200 01201 #define CS_STRING_TO_WIDE_(x) L ## x 01202 01209 #define CS_STRING_TO_WIDE(x) CS_STRING_TO_WIDE_(x) 01210 01211 #ifdef PACKAGE_NAME 01212 # define CS_NAMESPACE_PACKAGE_NAME PACKAGE_NAME 01213 #else 01214 # define CS_NAMESPACE_PACKAGE_NAME CS 01215 #endif 01216 01240 #define CS_PLUGIN_NAMESPACE_BEGIN(name) \ 01241 namespace CS_NAMESPACE_PACKAGE_NAME { namespace Plugin { namespace name 01242 #define CS_PLUGIN_NAMESPACE_END(name) \ 01243 } } 01244 #define CS_PLUGIN_NAMESPACE_NAME(name) \ 01245 CS_NAMESPACE_PACKAGE_NAME::Plugin::name 01246 01259 #if defined(CS_COMPILER_GCC) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)) 01260 # define CS_DEPRECATION_WARNINGS_DISABLE \ 01261 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") 01262 # define CS_DEPRECATION_WARNINGS_ENABLE \ 01263 _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"") 01264 #else 01265 # define CS_DEPRECATION_WARNINGS_DISABLE 01266 # define CS_DEPRECATION_WARNINGS_ENABLE 01267 #endif 01268 01269 namespace CS 01270 { 01271 namespace deprecated 01272 { 01273 CS_DEPRECATED_METHOD_MSG("Use CS::Platform::CreateDirectory() instead") 01274 CS_CRYSTALSPACE_EXPORT int CS_MKDIR (const char* path); 01275 } // namespace deprecated 01276 } // namespace CS 01277 01278 #define CS_MKDIR(path) CS::deprecated::CS_MKDIR(path) 01279 01280 // Include nullptr fallback (for convenience). 01281 #include "csutil/nullptr.h" 01282 01283 #endif // __CS_CSSYSDEF_H__
Generated for Crystal Space 2.1 by doxygen 1.6.1
