|
|
1.1 root 1: /* genwrap.h */
2:
3: /* General cross-platform development wrappers */
4:
5: /* $Id: genwrap.h,v 1.87 2006/08/14 22:51:12 rswindell Exp $ */
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: * *
11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
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 */
42: #include "gen_defs.h" /* ulong */
43: #include "wrapdll.h" /* DLLEXPORT and DLLCALL */
44:
45: #if defined(__unix__)
46: #include <sched.h> /* sched_yield */
47: #include <time.h> /* clock_t */
48: #include <sys/time.h> /* struct timeval */
49: #include <strings.h> /* strcasecmp() */
50: #include <unistd.h> /* usleep */
51:
52: #ifdef XPDEV_THREAD_SAFE
53: #include <pthread.h>/* Check for GNU PTH libs */
54: #ifdef _PTH_PTHREAD_H_
55: #include <pth.h>
56: #endif
57: #define GetCurrentThreadId() pthread_self()
58: #endif
59: #elif defined(_WIN32)
60: #include <process.h> /* getpid() */
61: #endif
62:
63: #if !defined(_WIN32)
64: /* Simple Win32 function equivalents */
65: #define GetCurrentProcessId() getpid()
66: #endif
67:
68: /* utime() support */
69: #if defined(_MSC_VER) || defined(__WATCOMC__)
70: #include <sys/utime.h>
71: #else
72: #include <utime.h>
73: #endif
74:
75: #if defined(__cplusplus)
76: extern "C" {
77: #endif
78:
79: /*********************/
80: /* Compiler-specific */
81: /*********************/
82:
83: /* Compiler Description */
84: #if defined(__BORLANDC__)
85:
86: #define DESCRIBE_COMPILER(str) SAFEPRINTF2(str,"BCC %X.%02X" \
87: ,__BORLANDC__>>8,__BORLANDC__&0xff);
88:
89: #elif defined(_MSC_VER)
90:
91: #define DESCRIBE_COMPILER(str) SAFEPRINTF(str,"MSC %u", _MSC_VER);
92:
93: #elif defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
94:
95: #define DESCRIBE_COMPILER(str) SAFEPRINTF3(str,"GCC %u.%u.%u" \
96: ,__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
97:
98: #elif defined(__GNUC__) && defined(__GNUC_MINOR__)
99:
100: #define DESCRIBE_COMPILER(str) SAFEPRINTF2(str,"GCC %u.%u" \
101: ,__GNUC__,__GNUC_MINOR__);
102:
103: #elif defined(__WATCOMC__)
104:
105: #define DESCRIBE_COMPILER(str) SAFEPRINTF(str,"WATC %d" \
106: ,__WATCOMC__);
107:
108: #elif defined(__DMC__) /* Digital Mars C/C++ */
109:
110: #define DESCRIBE_COMPILER(str) SAFEPRINTF(str,"DMC %X.%02X" \
111: ,__DMC__>>8,__DMC__&0xff);
112:
113: #else /* Unknown compiler */
114:
115: #define DESCRIBE_COMPILER(str) SAFECOPY(str,"UNKNOWN COMPILER");
116:
117: #endif
118:
119: /**********/
120: /* Macros */
121: /**********/
122:
123: /* Target Platform Description */
124: #if defined(_WIN64)
125: #define PLATFORM_DESC "Win64"
126: #elif defined(_WIN32)
127: #define PLATFORM_DESC "Win32"
128: #elif defined(__OS2__)
129: #define PLATFORM_DESC "OS/2"
130: #elif defined(__MSDOS__)
131: #define PLATFORM_DESC "DOS"
132: #elif defined(__linux__)
133: #define PLATFORM_DESC "Linux"
134: #elif defined(__FreeBSD__)
135: #define PLATFORM_DESC "FreeBSD"
136: #elif defined(__OpenBSD__)
137: #define PLATFORM_DESC "OpenBSD"
138: #elif defined(__NetBSD__)
139: #define PLATFORM_DESC "NetBSD"
140: #elif defined(__APPLE__) && defined(__MACH__) && defined(__POWERPC__)
141: #define PLATFORM_DESC "MacOSX"
142: #elif defined(BSD)
143: #define PLATFORM_DESC "BSD"
144: #elif defined(__solaris__)
145: #define PLATFORM_DESC "Solaris"
146: #elif defined(__sun__)
147: #define PLATFORM_DESC "SunOS"
148: #elif defined(__gnu__)
149: #define PLATFORM_DESC "GNU/Hurd"
150: #elif defined(__QNX__)
151: #define PLATFORM_DESC "QNX"
152: #elif defined(__unix__)
153: #define PLATFORM_DESC "Unix"
154: #else
155: #error "Need to describe target platform"
156: #endif
157:
158: /*********************/
159: /* String Functionss */
160: /*********************/
161:
162: #define snprintf safe_snprintf
163:
164: #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__DMC__)
165: #define vsnprintf _vsnprintf
166: #endif
167:
168: #if defined(__WATCOMC__)
169: #define vsnprintf(s,l,f,a) vsprintf(s,f,a)
170: #endif
171:
172: #if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
173: DLLEXPORT char* DLLCALL ultoa(ulong, char*, int radix);
174: #endif
175:
176: #if defined(__unix__)
177: DLLEXPORT char* DLLCALL strupr(char* str);
178: DLLEXPORT char* DLLCALL strlwr(char* str);
179: DLLEXPORT char* DLLCALL strrev(char* str);
180: #if !defined(stricmp)
181: #define stricmp strcasecmp
182: #define strnicmp strncasecmp
183: #endif
184: #endif
185:
186: /* Truncate white-space chars off end of string */
187: DLLEXPORT char* DLLCALL truncsp(char* str);
188: /* Truncate white-space chars off end of every \n-terminated line in string */
189: DLLEXPORT char* DLLCALL truncsp_lines(char* str);
190: /* Truncate new-line chars off end of string */
191: DLLEXPORT char* DLLCALL truncnl(char* str);
192:
193: #if defined(__unix__)
194: #define STRERROR(x) strerror(x)
195: #else
196: #define STRERROR(x) truncsp(strerror(x))
197: #endif
198:
199: /*********************/
200: /* Utility Functions */
201: /*********************/
202: /* Thunking for multi-threaded specific implementations of "errno" */
203: DLLEXPORT int DLLCALL get_errno(void);
204:
205: /**********************************/
206: /* Common Utility Macro Functions */
207: /**********************************/
208:
209: #if defined(_WIN32)
210:
211: #define YIELD() Sleep(1) /* Must sleep at least 1ms to avoid 100% CPU utilization */
212: #define MAYBE_YIELD() Sleep(0)
213: #define SLEEP(x) Sleep(x)
214: #define popen _popen
215: #define pclose _pclose
216: #if !defined(_MSC_VER) /* Conflicts with latest (Windows 2003 R2) PlatformSDK include/time.h */
217: #define tzname _tzname
218: #endif
219:
220: #elif defined(__OS2__)
221:
222: #define YIELD() DosSleep(1) /* Must sleep at least 1ms to avoid 100% CPU utilization */
223: #define MAYBE_YIELD() DosSleep(0)
224: #define SLEEP(x) DosSleep(x)
225:
226: #elif defined(__unix__) || defined(__APPLE__)
227:
228: #if defined(_PTH_PTHREAD_H_)
229: #define SLEEP(x) ({ int sleep_msecs=x; struct timeval tv; \
230: tv.tv_sec=(sleep_msecs/1000); tv.tv_usec=((sleep_msecs%1000)*1000); \
231: pth_nap(tv); })
232: #else
233: #define SLEEP(x) ({ int sleep_msecs=x; struct timeval tv; \
234: tv.tv_sec=(sleep_msecs/1000); tv.tv_usec=((sleep_msecs%1000)*1000); \
235: select(0,NULL,NULL,NULL,&tv); })
236: #endif
237:
238: #define YIELD() SLEEP(1)
239:
240: #if defined(XPDEV_THREAD_SAFE)
241: #if defined(__FreeBSD__)
242: #define MAYBE_YIELD() pthread_yield()
243: #elif defined(_PTH_PTHREAD_H_)
244: #define MAYBE_YIELD() pth_yield(NULL)
245: #elif defined(_POSIX_PRIORITY_SCHEDULING)
246: #define MAYBE_YIELD() sched_yield()
247: #else
248: #define MAYBE_YIELD() YIELD()
249: #endif
250: #else
251: #if defined(_POSIX_PRIORITY_SCHEDULING)
252: #define MAYBE_YIELD() sched_yield()
253: #else
254: #define MAYBE_YIELD() YIELD()
255: #endif
256: #endif
257:
258: /*
259: * QNX doesn't support fork() in threaded apps (yet) using vfork() instead
260: * works, but relies on undefined behaviours not being nasty. On most OSs
261: * vfork() will share the stack between the parent and child...
262: */
263: #if defined(__QNX__)
264: #define FORK() vfork()
265: #else
266: #define FORK() fork()
267: #endif
268:
269:
270: #else /* Unsupported OS */
271:
272: #error "Unsupported Target: Need some macros and/or function prototypes here."
273:
274: #endif
275:
276: /* Command processor/shell environment variable name */
277: #ifdef __unix__
278: #define OS_CMD_SHELL_ENV_VAR "SHELL"
279: #else /* DOS/Windows/OS2 */
280: #define OS_CMD_SHELL_ENV_VAR "COMSPEC"
281: #endif
282:
283: /* Win32 implementations of recursive (thread-safe) std C time functions on Unix */
284:
285: #if !defined(__unix__)
286:
287: #include <time.h> /* time_t, etc. */
288:
289: DLLEXPORT struct tm* DLLCALL gmtime_r(const time_t* t, struct tm* tm);
290: DLLEXPORT struct tm* DLLCALL localtime_r(const time_t* t, struct tm* tm);
291: DLLEXPORT char* DLLCALL ctime_r(const time_t *t, char *buf);
292: DLLEXPORT char* DLLCALL asctime_r(const struct tm *tm, char *buf);
293: DLLEXPORT char* DLLCALL strtok_r(char *str, const char *delim, char **last);
294:
295: #endif
296:
297: #if defined(__solaris__)
298: #define CTIME_R(x,y) ctime_r(x,y)
299: /* #define CTIME_R(x,y) ctime_r(x,y,sizeof y) */
300: #else
301: #define CTIME_R(x,y) ctime_r(x,y)
302: #endif
303:
304: /* Mimic the Borland randomize() and random() CRTL functions */
305: DLLEXPORT unsigned DLLCALL xp_randomize(void);
306: DLLEXPORT int DLLCALL xp_random(int);
307:
308: DLLEXPORT long double DLLCALL xp_timer(void);
309: DLLEXPORT char* DLLCALL os_version(char *str);
310: DLLEXPORT char* DLLCALL os_cmdshell(void);
311: DLLEXPORT char* DLLCALL lastchar(const char* str);
312: DLLEXPORT int DLLCALL safe_snprintf(char *dst, size_t size, const char *fmt, ...);
313:
314: /* C string/char escape-sequence processing */
315: DLLEXPORT char* DLLCALL c_escape_str(const char* src, char* dst, size_t maxlen, BOOL ctrl_only);
316: DLLEXPORT char* DLLCALL c_escape_char(char ch);
317: DLLEXPORT char* DLLCALL c_unescape_str(char* str);
318: DLLEXPORT char DLLCALL c_unescape_char_ptr(const char* str, char** endptr);
319: DLLEXPORT char DLLCALL c_unescape_char(char ch);
320:
321: /* Microsoft (e.g. DOS/Win32) real-time system clock API (ticks since process started) */
322: typedef clock_t msclock_t;
323: #if defined(_WIN32) || defined(__OS2__)
324: #define MSCLOCKS_PER_SEC CLOCKS_PER_SEC /* e.g. 18.2 on DOS, 1000.0 on Win32 */
325: #define msclock() clock()
326: #else
327: #define MSCLOCKS_PER_SEC 1000
328: msclock_t msclock(void);
329: #endif
330:
331: #if defined(__cplusplus)
332: }
333: #endif
334:
335: #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.