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