Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/mpg123/src/compat/compat.h
4393 views
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-23 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
19
// We are using C99 now, including possibly single-precision math.
20
#define _ISO_C99_SOURCE
21
22
#include <errno.h>
23
24
/* realloc, size_t */
25
#include <stdlib.h>
26
27
#include <stddef.h>
28
29
#include <stdio.h>
30
#include <math.h>
31
32
#ifdef HAVE_SIGNAL_H
33
#include <signal.h>
34
#else
35
#ifdef HAVE_SYS_SIGNAL_H
36
#include <sys/signal.h>
37
#endif
38
#endif
39
40
#ifdef HAVE_UNISTD_H
41
#include <unistd.h>
42
#endif
43
44
/* Types, types, types. */
45
/* Do we actually need these two in addition to sys/types.h? As replacement? */
46
#ifdef HAVE_SYS_TYPES_H
47
#include <sys/types.h>
48
#endif
49
#include <inttypes.h>
50
#include <stdint.h>
51
/* We want SIZE_MAX, etc. */
52
#include <limits.h>
53
54
#ifndef SIZE_MAX
55
#define SIZE_MAX ((size_t)-1)
56
#endif
57
#ifndef SSIZE_MAX
58
#define SSIZE_MAX ((size_t)-1/2)
59
#endif
60
#ifndef PTRDIFF_MAX
61
#define PTRDIFF_MAX SSIZE_MAX
62
#endif
63
#ifndef ULONG_MAX
64
#define ULONG_MAX ((unsigned long)-1)
65
#endif
66
67
#ifndef INT64_MAX
68
#define INT64_MAX 9223372036854775807LL
69
#endif
70
#ifndef INT64_MIN
71
#define INT64_MIN (-INT64_MAX - 1)
72
#endif
73
#ifndef INT32_MAX
74
#define INT32_MAX 2147483647L
75
#endif
76
#ifndef INT32_MIN
77
#define INT32_MIN (-INT32_MAX - 1)
78
#endif
79
80
// Add two values (themselves assumed to be < limit), saturating to given limit.
81
#define SATURATE_ADD(inout, add, limit) inout = (limit-add >= inout) ? inout+add : limit;
82
#define SATURATE_SUB(inout, sub, limit) inout = (limit+sub >= inout) ? inout-sub : limit;
83
84
#include <string.h>
85
#ifdef HAVE_STRINGS_H
86
#include <strings.h>
87
#endif
88
89
#ifdef __OS2__
90
#include <float.h>
91
#endif
92
93
#ifdef HAVE_SYS_TIME_H
94
#include <sys/time.h>
95
#endif
96
/* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h */
97
#ifdef HAVE_SYS_SELECT_H
98
#include <sys/select.h>
99
#endif
100
101
/* INT123_compat_open makes little sense without */
102
#include <fcntl.h>
103
104
/* To parse big numbers... */
105
#ifdef HAVE_ATOLL
106
#define atobigint atoll
107
#else
108
#define atobigint atol
109
#endif
110
111
typedef unsigned char byte;
112
113
// Annoying hackery to select a safe strtok variant. MS decided to call their strtok_r strtok_s, while
114
// C11 declares another strtok_s with different prototype. Thanks to you all.
115
#ifdef HAVE_STRTOK_R
116
#define INT123_compat_strtok(a, b, c) strtok_r((a), (b), (c))
117
#endif
118
119
#if (defined(_UCRT) || defined(_MSC_VER) || (defined(__MINGW32__) || defined(__MINGW64__)) || (defined(__WATCOMC__) && defined(__NT__))) && !defined(__CYGWIN__)
120
#define MPG123_COMPAT_MSVCRT_IO
121
#ifndef INT123_compat_strtok
122
#define INT123_compat_strtok(a, b, c) strtok_s((a), (b), (c))
123
#endif
124
#endif
125
126
#if defined(MPG123_COMPAT_MSVCRT_IO)
127
#if defined(_UCRT)
128
// needs to get checked separately from MSVC and MinGW becuase it is also used by native Clang on Windows
129
#ifndef MPG123_COMPAT_MSVCRT_IO_64
130
#define MPG123_COMPAT_MSVCRT_IO_64
131
#endif
132
#endif
133
#if defined(_MSC_VER)
134
#if (_MSC_VER >= 1200)
135
// >= VC6
136
#ifndef MPG123_COMPAT_MSVCRT_IO_64
137
#define MPG123_COMPAT_MSVCRT_IO_64
138
#endif
139
#endif
140
#endif
141
#if defined(__MINGW32__) || defined(__MINGW64__)
142
#if (defined(__MSVCRT__) || defined(_UCRT)) && !defined(__CRTDLL__)
143
#ifndef MPG123_COMPAT_MSVCRT_IO_64
144
#define MPG123_COMPAT_MSVCRT_IO_64
145
#endif
146
#endif
147
#endif
148
#if defined(__WATCOMC__) && defined(__NT__)
149
#if (__WATCOMC__ >= 1100)
150
#ifndef MPG123_COMPAT_MSVCRT_IO_64
151
#define MPG123_COMPAT_MSVCRT_IO_64
152
#endif
153
#endif
154
#endif
155
#endif
156
157
#if defined(HAVE__SETMODE) || defined(HAVE_SETMODE) || defined(MPG123_COMPAT_MSVCRT_IO)
158
// For _setmode(), at least.
159
#include <io.h>
160
#endif
161
162
#ifndef INT123_compat_strtok
163
#warning "no safe strtok found"
164
#define INT123_compat_strtok(a, b, c) strtok((a), (b))
165
#endif
166
167
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
168
void *INT123_safe_realloc(void *ptr, size_t size);
169
// Also freeing ptr if result is NULL. You can do
170
// ptr = INT123_safer_realloc(ptr, size)
171
// Also, ptr = INT123_safer_realloc(ptr, 0) will do free(ptr); ptr=NULL;.
172
void *INT123_safer_realloc(void *ptr, size_t size);
173
const char *INT123_strerror(int errnum);
174
175
/* Roll our own strdup() that does not depend on libc feature test macros
176
and returns NULL on NULL input instead of crashing. */
177
char* INT123_compat_strdup(const char *s);
178
179
/* Get an environment variable, possibly converted to UTF-8 from wide string.
180
The return value is a copy that you shall free. */
181
char *INT123_compat_getenv(const char* name);
182
183
/**
184
* Opening a file handle can be different.
185
* 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.
186
* @param[in] wptr Pointer to wide string.
187
* @param[in] mbptr Pointer to multibyte string.
188
* @return file descriptor (>=0) or error code.
189
*/
190
int INT123_compat_open(const char *filename, int flags);
191
FILE* INT123_compat_fopen(const char *filename, const char *mode);
192
/**
193
* Also fdopen to avoid having to define POSIX macros in various source files.
194
*/
195
FILE* INT123_compat_fdopen(int fd, const char *mode);
196
197
/**
198
* Closing a file handle can be platform specific.
199
* This function takes a file descriptor that is to be closed.
200
* @param[in] infd File descriptor to be closed.
201
* @return 0 if the file was successfully closed. A return value of -1 indicates an error.
202
*/
203
int INT123_compat_close(int infd);
204
int INT123_compat_fclose(FILE* stream);
205
206
/**
207
* Setting binary mode on a descriptor, where necessary.
208
* We do not bother with errors. This has to work.
209
* You can enable or disable binary mode.
210
*/
211
void INT123_compat_binmode(int fd, int enable);
212
213
/* 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. */
214
215
#if defined (_WIN32) || defined (__CYGWIN__)
216
/**
217
* win32_uni2mbc
218
* Converts a null terminated UCS-2 string to a multibyte (UTF-8) equivalent.
219
* Caller is supposed to free allocated buffer.
220
* @param[in] wptr Pointer to wide string.
221
* @param[out] mbptr Pointer to multibyte string.
222
* @param[out] buflen Optional parameter for length of allocated buffer.
223
* @return status of WideCharToMultiByte conversion.
224
*
225
* WideCharToMultiByte - http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspx
226
*/
227
int INT123_win32_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t * buflen);
228
229
/**
230
* win32_uni2mbc
231
* Converts a null terminated UCS-2 string to a multibyte (UTF-7) equivalent.
232
* Caller is supposed to free allocated buffer.
233
* @param[in] wptr Pointer to wide string.
234
* @param[out] mbptr Pointer to multibyte string.
235
* @param[out] buflen Optional parameter for length of allocated buffer.
236
* @return status of WideCharToMultiByte conversion.
237
*
238
* WideCharToMultiByte - http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspx
239
*/
240
int INT123_win32_wide_utf7(const wchar_t * const wptr, char **mbptr, size_t * buflen);
241
242
/**
243
* win32_mbc2uni
244
* Converts a null terminated UTF-8 string to a UCS-2 equivalent.
245
* Caller is supposed to free allocated buffer.
246
* @param[in] mbptr Pointer to multibyte string.
247
* @param[out] wptr Pointer to wide string.
248
* @param[out] buflen Optional parameter for length of allocated buffer.
249
* @return status of WideCharToMultiByte conversion.
250
*
251
* MultiByteToWideChar - http://msdn.microsoft.com/en-us/library/dd319072(VS.85).aspx
252
*/
253
254
int INT123_win32_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen);
255
#endif
256
257
/*
258
A little bit of path abstraction: We always work with plain char strings
259
that usually represent POSIX-ish UTF-8 paths (something like c:/some/file
260
might appear). For Windows, those are converted to wide strings with \
261
instead of / and possible fun is had with prefixes to get around the old
262
path length limit. Outside of the compat library, that stuff should not
263
matter, although something like //?/UNC/server/some/file could be thrown
264
around as UTF-8 string, to be converted to a wide \\?\UNC\server\some\file
265
just before handing it to Windows API.
266
267
There is a lot of unnecessary memory allocation and string copying because
268
of this, but this filesystem stuff is not really relevant to mpg123
269
performance, so the goal is to keep the code outside the compatibility layer
270
simple.
271
*/
272
273
/*
274
Concatenate a prefix and a path, one of them alowed to be NULL.
275
If the path is already absolute, the prefix is ignored. Relative
276
parts (like /..) are resolved if this is sensible for the platform
277
(meaning: for Windows), else they are preserved (on POSIX, actual
278
file system access would be needed because of symlinks).
279
*/
280
char* INT123_compat_catpath(const char *prefix, const char* path);
281
282
/* Return 1 if the given path indicates an existing directory,
283
0 otherwise. */
284
int INT123_compat_isdir(const char *path);
285
286
/*
287
Directory traversal. This talks ASCII/UTF-8 paths externally, converts
288
to/from wchar_t internally if the platform wants that. Returning NULL
289
means failure to open/end of listing.
290
There is no promise about sorting entries.
291
*/
292
struct compat_dir;
293
/* Returns NULL if either directory failed to open or listing is empty.
294
Listing can still be empty even if non-NULL, so always rely on the
295
nextfile/nextdir functions. */
296
struct compat_dir* INT123_compat_diropen(char *path);
297
void INT123_compat_dirclose(struct compat_dir*);
298
/* Get the next entry that is a file (or symlink to one).
299
The returned string is a copy that needs to be freed after use. */
300
char* INT123_compat_nextfile(struct compat_dir*);
301
/* Get the next entry that is a directory (or symlink to one).
302
The returned string is a copy that needs to be freed after use. */
303
char* INT123_compat_nextdir (struct compat_dir*);
304
305
#ifdef USE_MODULES
306
/*
307
For keeping the path mess local, a system-specific dlopen() variant
308
is contained in here, too. This is very thin wrapping, even sparing
309
definition of a handle type, just using void pointers.
310
Use of absolute paths is a good idea if you want to be sure which
311
file is openend, as default search paths vary.
312
*/
313
void *INT123_compat_dlopen (const char *path);
314
void *INT123_compat_dlsym (void *handle, const char* name);
315
void INT123_compat_dlclose(void *handle);
316
#endif
317
318
/* Blocking write/read of data with signal resilience.
319
They continue after being interrupted by signals and always return the
320
amount of processed data (shortage indicating actual problem or EOF). */
321
size_t INT123_unintr_write(int fd, void const *buffer, size_t bytes);
322
size_t INT123_unintr_read (int fd, void *buffer, size_t bytes);
323
size_t INT123_unintr_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
324
325
/* OSX SDK defines an enum with "normal" as value. That clashes with
326
optimize.h */
327
#ifdef __APPLE__
328
#define normal mpg123_normal
329
#endif
330
331
#include "../common/true.h"
332
333
#if (!defined(WIN32) || defined (__CYGWIN__)) && defined(HAVE_SIGNAL_H)
334
void (*INT123_catchsignal(int signum, void(*handler)(int)))(int);
335
#endif
336
337
// Some ancient toolchains miss the documented errno value.
338
#if defined(_WIN32) && !defined(EOVERFLOW)
339
#define EOVERFLOW 132
340
#endif
341
342
#endif
343
344