summaryrefslogtreecommitdiff
path: root/src/port.h
blob: 4dc56ee29dae00d7b7d4bbf86bf6a844586125f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
#ifndef PORT_H_
#define PORT_H_

#include "config.h"

#ifdef __MINGW32__
// Microsoft Windows headers expect this to be set. The MSVC compiler sets
// it, but MinGW doesn't.
#	if defined(_X86_)
#		define _M_IX86
#	elif defined(_IA64_)
#		define _M_IA64
#	elif defined(__amd64__)
#		define _M_AMD64
#		define _M_X64
#	elif defined(__m68k__)
#		define _68K_
#	elif defined(__ppc__)
#		define _M_PPC
#	endif
#endif


// Compilation related
#ifdef _MSC_VER
#	define inline __inline
#elif defined(__SYMBIAN32__)
#else
#	define inline __inline__
#	ifdef __MINGW32__
		// For when including Microsoft Windows header files.
#		define _inline inline
#	endif
#endif


// Compilation warnings:
#ifdef _MSC_VER
	// UQM uses a lot of functions that can be used unsafely, but it uses them
	// in a safe way. The warnings about these functions however may drown out
	// serious warnings, so we turn them off.
#	define _CRT_SECURE_NO_DEPRECATE

	// Escalate some warnings we consider important
	// "'operator' : 'identifier1' indirection to slightly different base
	//   types from 'identifier2'
#	pragma warning( 3 : 4057 )
	// "unreferenced formal parameter"
#	pragma warning( 3 : 4100 )
	// "'function' : unreferenced local function has been removed"
#	pragma warning( 3 : 4505 )
	// "local variable 'name' may be used without having been initialized"
#	pragma warning( 3 : 4701 )

	// Downgrade some warnings we consider unimportant
	// "'operator' conversion from 'type1' to 'type2', possible loss of data"
#	pragma warning( 4 : 4244)
#endif


#ifdef _MSC_VER
#	include <io.h>
#else
#	include <unistd.h>
#endif

// Using "HAVE_STRCASECMP_UQM" instead of "HAVE_STRCASECMP" as the latter
// conflicts with SDL.
#if !defined(HAVE_STRICMP) && !defined(HAVE_STRCASECMP_UQM)
#	error Neither stricmp() nor strcasecmp() is available.
#elif !defined(HAVE_STRICMP)
#	define stricmp strcasecmp
#elif !defined(HAVE_STRCASECMP_UQM)
#	define strcasecmp stricmp
#else
	// We should take care not to define anything if both strcasecmp() and
	// stricmp() are defined, as one might exist as a macro to the other.
#endif


#ifndef HAVE_STRUPR
#if defined(__cplusplus)
extern "C" {
#endif
char *strupr (char *str);
#if defined(__cplusplus)
}
#endif
#endif

#if !defined (_MSC_VER) && !defined (HAVE_READDIR_R)
#	include <dirent.h>
#if defined(__cplusplus)
extern "C" {
#endif
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
#if defined(__cplusplus)
}
#endif
#endif

// Directories
#ifdef WIN32
#	include <stdlib.h>
#	define PATH_MAX  _MAX_PATH
#	define NAME_MAX  _MAX_FNAME
		// _MAX_DIR and FILENAME_MAX could also be candidates.
		// If anyone can tell me which one matches NAME_MAX, please
		// let me know. - SvdB
#elif defined(_WIN32_WCE)
#	include <sys/syslimits.h>
#else
#	include <limits.h>
		/* PATH_MAX is per POSIX defined in <limits.h>, but:
		 * "A definition of one of the values from Table 2.6 shall bea
		 * omitted from <limits.h> on specific implementations where the
		 * corresponding value is equal to or greater than the
		 * stated minimum, but where the value can vary depending
		 * on the file to which it is applied. The actual value supported
		 * for a specific pathname shall be provided by the pathconf()
		 * function."
		 * _POSIX_NAME_MAX will provide a minimum (14).
		 * This is relevant (at least) for Solaris.
		 */
#	ifndef NAME_MAX
#		define NAME_MAX _POSIX_NAME_MAX
#	endif
#endif

// Some types
#ifdef _MSC_VER
typedef int ssize_t;
typedef unsigned short mode_t;
#endif

// Directories
#include <sys/stat.h>
#ifdef _MSC_VER
#	define MKDIR(name, mode) ((void) mode, _mkdir(name))
#elif defined(__MINGW32__)
#	define MKDIR(name, mode) ((void) mode, mkdir(name))
#else
#	define MKDIR mkdir
#endif
#ifdef _MSC_VER
#	include <direct.h>
#	define chdir _chdir
#	define getcwd _getcwd
#	define access _access
#	define F_OK 0
#	define W_OK 2
#	define R_OK 4
#	define open _open
#	define read _read
//#	define fstat _fstat
#	define write _write
//#	define stat _stat
#	define unlink _unlink
#endif

// Memory
#ifdef WIN32
#	ifdef __MINGW32__
#		include <malloc.h>
#	elif defined (_MSC_VER)
#		define alloca _alloca
#	endif
#elif defined(__linux__) || defined(__svr4__)
#	include <alloca.h>
#endif

// String formatting
#ifdef _MSC_VER
#	include <stdarg.h>
// Defined in port.c
#if defined(__cplusplus)
extern "C" {
#endif
int snprintf(char *str, size_t size, const char *format, ...);
int vsnprintf(char *str, size_t size, const char *format, va_list args);
#if defined(__cplusplus)
}
#endif

#endif  /* _MSC_VER */

#if defined(__cplusplus)
extern "C" {
#endif

// setenv()
#ifndef HAVE_SETENV
int setenv (const char *name, const char *value, int overwrite);
#endif

#ifndef HAVE_WCHAR_T
typedef unsigned short wchar_t;
#endif

#ifndef HAVE_WINT_T
typedef unsigned int wint_t;
#endif

#if defined(__cplusplus)
}
#endif

#if defined (_MSC_VER) || defined(__MINGW32__)
#	define USE_WINSOCK
#endif

// errno error numbers. The values used don't matter, as long as they
// don't conflict with existing errno error numbers.
#ifdef PORT_WANT_ERRNO
#	ifdef USE_WINSOCK
#		include <errno.h>
#		ifndef E2BIG
#			define E2BIG            0x01000001
#		endif
#		ifndef EACCES
#			define EACCES           0x01000002
#		endif
#		ifndef EADDRINUSE
#			define EADDRINUSE       0x01000003
#		endif
#		ifndef EADDRNOTAVAIL
#			define EADDRNOTAVAIL    0x01000004
#		endif
#		ifndef EAFNOSUPPORT
#			define EAFNOSUPPORT     0x01000005
#		endif
#		ifndef EAGAIN
#			ifdef EWOULDBLOCK
#				define EAGAIN       EWOULDBLOCK
#			else
#				define EAGAIN       0x01000006
#			endif
#		endif
#		ifndef EALREADY
#			define EALREADY         0x01000007
#		endif
#		ifndef EBADF
#			define EBADF            0x01000008
#		endif
#		ifndef EBADMSG
#			define EBADMSG          0x01000009
#		endif
#		ifndef EBUSY
#			define EBUSY            0x0100000a
#		endif
#		ifndef ECANCELED
#			define ECANCELED        0x0100000b
#		endif
#		ifndef ECHILD
#			define ECHILD           0x0100000c
#		endif
#		ifndef ECONNABORTED
#			define ECONNABORTED     0x0100000d
#		endif
#		ifndef ECONNREFUSED
#			define ECONNREFUSED     0x0100000e
#		endif
#		ifndef ECONNRESET
#			define ECONNRESET       0x0100000f
#		endif
#		ifndef EDEADLK
#			define EDEADLK          0x01000010
#		endif
#		ifndef EDESTADDRREQ
#			define EDESTADDRREQ     0x01000011
#		endif
#		ifndef EDOM
#			define EDOM             0x01000012
#		endif
// Reserved in POSIX
//#		ifndef //EDQUOT
//#			define //EDQUOT         0x01000013
//#		endif
#		ifndef EEXIST
#			define EEXIST           0x01000014
#		endif
#		ifndef EFAULT
#			define EFAULT           0x01000015
#		endif
#		ifndef EFBIG
#			define EFBIG            0x01000016
#		endif
#		ifndef EHOSTUNREACH
#			define EHOSTUNREACH     0x01000017
#		endif
#		ifndef EIDRM
#			define EIDRM            0x01000018
#		endif
#		ifndef EILSEQ
#			define EILSEQ           0x01000019
#		endif
#		ifndef EINPROGRESS
#			define EINPROGRESS      0x0100001a
#		endif
#		ifndef EINTR
#			define EINTR            0x0100001b
#		endif
#		ifndef EINVAL
#			define EINVAL           0x0100001c
#		endif
#		ifndef EIO
#			define EIO              0x0100001d
#		endif
#		ifndef EISCONN
#			define EISCONN          0x0100001e
#		endif
#		ifndef EISDIR
#			define EISDIR           0x0100001f
#		endif
#		ifndef ELOOP
#			define ELOOP            0x01000020
#		endif
#		ifndef EMFILE
#			define EMFILE           0x01000021
#		endif
#		ifndef EMLINK
#			define EMLINK           0x01000022
#		endif
#		ifndef EMSGSIZE
#			define EMSGSIZE         0x01000023
#		endif
// Reserved in POSIX
//#		ifndef //EMULTIHOP
//#			define //EMULTIHOP      0x01000024
//#		endif
#		ifndef ENAMETOOLONG
#			define ENAMETOOLONG     0x01000025
#		endif
#		ifndef ENETDOWN
#			define ENETDOWN         0x01000026
#		endif
#		ifndef ENETRESET
#			define ENETRESET        0x01000027
#		endif
#		ifndef ENETUNREACH
#			define ENETUNREACH      0x01000028
#		endif
#		ifndef ENFILE
#			define ENFILE           0x01000029
#		endif
#		ifndef ENOBUFS
#			define ENOBUFS          0x0100002a
#		endif
#		ifndef ENODATA
#			define ENODATA          0x0100002b
#		endif
#		ifndef ENODEV
#			define ENODEV           0x0100002c
#		endif
#		ifndef ENOENT
#			define ENOENT           0x0100002d
#		endif
#		ifndef ENOEXEC
#			define ENOEXEC          0x0100002e
#		endif
#		ifndef ENOLCK
#			define ENOLCK           0x0100002f
#		endif
// Reserved in POSIX
//#		ifndef ENOLINK
//#			define ENOLINK          0x01000030
//#		endif
#		ifndef ENOMEM
#			define ENOMEM           0x01000031
#		endif
#		ifndef ENOMSG
#			define ENOMSG           0x01000032
#		endif
#		ifndef ENOPROTOOPT
#			define ENOPROTOOPT      0x01000033
#		endif
#		ifndef ENOSPC
#			define ENOSPC           0x01000034
#		endif
#		ifndef ENOSR
#			define ENOSR            0x01000035
#		endif
#		ifndef ENOSTR
#			define ENOSTR           0x01000036
#		endif
#		ifndef ENOSYS
#			define ENOSYS           0x01000037
#		endif
#		ifndef ENOTCONN
#			define ENOTCONN         0x01000038
#		endif
#		ifndef ENOTDIR
#			define ENOTDIR          0x01000039
#		endif
#		ifndef ENOTEMPTY
#			define ENOTEMPTY        0x0100003a
#		endif
#		ifndef ENOTSOCK
#			define ENOTSOCK         0x0100003b
#		endif
#		ifndef ENOTSUP
#			define ENOTSUP          0x0100003c
#		endif
#		ifndef ENOTTY
#			define ENOTTY           0x0100003d
#		endif
#		ifndef ENXIO
#			define ENXIO            0x0100003e
#		endif
#		ifndef EOPNOTSUPP
#			define EOPNOTSUPP       0x0100003f
#		endif
#		ifndef EOVERFLOW
#			define EOVERFLOW        0x01000040
#		endif
#		ifndef EPERM
#			define EPERM            0x01000041
#		endif
#		ifndef EPIPE
#			define EPIPE            0x01000042
#		endif
#		ifndef EPROTO
#			define EPROTO           0x01000043
#		endif
#		ifndef EPROTONOSUPPORT
#			define EPROTONOSUPPORT  0x01000044
#		endif
#		ifndef EPROTOTYPE
#			define EPROTOTYPE       0x01000045
#		endif
#		ifndef ERANGE
#			define ERANGE           0x01000046
#		endif
#		ifndef EROFS
#			define EROFS            0x01000047
#		endif
#		ifndef ESPIPE
#			define ESPIPE           0x01000048
#		endif
#		ifndef ESRCH
#			define ESRCH            0x01000049
#		endif
// Reserved in POSIX
//#		ifndef //ESTALE
//#			define //ESTALE         0x0100004a
//#		endif
#		ifndef ETIME
#			define ETIME            0x0100004b
#		endif
#		ifndef ETIMEDOUT
#			define ETIMEDOUT        0x0100004c
#		endif
#		ifndef ETXTBSY
#			define ETXTBSY          0x0100004d
#		endif
#		ifndef EWOULDBLOCK
#			ifdef EAGAIN
#				define EWOULDBLOCK  EAGAIN
#			else
#				define EWOULDBLOCK  0x0100004e
#			endif
#		endif
#		ifndef EXDEV
#			define EXDEV            0x0100004f
#		endif

// Non-POSIX:
#		ifndef EHOSTDOWN
#			define EHOSTDOWN        0x01100001
#		endif
#		ifndef EPFNOSUPPORT
#			define EPFNOSUPPORT     0x01100002
#		endif
#		ifndef EPROCLIM
#			define EPROCLIM         0x01100003
#		endif
#		ifndef ESHUTDOWN
#			define ESHUTDOWN        0x01100004
#		endif
#		ifndef ESOCKTNOSUPPORT
#			define ESOCKTNOSUPPORT  0x01100005
#		endif
#	elif  defined (__FreeBSD__) || defined (__OpenBSD__)
#		ifndef EBADMSG
#			define EBADMSG EIO
#		endif
#	endif  /* defined (__FreeBSD__) || defined (__OpenBSD__) */
#endif  /* defined (PORT_WANT_ERRNO) */

// Use SDL_INCLUDE to portably include the SDL files from the right location.
// The SDL_DIR definition is provided by the build configuration.
#define SDL_INCLUDE(file) #file

// Mark a function as using printf-style function arguments, so that
// extra consistency checks can be made by the compiler.
// The first argument to PRINTF_FUNCTION and VPRINTF_FUNCTION is the
// index of the format string argument, the second is the index of
// the first argument which is specified in the format string (in the
// case of PRINTF_FUNCTION) or of the va_list argument (in the case of
// VPRINTF_FUNCTION).
#ifdef __GNUC__
#	define PRINTF_FUNCTION(formatArg, firstArg) \
			__attribute__((format(printf, formatArg, firstArg)))
#	define VPRINTF_FUNCTION(formatArg) \
			__attribute__((format(printf, formatArg, 0)))
#else
#	define PRINTF_FUNCTION(formatArg, firstArg)
#	define VPRINTF_FUNCTION(formatArg)
#endif

#if defined(__GNUC__)
#	define _NORETURN __attribute__((noreturn))
#else
#	define _NORETURN
#endif

// Buffered vs. unbuffered logfile
// stderr is normally unbuffered when connected to a terminal, but it
// will be buffered when connected to a file, when a --logfile argument
// is passed to uqm.
// Unbuffered output is slower, which can be significant if much debug output
// is requested, but after a crash occurs the logfile will still be up to
// date.
// On platforms where there is no console, having up-to-date log files
// after a crash is valuable enough to make the logfile unbuffered by
// default there.
#if defined(_WIN32_WCE)
#	define UNBUFFERED_LOGFILE
#endif

// Variations in path handling
#if defined(WIN32) || defined(__SYMBIAN32__)
	// HAVE_DRIVE_LETTERS is defined to signify that DOS/Windows style drive
	// letters are to be recognised on this platform.
#	define HAVE_DRIVE_LETTERS
	// BACKSLASH_IS_PATH_SEPARATOR is defined to signify that the backslash
	// character is to be recognised as a path separator on this platform.
	// This does not affect the acceptance of forward slashes as path
	// separators.
#	define BACKSLASH_IS_PATH_SEPARATOR
#endif
#if defined(WIN32)
	// HAVE_UNC_PATHS is defined to signify that Universal Naming Convention
	// style paths are to be recognised on this platform.
#	define HAVE_UNC_PATHS
	// HAVE_CWD_PER_DRIVE is defined to signify that every drive has its own
	// current working directory.
#	define HAVE_CWD_PER_DRIVE
#endif
// REJECT_DRIVE_PATH_WITHOUT_SLASH can also be defined, if paths of the form
// "d:foo/bar" (without a slash after the drive letter) are to be rejected.

#endif  /* PORT_H_ */