[LIBMPG123]
[reactos.git] / reactos / sdk / include / reactos / libs / libmpg123 / compat.h
1 /*
2 compat: Some compatibility functions and header inclusions.
3 Basic standard C stuff, that may barely be above/around C89.
4
5 The mpg123 code is determined to keep it's legacy. A legacy of old, old UNIX.
6 It is envisioned to include this compat header instead of any of the "standard" headers, to catch compatibility issues.
7 So, don't include stdlib.h or string.h ... include compat.h.
8
9 copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
10 see COPYING and AUTHORS files in distribution or http://mpg123.org
11 initially written by Thomas Orgis
12 */
13
14 #ifndef MPG123_COMPAT_H
15 #define MPG123_COMPAT_H
16
17 #include "config.h"
18 #include "intsym.h"
19
20 /* For --nagging compilation with -std=c89, we need
21 to disable the inline keyword. */
22 #ifdef PLAIN_C89
23 #ifndef inline
24 #define inline
25 #endif
26 #endif
27
28 #include <errno.h>
29
30 #ifdef HAVE_STDLIB_H
31 /* realloc, size_t */
32 #include <stdlib.h>
33 #endif
34
35 #include <stdio.h>
36 #include <math.h>
37
38 #ifdef HAVE_SIGNAL_H
39 #include <signal.h>
40 #else
41 #ifdef HAVE_SYS_SIGNAL_H
42 #include <sys/signal.h>
43 #endif
44 #endif
45
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49
50 /* Types, types, types. */
51 /* Do we actually need these two in addition to sys/types.h? As replacement? */
52 #ifdef HAVE_SYS_TYPES_H
53 #include <sys/types.h>
54 #endif
55 #ifdef HAVE_INTTYPES_H
56 #include <inttypes.h>
57 #endif
58 #ifdef HAVE_STDINT_H
59 #include <stdint.h>
60 #endif
61 /* We want SIZE_MAX, etc. */
62 #ifdef HAVE_LIMITS_H
63 #include <limits.h>
64 #endif
65
66 #ifndef SIZE_MAX
67 #define SIZE_MAX ((size_t)-1)
68 #endif
69 #ifndef ULONG_MAX
70 #define ULONG_MAX ((unsigned long)-1)
71 #endif
72
73 #ifdef HAVE_STRING_H
74 #include <string.h>
75 #endif
76 #ifdef HAVE_STRINGS_H
77 #include <strings.h>
78 #endif
79
80 #ifdef OS2
81 #include <float.h>
82 #endif
83
84 #ifdef HAVE_SYS_TIME_H
85 #include <sys/time.h>
86 #endif
87 /* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h */
88 #ifdef HAVE_SYS_SELECT_H
89 #include <sys/select.h>
90 #endif
91
92 /* compat_open makes little sense without */
93 #include <fcntl.h>
94
95 /* To parse big numbers... */
96 #ifdef HAVE_ATOLL
97 #define atobigint atoll
98 #else
99 #define atobigint atol
100 #endif
101
102 typedef unsigned char byte;
103
104 #ifndef __REACTOS__
105 #if defined(_MSC_VER) && !defined(MPG123_DEF_SSIZE_T)
106 #define MPG123_DEF_SSIZE_T
107 #include <stddef.h>
108 typedef ptrdiff_t ssize_t;
109 #endif
110 #endif /* __REACTOS__ */
111
112 /* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
113 void *safe_realloc(void *ptr, size_t size);
114 #ifndef HAVE_STRERROR
115 const char *strerror(int errnum);
116 #endif
117
118 /* Roll our own strdup() that does not depend on libc feature test macros
119 and returns NULL on NULL input instead of crashing. */
120 char* compat_strdup(const char *s);
121
122 /* If we have the size checks enabled, try to derive some sane printfs.
123 Simple start: Use max integer type and format if long is not big enough.
124 I am hesitating to use %ll without making sure that it's there... */
125 #if !(defined PLAIN_C89) && (defined SIZEOF_OFF_T) && (SIZEOF_OFF_T > SIZEOF_LONG) && (defined PRIiMAX)
126 # define OFF_P PRIiMAX
127 typedef intmax_t off_p;
128 #else
129 # define OFF_P "li"
130 typedef long off_p;
131 #endif
132
133 #if !(defined PLAIN_C89) && (defined SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > SIZEOF_LONG) && (defined PRIuMAX)
134 # define SIZE_P PRIuMAX
135 typedef uintmax_t size_p;
136 #else
137 # define SIZE_P "lu"
138 typedef unsigned long size_p;
139 #endif
140
141 #if !(defined PLAIN_C89) && (defined SIZEOF_SSIZE_T) && (SIZEOF_SSIZE_T > SIZEOF_LONG) && (defined PRIiMAX)
142 # define SSIZE_P PRIuMAX
143 typedef intmax_t ssize_p;
144 #else
145 # define SSIZE_P "li"
146 typedef long ssize_p;
147 #endif
148
149 /* Get an environment variable, possibly converted to UTF-8 from wide string.
150 The return value is a copy that you shall free. */
151 char *compat_getenv(const char* name);
152
153 /**
154 * Opening a file handle can be different.
155 * This function here is defined to take a path in native encoding (ISO8859 / UTF-8 / ...), or, when MS Windows Unicode support is enabled, an UTF-8 string that will be converted back to native UCS-2 (wide character) before calling the system's open function.
156 * @param[in] wptr Pointer to wide string.
157 * @param[in] mbptr Pointer to multibyte string.
158 * @return file descriptor (>=0) or error code.
159 */
160 int compat_open(const char *filename, int flags);
161 FILE* compat_fopen(const char *filename, const char *mode);
162 /**
163 * Also fdopen to avoid having to define POSIX macros in various source files.
164 */
165 FILE* compat_fdopen(int fd, const char *mode);
166
167 /**
168 * Closing a file handle can be platform specific.
169 * This function takes a file descriptor that is to be closed.
170 * @param[in] infd File descriptor to be closed.
171 * @return 0 if the file was successfully closed. A return value of -1 indicates an error.
172 */
173 int compat_close(int infd);
174 int compat_fclose(FILE* stream);
175
176 /* Those do make sense in a separate file, but I chose to include them in compat.c because that's the one source whose object is shared between mpg123 and libmpg123 -- and both need the functionality internally. */
177
178 #ifdef WANT_WIN32_UNICODE
179 /**
180 * win32_uni2mbc
181 * Converts a null terminated UCS-2 string to a multibyte (UTF-8) equivalent.
182 * Caller is supposed to free allocated buffer.
183 * @param[in] wptr Pointer to wide string.
184 * @param[out] mbptr Pointer to multibyte string.
185 * @param[out] buflen Optional parameter for length of allocated buffer.
186 * @return status of WideCharToMultiByte conversion.
187 *
188 * WideCharToMultiByte - http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspx
189 */
190 int win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen);
191
192 /**
193 * win32_mbc2uni
194 * Converts a null terminated UTF-8 string to a UCS-2 equivalent.
195 * Caller is supposed to free allocated buffer.
196 * @param[out] mbptr Pointer to multibyte string.
197 * @param[in] wptr Pointer to wide string.
198 * @param[out] buflen Optional parameter for length of allocated buffer.
199 * @return status of WideCharToMultiByte conversion.
200 *
201 * MultiByteToWideChar - http://msdn.microsoft.com/en-us/library/dd319072(VS.85).aspx
202 */
203
204 int win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen);
205 #endif
206
207 /*
208 A little bit of path abstraction: We always work with plain char strings
209 that usually represent POSIX-ish UTF-8 paths (something like c:/some/file
210 might appear). For Windows, those are converted to wide strings with \
211 instead of / and possible fun is had with prefixes to get around the old
212 path length limit. Outside of the compat library, that stuff should not
213 matter, although something like //?/UNC/server/some/file could be thrown
214 around as UTF-8 string, to be converted to a wide \\?\UNC\server\some\file
215 just before handing it to Windows API.
216
217 There is a lot of unnecessary memory allocation and string copying because
218 of this, but this filesystem stuff is not really relevant to mpg123
219 performance, so the goal is to keep the code outside the compatibility layer
220 simple.
221 */
222
223 /*
224 Concatenate a prefix and a path, one of them alowed to be NULL.
225 If the path is already absolute, the prefix is ignored. Relative
226 parts (like /..) are resolved if this is sensible for the platform
227 (meaning: for Windows), else they are preserved (on POSIX, actual
228 file system access would be needed because of symlinks).
229 */
230 char* compat_catpath(const char *prefix, const char* path);
231
232 /* Return 1 if the given path indicates an existing directory,
233 0 otherwise. */
234 int compat_isdir(const char *path);
235
236 /*
237 Directory traversal. This talks ASCII/UTF-8 paths externally, converts
238 to/from wchar_t internally if the platform wants that. Returning NULL
239 means failure to open/end of listing.
240 There is no promise about sorting entries.
241 */
242 struct compat_dir;
243 /* Returns NULL if either directory failed to open or listing is empty.
244 Listing can still be empty even if non-NULL, so always rely on the
245 nextfile/nextdir functions. */
246 struct compat_dir* compat_diropen(char *path);
247 void compat_dirclose(struct compat_dir*);
248 /* Get the next entry that is a file (or symlink to one).
249 The returned string is a copy that needs to be freed after use. */
250 char* compat_nextfile(struct compat_dir*);
251 /* Get the next entry that is a directory (or symlink to one).
252 The returned string is a copy that needs to be freed after use. */
253 char* compat_nextdir (struct compat_dir*);
254
255 #ifdef USE_MODULES
256 /*
257 For keeping the path mess local, a system-specific dlopen() variant
258 is contained in here, too. This is very thin wrapping, even sparing
259 definition of a handle type, just using void pointers.
260 Use of absolute paths is a good idea if you want to be sure which
261 file is openend, as default search paths vary.
262 */
263 void *compat_dlopen (const char *path);
264 void *compat_dlsym (void *handle, const char* name);
265 void compat_dlclose(void *handle);
266 #endif
267
268 /* Blocking write/read of data with signal resilience.
269 Both continue after being interrupted by signals and always return the
270 amount of processed data (shortage indicating actual problem or EOF). */
271 size_t unintr_write(int fd, void const *buffer, size_t bytes);
272 size_t unintr_read (int fd, void *buffer, size_t bytes);
273
274 /* That one comes from Tellie on OS/2, needed in resolver. */
275 #ifdef __KLIBC__
276 typedef int socklen_t;
277 #endif
278
279 /* OSX SDK defines an enum with "normal" as value. That clashes with
280 optimize.h */
281 #ifdef __APPLE__
282 #define normal mpg123_normal
283 #endif
284
285 #include "true.h"
286
287 #if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
288 void (*catchsignal(int signum, void(*handler)()))();
289 #endif
290
291 #endif