]> git.sesse.net Git - vlc/blob - include/vlc_fixups.h
WInCE: fix infinite loop in vasprintf replacement
[vlc] / include / vlc_fixups.h
1 /*****************************************************************************
2  * fixups.h: portability fixups included from config.h
3  *****************************************************************************
4  * Copyright © 1998-2008 the VideoLAN project
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20
21 /**
22  * \file
23  * This file is a collection of portability fixes
24  */
25
26 #ifndef LIBVLC_FIXUPS_H
27 # define LIBVLC_FIXUPS_H 1
28
29 #ifndef HAVE_STRDUP
30 # include <string.h>
31 # include <stdlib.h>
32 static inline char *strdup (const char *str)
33 {
34     size_t len = strlen (str) + 1;
35     char *res = (char *)malloc (len);
36     if (res) memcpy (res, str, len);
37     return res;
38 }
39 #endif
40
41 #ifndef HAVE_VASPRINTF
42 # include <stdio.h>
43 # include <stdlib.h>
44 # include <stdarg.h>
45 static inline int vasprintf (char **strp, const char *fmt, va_list ap)
46 {
47 #ifndef UNDER_CE
48     int len = vsnprintf (NULL, 0, fmt, ap) + 1;
49     char *res = (char *)malloc (len);
50     if (res == NULL)
51         return -1;
52     *strp = res;
53     return vsnprintf (res, len, fmt, ap);
54 #else
55     /* HACK: vsnprintf in the WinCE API behaves like
56      * the one in glibc 2.0 and doesn't return the number of characters
57      * it needed to copy the string.
58      * cf http://msdn.microsoft.com/en-us/library/1kt27hek.aspx
59      * and cf the man page of vsnprintf
60      *
61      Guess we need no more than 50 bytes. */
62     int n, size = 50;
63     char *res, *np;
64
65     if ((res = (char *) malloc (size)) == NULL)
66         return -1;
67
68     while (1)
69     {
70         n = vsnprintf (res, size, fmt, ap);
71
72         /* If that worked, return the string. */
73         if (n > -1 && n < size)
74         {
75             *strp = res;
76             return n;
77         }
78
79         /* Else try again with more space. */
80         size *= 2;  /* twice the old size */
81
82         if ((np = (char *) realloc (res, size)) == NULL)
83         {
84             free(res);
85             return -1;
86         }
87         else
88         {
89             res = np;
90         }
91
92     }
93 #endif /* UNDER_CE */
94 }
95 #endif
96
97 #ifndef HAVE_ASPRINTF
98 # include <stdio.h>
99 # include <stdarg.h>
100 static inline int asprintf (char **strp, const char *fmt, ...)
101 {
102     va_list ap;
103     int ret;
104     va_start (ap, fmt);
105     ret = vasprintf (strp, fmt, ap);
106     va_end (ap);
107     return ret;
108 }
109 #endif
110
111 #ifndef HAVE_STRNLEN
112 # include <string.h>
113 static inline size_t strnlen (const char *str, size_t max)
114 {
115     const char *end = (const char *) memchr (str, 0, max);
116     return end ? (size_t)(end - str) : max;
117 }
118 #endif
119
120 #ifndef HAVE_STRNDUP
121 # include <string.h>
122 # include <stdlib.h>
123 static inline char *strndup (const char *str, size_t max)
124 {
125     size_t len = strnlen (str, max);
126     char *res = (char *) malloc (len + 1);
127     if (res)
128     {
129         memcpy (res, str, len);
130         res[len] = '\0';
131     }
132     return res;
133 }
134 #endif
135
136 #ifndef HAVE_STRLCPY
137 # define strlcpy vlc_strlcpy
138 #endif
139
140 #ifndef HAVE_STRTOF
141 # define strtof( a, b ) ((float)strtod (a, b))
142 #endif
143
144 #ifndef HAVE_ATOF
145 # define atof( str ) (strtod ((str), (char **)NULL, 10))
146 #endif
147
148 #ifndef HAVE_STRTOLL
149 # define strtoll vlc_strtoll
150 #endif
151
152 #ifndef HAVE_STRSEP
153 static inline char *strsep( char **ppsz_string, const char *psz_delimiters )
154 {
155     char *psz_string = *ppsz_string;
156     if( !psz_string )
157         return NULL;
158
159     char *p = strpbrk( psz_string, psz_delimiters );
160     if( !p )
161     {
162         *ppsz_string = NULL;
163         return psz_string;
164     }
165     *p++ = '\0';
166
167     *ppsz_string = p;
168     return psz_string;
169 }
170 #endif
171
172 #ifndef HAVE_ATOLL
173 # define atoll( str ) (strtoll ((str), (char **)NULL, 10))
174 #endif
175
176 #ifndef HAVE_LLDIV
177 typedef struct {
178     long long quot; /* Quotient. */
179     long long rem;  /* Remainder. */
180 } lldiv_t;
181
182 static inline lldiv_t lldiv (long long numer, long long denom)
183 {
184     lldiv_t d = { .quot = numer / denom, .rem = numer % denom };
185     return d;
186 }
187 #endif
188
189 #ifndef HAVE_SCANDIR
190 # define scandir vlc_scandir
191 # define alphasort vlc_alphasort
192 #endif
193
194 #ifndef HAVE_GETENV
195 static inline char *getenv (const char *name)
196 {
197     (void)name;
198     return NULL;
199 }
200 #endif
201
202 #ifndef HAVE_STRCASECMP
203 # ifndef HAVE_STRICMP
204 #  include <ctype.h>
205 static inline int strcasecmp (const char *s1, const char *s2)
206 {
207     for (size_t i = 0;; i++)
208     {
209         int d = tolower (s1[i]) - tolower (s2[i]);
210         if (d || !s1[i]) return d;
211     }
212     return 0;
213 }
214 # else
215 #  define strcasecmp stricmp
216 # endif
217 #endif
218
219 #ifndef HAVE_STRNCASECMP
220 # ifndef HAVE_STRNICMP
221 #  include <ctype.h>
222 static inline int strncasecmp (const char *s1, const char *s2, size_t n)
223 {
224     for (size_t i = 0; i < n; i++)
225     {
226         int d = tolower (s1[i]) - tolower (s2[i]);
227         if (d || !s1[i]) return d;
228     }
229     return 0;
230 }
231 # else
232 #  define strncasecmp strnicmp
233 # endif
234 #endif
235
236 #ifndef HAVE_STRCASESTR
237 # ifndef HAVE_STRISTR
238 #  define strcasestr vlc_strcasestr
239 # else
240 #  define strcasestr stristr
241 # endif
242 #endif
243
244 #ifndef HAVE_LOCALTIME_R
245 /* If localtime_r() is not provided, we assume localtime() uses
246  * thread-specific storage. */
247 # include <time.h>
248 static inline struct tm *localtime_r (const time_t *timep, struct tm *result)
249 {
250     struct tm *s = localtime (timep);
251     if (s == NULL)
252         return NULL;
253
254     *result = *s;
255     return result;
256 }
257 static inline struct tm *gmtime_r (const time_t *timep, struct tm *result)
258 {
259     struct tm *s = gmtime (timep);
260     if (s == NULL)
261         return NULL;
262
263     *result = *s;
264     return result;
265 }
266 #endif
267
268 /* Alignment of critical static data structures */
269 #ifdef ATTRIBUTE_ALIGNED_MAX
270 #   define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
271 #else
272 #   define ATTR_ALIGN(align)
273 #endif
274
275 #ifndef HAVE_USELOCALE
276 typedef void *locale_t;
277 # define newlocale( a, b, c ) ((locale_t)0)
278 # define uselocale( a ) ((locale_t)0)
279 # define freelocale( a ) (void)0
280 #endif
281
282 #ifdef WIN32
283 # include <dirent.h>
284 # define opendir Use_utf8_opendir_or_vlc_wopendir_instead!
285 # define readdir Use_utf8_readdir_or_vlc_wreaddir_instead!
286 # define closedir vlc_wclosedir
287 #endif
288
289 /* libintl support */
290 #define _(str) vlc_gettext (str)
291
292 #if defined (ENABLE_NLS)
293 # include <libintl.h>
294 #endif
295
296 #define N_(str) gettext_noop (str)
297 #define gettext_noop(str) (str)
298
299 #ifdef UNDER_CE
300 static inline void rewind ( FILE *stream )
301 {
302     fseek(stream, 0L, SEEK_SET);
303     clearerr(stream);
304 }
305 #endif
306
307 #endif /* !LIBVLC_FIXUPS_H */