|
|
1.1 root 1: /* genwrap.h */
2:
3: /* General cross-platform development wrappers */
4:
1.1.1.2 ! root 5: /* $Id: genwrap.h,v 1.96 2011/05/11 00:46:32 deuce Exp $ */
1.1 root 6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
1.1.1.2 ! root 11: * Copyright 2010 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 12: * *
13: * This library is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU Lesser General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU Lesser General Public License for more details: lgpl.txt or *
18: * http://www.fsf.org/copyleft/lesser.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #ifndef _GENWRAP_H
39: #define _GENWRAP_H
40:
41: #include <stdio.h> /* sprintf */
1.1.1.2 ! root 42: #include <string.h> /* strerror() */
! 43: #include <time.h> /* clock_t */
1.1 root 44: #include "gen_defs.h" /* ulong */
45: #include "wrapdll.h" /* DLLEXPORT and DLLCALL */
46:
47: #if defined(__unix__)
48: #include <sched.h> /* sched_yield */
49: #include <time.h> /* clock_t */
50: #include <sys/time.h> /* struct timeval */
51: #include <strings.h> /* strcasecmp() */
52: #include <unistd.h> /* usleep */
53:
54: #ifdef XPDEV_THREAD_SAFE
55: #include <pthread.h>/* Check for GNU PTH libs */
56: #ifdef _PTH_PTHREAD_H_
57: #include <pth.h>
58: #endif
59: #define GetCurrentThreadId() pthread_self()
60: #endif
61: #elif defined(_WIN32)
62: #include <process.h> /* getpid() */
1.1.1.2 ! root 63: typedef DWORD pid_t;
1.1 root 64: #endif
65:
66: #if !defined(_WIN32)
67: /* Simple Win32 function equivalents */
68: #define GetCurrentProcessId() getpid()
69: #endif
70:
71: /* utime() support */
72: #if defined(_MSC_VER) || defined(__WATCOMC__)
73: #include <sys/utime.h>
74: #else
75: #include <utime.h>
76: #endif
77:
78: #if defined(__cplusplus)
79: extern "C" {
80: #endif
81:
82: /*********************/
83: /* Compiler-specific */
84: /*********************/
85:
86: /* Compiler Description */
87: #if defined(__BORLANDC__)
88:
89: #define DESCRIBE_COMPILER(str) SAFEPRINTF2(str,"BCC %X.%02X" \
90: ,__BORLANDC__>>8,__BORLANDC__&0xff);
91:
92: #elif defined(_MSC_VER)
93:
94: #define DESCRIBE_COMPILER(str) SAFEPRINTF(str,"MSC %u", _MSC_VER);
95:
96: #elif defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
97:
98: #define DESCRIBE_COMPILER(str) SAFEPRINTF3(str,"GCC %u.%u.%u" \
99: ,__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
100:
101: #elif defined(__GNUC__) && defined(__GNUC_MINOR__)
102:
103: #define DESCRIBE_COMPILER(str) SAFEPRINTF2(str,"GCC %u.%u" \
104: ,__GNUC__,__GNUC_MINOR__);
105:
106: #elif defined(__WATCOMC__)
107:
108: #define DESCRIBE_COMPILER(str) SAFEPRINTF(str,"WATC %d" \
109: ,__WATCOMC__);
110:
111: #elif defined(__DMC__) /* Digital Mars C/C++ */
112:
113: #define DESCRIBE_COMPILER(str) SAFEPRINTF(str,"DMC %X.%02X" \
114: ,__DMC__>>8,__DMC__&0xff);
115:
116: #else /* Unknown compiler */
117:
118: #define DESCRIBE_COMPILER(str) SAFECOPY(str,"UNKNOWN COMPILER");
119:
120: #endif
121:
122: /**********/
123: /* Macros */
124: /**********/
125:
126: /* Target Platform Description */
127: #if defined(_WIN64)
128: #define PLATFORM_DESC "Win64"
129: #elif defined(_WIN32)
130: #define PLATFORM_DESC "Win32"
131: #elif defined(__OS2__)
132: #define PLATFORM_DESC "OS/2"
133: #elif defined(__MSDOS__)
134: #define PLATFORM_DESC "DOS"
135: #elif defined(__linux__)
136: #define PLATFORM_DESC "Linux"
137: #elif defined(__FreeBSD__)
138: #define PLATFORM_DESC "FreeBSD"
139: #elif defined(__OpenBSD__)
140: #define PLATFORM_DESC "OpenBSD"
141: #elif defined(__NetBSD__)
142: #define PLATFORM_DESC "NetBSD"
143: #elif defined(__APPLE__) && defined(__MACH__) && defined(__POWERPC__)
144: #define PLATFORM_DESC "MacOSX"
145: #elif defined(BSD)
146: #define PLATFORM_DESC "BSD"
147: #elif defined(__solaris__)
148: #define PLATFORM_DESC "Solaris"
149: #elif defined(__sun__)
150: #define PLATFORM_DESC "SunOS"
151: #elif defined(__gnu__)
152: #define PLATFORM_DESC "GNU/Hurd"
153: #elif defined(__QNX__)
154: #define PLATFORM_DESC "QNX"
155: #elif defined(__unix__)
156: #define PLATFORM_DESC "Unix"
157: #else
158: #error "Need to describe target platform"
159: #endif
160:
1.1.1.2 ! root 161: #if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__amd64__)
! 162: #define ARCHITECTURE_DESC "x64"
! 163: #elif defined(__i386__) || _M_IX86 == 300
! 164: #define ARCHITECTURE_DESC "i386"
! 165: #elif defined(__i486__) || _M_IX86 == 400
! 166: #define ARCHITECTURE_DESC "i486"
! 167: #elif defined(__i586__) || _M_IX86 == 500
! 168: #define ARCHITECTURE_DESC "i586"
! 169: #elif defined(__i686__) || _M_IX86 == 600
! 170: #define ARCHITECTURE_DESC "i686"
! 171: #elif defined(__i786__) || _M_IX86 == 700
! 172: #define ARCHITECTURE_DESC "i786"
! 173: #elif defined(_X86_) || defined(__x86__) || defined(_M_IX86)
! 174: #define ARCHITECTURE_DESC "x86"
! 175: #elif defined(__mips__)
! 176: #define ARCHITECTURE_DESC "mips"
! 177: #elif defined(__arm__)
! 178: #define ARCHITECTURE_DESC "arm"
! 179: #elif defined(_M_PPC) || defined(__ppc__)
! 180: #define ARCHITECTURE_DESC "ppc"
! 181: #elif defined(_M_IA64) || defined(__ia64__)
! 182: #define ARCHITECTURE_DESC "ia64"
! 183: #else
! 184: #error "Need to describe target architecture"
! 185: #endif
! 186:
1.1 root 187: /*********************/
188: /* String Functionss */
189: /*********************/
190:
1.1.1.2 ! root 191: #ifndef USE_SNPRINTF
! 192: #define snprintf safe_snprintf
! 193: #endif
1.1 root 194:
195: #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__DMC__)
1.1.1.2 ! root 196: #if !defined(snprintf)
! 197: #define snprintf _snprintf
! 198: #endif
1.1 root 199: #define vsnprintf _vsnprintf
200: #endif
201:
202: #if defined(__WATCOMC__)
203: #define vsnprintf(s,l,f,a) vsprintf(s,f,a)
204: #endif
205:
206: #if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
207: DLLEXPORT char* DLLCALL ultoa(ulong, char*, int radix);
208: #endif
209:
210: #if defined(__unix__)
211: DLLEXPORT char* DLLCALL strupr(char* str);
212: DLLEXPORT char* DLLCALL strlwr(char* str);
213: DLLEXPORT char* DLLCALL strrev(char* str);
214: #if !defined(stricmp)
215: #define stricmp strcasecmp
216: #define strnicmp strncasecmp
217: #endif
218: #endif
219:
1.1.1.2 ! root 220: /* Skip white-space chars at beginning of string */
! 221: DLLEXPORT char* DLLCALL skipsp(char* str);
1.1 root 222: /* Truncate white-space chars off end of string */
223: DLLEXPORT char* DLLCALL truncsp(char* str);
224: /* Truncate white-space chars off end of every \n-terminated line in string */
225: DLLEXPORT char* DLLCALL truncsp_lines(char* str);
226: /* Truncate new-line chars off end of string */
227: DLLEXPORT char* DLLCALL truncnl(char* str);
228:
229: #if defined(__unix__)
230: #define STRERROR(x) strerror(x)
231: #else
232: #define STRERROR(x) truncsp(strerror(x))
233: #endif
234:
235: /*********************/
236: /* Utility Functions */
237: /*********************/
238: /* Thunking for multi-threaded specific implementations of "errno" */
239: DLLEXPORT int DLLCALL get_errno(void);
240:
241: /**********************************/
242: /* Common Utility Macro Functions */
243: /**********************************/
244:
245: #if defined(_WIN32)
246:
247: #define YIELD() Sleep(1) /* Must sleep at least 1ms to avoid 100% CPU utilization */
248: #define MAYBE_YIELD() Sleep(0)
249: #define SLEEP(x) Sleep(x)
250: #define popen _popen
251: #define pclose _pclose
252: #if !defined(_MSC_VER) /* Conflicts with latest (Windows 2003 R2) PlatformSDK include/time.h */
253: #define tzname _tzname
254: #endif
255:
256: #elif defined(__OS2__)
257:
258: #define YIELD() DosSleep(1) /* Must sleep at least 1ms to avoid 100% CPU utilization */
259: #define MAYBE_YIELD() DosSleep(0)
260: #define SLEEP(x) DosSleep(x)
261:
262: #elif defined(__unix__) || defined(__APPLE__)
263:
264: #if defined(_PTH_PTHREAD_H_)
265: #define SLEEP(x) ({ int sleep_msecs=x; struct timeval tv; \
266: tv.tv_sec=(sleep_msecs/1000); tv.tv_usec=((sleep_msecs%1000)*1000); \
267: pth_nap(tv); })
268: #else
269: #define SLEEP(x) ({ int sleep_msecs=x; struct timeval tv; \
270: tv.tv_sec=(sleep_msecs/1000); tv.tv_usec=((sleep_msecs%1000)*1000); \
271: select(0,NULL,NULL,NULL,&tv); })
272: #endif
273:
274: #define YIELD() SLEEP(1)
275:
276: #if defined(XPDEV_THREAD_SAFE)
277: #if defined(__FreeBSD__)
278: #define MAYBE_YIELD() pthread_yield()
279: #elif defined(_PTH_PTHREAD_H_)
280: #define MAYBE_YIELD() pth_yield(NULL)
281: #elif defined(_POSIX_PRIORITY_SCHEDULING)
282: #define MAYBE_YIELD() sched_yield()
283: #else
284: #define MAYBE_YIELD() YIELD()
285: #endif
286: #else
287: #if defined(_POSIX_PRIORITY_SCHEDULING)
288: #define MAYBE_YIELD() sched_yield()
289: #else
290: #define MAYBE_YIELD() YIELD()
291: #endif
292: #endif
293:
294: /*
295: * QNX doesn't support fork() in threaded apps (yet) using vfork() instead
296: * works, but relies on undefined behaviours not being nasty. On most OSs
297: * vfork() will share the stack between the parent and child...
298: */
299: #if defined(__QNX__)
300: #define FORK() vfork()
301: #else
302: #define FORK() fork()
303: #endif
304:
305:
306: #else /* Unsupported OS */
307:
308: #error "Unsupported Target: Need some macros and/or function prototypes here."
309:
310: #endif
311:
312: /* Command processor/shell environment variable name */
313: #ifdef __unix__
314: #define OS_CMD_SHELL_ENV_VAR "SHELL"
315: #else /* DOS/Windows/OS2 */
316: #define OS_CMD_SHELL_ENV_VAR "COMSPEC"
317: #endif
318:
319: /* Win32 implementations of recursive (thread-safe) std C time functions on Unix */
320: #if !defined(__unix__)
321:
322: DLLEXPORT char* DLLCALL strtok_r(char *str, const char *delim, char **last);
323: #endif
324:
325: /* Mimic the Borland randomize() and random() CRTL functions */
1.1.1.2 ! root 326: DLLEXPORT void DLLCALL xp_randomize(void);
! 327: DLLEXPORT long DLLCALL xp_random(int);
1.1 root 328:
329: DLLEXPORT long double DLLCALL xp_timer(void);
330: DLLEXPORT char* DLLCALL os_version(char *str);
331: DLLEXPORT char* DLLCALL os_cmdshell(void);
332: DLLEXPORT char* DLLCALL lastchar(const char* str);
333: DLLEXPORT int DLLCALL safe_snprintf(char *dst, size_t size, const char *fmt, ...);
334:
335: /* C string/char escape-sequence processing */
336: DLLEXPORT char* DLLCALL c_escape_str(const char* src, char* dst, size_t maxlen, BOOL ctrl_only);
337: DLLEXPORT char* DLLCALL c_escape_char(char ch);
338: DLLEXPORT char* DLLCALL c_unescape_str(char* str);
339: DLLEXPORT char DLLCALL c_unescape_char_ptr(const char* str, char** endptr);
340: DLLEXPORT char DLLCALL c_unescape_char(char ch);
341:
342: /* Microsoft (e.g. DOS/Win32) real-time system clock API (ticks since process started) */
343: typedef clock_t msclock_t;
344: #if defined(_WIN32) || defined(__OS2__)
345: #define MSCLOCKS_PER_SEC CLOCKS_PER_SEC /* e.g. 18.2 on DOS, 1000.0 on Win32 */
346: #define msclock() clock()
347: #else
348: #define MSCLOCKS_PER_SEC 1000
349: msclock_t msclock(void);
350: #endif
351:
1.1.1.2 ! root 352: DLLEXPORT BOOL DLLCALL check_pid(pid_t);
! 353: DLLEXPORT BOOL DLLCALL terminate_pid(pid_t);
! 354:
1.1 root 355: #if defined(__cplusplus)
356: }
357: #endif
358:
359: #endif /* Don't add anything after this line */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.