diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | lib/asprintf.c | 64 | ||||
-rw-r--r-- | lib/os_internal.h | 21 |
3 files changed, 86 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index ff91be533..12aff6484 100644 --- a/configure.ac +++ b/configure.ac @@ -1876,7 +1876,7 @@ AC_CHECK_FUNCS([_vsnprintf _snprintf _stricmp _strnicmp vsscanf sigaction sigset AC_FUNC_FSEEKO AC_DEFINE(_GNU_SOURCE) AC_CHECK_HEADERS(assert.h byteswap.h malloc.h execinfo.h ucontext.h sys/mman.h sys/mixer.h libgen.h netdb.h dirent.h sys/times.h sys/ioctl.h sys/param.h) -AC_REPLACE_FUNCS(basename gettimeofday setenv strndup strpbrk strsep strtok_r timegm unsetenv) +AC_REPLACE_FUNCS(asprintf basename gettimeofday setenv strndup strpbrk strsep strtok_r timegm unsetenv) AC_LIBSOURCE(hstrerror.c) AC_LINK_IFELSE([#include <netdb.h> diff --git a/lib/asprintf.c b/lib/asprintf.c new file mode 100644 index 000000000..aecfa9141 --- /dev/null +++ b/lib/asprintf.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * xine is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + */ + +#include "config.h" +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> + +int _xine_private_vasprintf (char **buffer, const char *format, va_list ap) +{ + char *buf = NULL; + int size = 128; + + for (;;) + { + int ret; + va_list cp; + char *newbuf = realloc (buf, size *= 2); + if (!newbuf) + { + free (buf); + return -1; + } + buf = newbuf; + + va_copy (cp, ap); + ret = vsnprintf (buf, size, format, cp); + va_end (cp); + + if (ret >= 0 && ret < size) + { + *buffer = realloc (buf, ret + 1); + return ret; + } + } +} + +int _xine_private_asprintf (char **buffer, const char *format, ...) +{ + int ret; + va_list ap; + va_start (ap, format); + ret = _xine_private_vasprintf (buffer, format, ap); + va_end (ap); + return ret; +} diff --git a/lib/os_internal.h b/lib/os_internal.h index 24ec8fe73..9f6d2610a 100644 --- a/lib/os_internal.h +++ b/lib/os_internal.h @@ -2,6 +2,7 @@ #define _XINE_OS_INTERNAL_H #include <stddef.h> +#include <stdarg.h> #ifdef HOST_OS_DARWIN /* Darwin (Mac OS X) needs __STDC_LIBRARY_SUPPORTED__ for SCNx64 and @@ -98,6 +99,26 @@ time_t _xine_private_timegm(struct tm *tm); void _xine_private_unsetenv(const char *name); #endif +/* replacement of asprintf & vasprintf */ +#ifndef HAVE_ASPRINTF +#ifdef __GNUC__ + #define asprintf(STRINGPP, FORMAT, ARGS...) _xine_private_asprintf((STRINGPP), FORMAT, ##ARGS) +#elif defined (_MSC_VER) + #define asprintf(STRINGPP, FORMATARGS) _xine_private_asprintf((STRINGPP), FORMATARGS) +#else + #define asprintf(STRINGPP, FORMAT, ...) _xine_private_asprintf((STRINGPP), FORMAT, __VA_ARGS__) +#endif +#define vasprintf(STRINGPP, FORMAT, VA_ARG) _xine_private_vasprintf((STRINGPP), (FORMAT), (VA_ARG)) +int _xine_private_asprintf(char **string, const char *format, ...) __attribute__ ((format (printf, 2, 3))); +int _xine_private_vasprintf(char **string, const char *format, va_list ap) __attribute__ ((format (printf, 2, 0))); +#endif + +/* replacement of strndup */ +#ifndef HAVE_STRNDUP +#define strndup(S, N) _xine_private_strndup((S), (N)) +char *_xine_private_strndup(const char *s, size_t n); +#endif + /* handle non-standard function names */ #if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF) # define snprintf _snprintf |