1 /*
2  * Copyright 2011-2013 Arx Libertatis Team (see the AUTHORS file)
3  *
4  * This file is part of Arx Libertatis.
5  *
6  * Arx Libertatis is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Arx Libertatis is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Arx Libertatis.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ARX_PLATFORM_PLATFORM_H
21 #define ARX_PLATFORM_PLATFORM_H
22 
23 #include <stddef.h>
24 #include <cstdlib>
25 
26 #include "platform/PlatformConfig.h"
27 
28 #define ARX_STR_HELPER(x) # x
29 #define ARX_STR(x) ARX_STR_HELPER(x)
30 
31 /* ---------------------------------------------------------
32                           Platforms
33 ------------------------------------------------------------*/
34 
35 #define ARX_PLATFORM_UNKNOWN 0
36 #define ARX_PLATFORM_WIN32   1
37 #define ARX_PLATFORM_LINUX   2
38 #define ARX_PLATFORM_MACOSX  3
39 #define ARX_PLATFORM_BSD     100 // Generic BSD system
40 #define ARX_PLATFORM_UNIX    101 // Generic UNIX system
41 
42 #if defined(__linux)
43 	#define ARX_PLATFORM ARX_PLATFORM_LINUX
44 #elif defined(_WIN32)
45 	#define ARX_PLATFORM ARX_PLATFORM_WIN32
46 #elif defined(__MACH__)
47 	#define ARX_PLATFORM ARX_PLATFORM_MACOSX
48 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
49       || defined(__bsdi__) || defined(__DragonFly__)
50 	#define ARX_PLATFORM ARX_PLATFORM_BSD
51 #elif defined(__unix__) || defined(__unix) || defined(unix)
52 	#define ARX_PLATFORM ARX_PLATFORM_UNIX
53 #else
54 	#define ARX_PLATFORM ARX_PLATFORM_UNKNOWN
55 #endif
56 
57 /* ---------------------------------------------------------
58                           Compilers
59 ------------------------------------------------------------*/
60 
61 // This is used in many places, keep it for now
62 #if defined(_MSC_VER)
63 #define ARX_COMPILER_MSVC 1
64 #else
65 #define ARX_COMPILER_MSVC 0
66 #endif
67 
68 #if ARX_COMPILER_MSVC
69 	#include <direct.h>
70 	#define __func__ __FUNCTION__ // MSVC doesn't know about C99 __func__
71 #endif
72 
73 #if ARX_COMPILER_MSVC && (_MSC_VER >= 1600 /* MSVC 10 */)
74 	#define ARX_COMPILER_HAS_CXX11_AUTO
75 #endif
76 
77 /* ---------------------------------------------------------
78                            Types
79 ------------------------------------------------------------*/
80 
81 #if ARX_COMPILER_MSVC
82 
83 	typedef signed char s8;         //  8 bits integer
84 	typedef unsigned char u8;       //  8 bits unsigned integer
85 
86 	typedef signed short s16;       // 16 bits signed integer
87 	typedef unsigned short u16;     // 16 bits unsigned integer
88 
89 	typedef signed long s32;        // 32 bits signed integer
90 	typedef unsigned long u32;      // 32 bits unsigned integer
91 
92 	typedef signed long long s64;   // 64 bits signed integer
93 	typedef unsigned long long u64; // 64 bits unsigned integer
94 
95 #else // ARX_COMPILER_MSVC
96 
97 	#include <stdint.h>
98 
99 	typedef int8_t s8;    //  8 bits integer
100 	typedef uint8_t u8;   //  8 bits unsigned integer
101 
102 	typedef int16_t s16;  // 16 bits signed integer
103 	typedef uint16_t u16; // 16 bits unsigned integer
104 
105 	typedef int32_t s32;  // 32 bits signed integer
106 	typedef uint32_t u32; // 32 bits unsigned integer
107 
108 	typedef int64_t s64;  // 64 bits signed integer
109 	typedef uint64_t u64; // 64 bits unsigned integer
110 
111 #endif // ARX_COMPILER_MSVC
112 
113 typedef float f32; // 32 bits float
114 typedef double f64; // 64 bits double float
115 
116 
117 /* ---------------------------------------------------------
118                           Break
119 ------------------------------------------------------------*/
120 
121 /*!
122  * ARX_DEBUG_BREAK() - halt execution and notify any attached debugger
123  */
124 #if ARX_COMPILER_MSVC
125 	#define ARX_DEBUG_BREAK() __debugbreak()
126 #elif ARX_HAVE_BUILTIN_TRAP
127 	#define ARX_DEBUG_BREAK() __builtin_trap()
128 #else
129 	#define ARX_DEBUG_BREAK() std::abort()
130 #endif
131 
132 /* ---------------------------------------------------------
133                 Compiler-specific attributes
134 ------------------------------------------------------------*/
135 
136 //! ARX_DISCARD(...) - Discard parameters from a macro
137 #if ARX_COMPILER_MSVC
138 	// MS compilers support noop which discards everything inside the parens
139 	#define ARX_DISCARD(...) __noop
140 #else
141 	#define ARX_DISCARD(...) ((void)0)
142 #endif
143 
144 /*!
145  * Declare that a function argument is a printf-like format string.
146  *
147  * Usage: T function(args, message, ...) ARX_FORMAT_PRINTF(message_arg, param_vararg)
148  *
149  * @param message_arg index of the format string arg (1 for the first)
150  * @param param_vararg index of the vararg for the parameters
151  *
152  * This is useful to
153  *  a) Let the compiler check the format string and parameters when calling the function
154  *  b) Prevent warnings due to a non-literal format string in the implementation
155  */
156 #if ARX_HAVE_ATTRIBUTE_FORMAT_PRINTF
157 #define ARX_FORMAT_PRINTF(message_arg, param_vararg) \
158 	__attribute__((format(printf, message_arg, param_vararg)))
159 #else
160 #define ARX_FORMAT_PRINTF(message_arg, param_vararg)
161 #endif
162 
163 /* ---------------------------------------------------------
164                      Macro for assertion
165 ------------------------------------------------------------*/
166 
167 /*!
168  * Log that an assertion has failed.
169  * This is a low-level implementation, use arx_assert() or arx_assert_msg() instead!
170  */
171 void assertionFailed(const char * expression, const char * file, unsigned line,
172                      const char * message = NULL, ...) ARX_FORMAT_PRINTF(4, 5);
173 
174 #ifdef ARX_DEBUG
175 	#define arx_assert_impl(Expression, File, Line, ...) { \
176 			if(!(Expression)) { \
177 				assertionFailed(#Expression, File, Line, ##__VA_ARGS__); \
178 				ARX_DEBUG_BREAK(); \
179 			} \
180 		}
181 #else // ARX_DEBUG
182 	#define arx_assert_impl(Expression, File, Line, ...) \
183 		ARX_DISCARD(Expression, File, Line, Message, ##__VA_ARGS__)
184 #endif // ARX_DEBUG
185 
186 #define arx_assert_msg(Expression, Message, ...) \
187 	arx_assert_impl(Expression, (__FILE__), __LINE__, Message, ##__VA_ARGS__)
188 #define arx_assert(Expression) \
189 	arx_assert_impl(Expression, (__FILE__), __LINE__)
190 
191 #define arx_error_msg(Message, ...) arx_assert_msg(false, Message, ##__VA_ARGS__)
192 #define arx_error() arx_assert(false)
193 
194 /* ---------------------------------------------------------
195                             Define
196 ------------------------------------------------------------*/
197 
198 //! Get the number of items in a static array
199 #define ARRAY_SIZE(a) ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
200 
201 /* ---------------------------------------------------------
202                            Pragma
203 ------------------------------------------------------------*/
204 
205 #define ARX_DEAD_CODE() arx_assert(false)
206 
207 /*!
208  * Remove warnings about unused but necessary variable
209  * (unused params, variables only used for asserts...)
210  */
211 #define ARX_UNUSED(x) ((void)&x)
212 
213 /* ---------------------------------------------------------
214                       String utilities
215 ------------------------------------------------------------*/
216 
217 // TODO move into a separate header
218 
219 template <class CTYPE, class STYPE>
safeGetString(CTYPE * & pos,STYPE & size)220 inline CTYPE * safeGetString(CTYPE * & pos, STYPE & size) {
221 
222 	CTYPE * begin = pos;
223 
224 	for(size_t i = 0; i < size; i++) {
225 		if(pos[i] == 0) {
226 			size -= i + 1;
227 			pos += i + 1;
228 			return begin;
229 		}
230 	}
231 
232 	return NULL;
233 }
234 
235 template <class T, class CTYPE, class STYPE>
safeGet(T & data,CTYPE * & pos,STYPE & size)236 inline bool safeGet(T & data, CTYPE * & pos, STYPE & size) {
237 
238 	if(size < sizeof(T)) {
239 		return false;
240 	}
241 	data = *reinterpret_cast<const T *>(pos);
242 	pos += sizeof(T);
243 	size -= sizeof(T);
244 	return true;
245 }
246 
247 #endif // ARX_PLATFORM_PLATFORM_H
248