diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2014-02-18 22:18:00 -0800 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2014-02-25 23:22:44 -0800 |
commit | f232f4ddb260dabdc4e99551a55015a536e2f827 (patch) | |
tree | b4949a56d25786e62069c6a6f746f9e3a68746b3 | |
parent | 92bbcc067e4c9d9883521c80cd298f6459ec4a54 (diff) |
Replace manual calculations of memory allocations with asprintf calls
Includes fallback asprintf() for platforms that don't have it yet.
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | mkcomposecache.c | 66 |
2 files changed, 61 insertions, 12 deletions
diff --git a/configure.ac b/configure.ac index 727f100..aff0a49 100644 --- a/configure.ac +++ b/configure.ac @@ -8,6 +8,11 @@ AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE +# Set common system defines for POSIX extensions, such as _GNU_SOURCE +# Must be called before any macros that run the compiler (like those in +# XORG_DEFAULT_OPTIONS) to avoid autoconf errors. +AC_USE_SYSTEM_EXTENSIONS + # Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS m4_ifndef([XORG_MACROS_VERSION], [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) @@ -18,7 +23,7 @@ PKG_CHECK_MODULES(XLIB, x11) AC_CHECK_HEADERS([stdio.h stdlib.h string.h unistd.h locale.h], , [AC_MSG_FAILURE("cannot find essential header")]) AC_CHECK_FUNCS([setlocale], , [AC_MSG_FAILURE("cannot find essential function")]) -AC_CHECK_FUNCS([unsetenv]) +AC_CHECK_FUNCS([unsetenv asprintf]) AC_CONFIG_FILES([ Makefile diff --git a/mkcomposecache.c b/mkcomposecache.c index c65951c..3b94e77 100644 --- a/mkcomposecache.c +++ b/mkcomposecache.c @@ -27,11 +27,55 @@ #include <unistd.h> #include <locale.h> +#ifndef HAVE_ASPRINTF +#include <stdarg.h> + +/* sprintf variant found in newer libc's which allocates string to print to */ +static int _X_ATTRIBUTE_PRINTF(2,3) +asprintf(char ** ret, const char *format, ...) +{ + char buf[256]; + int len; + va_list ap; + + va_start(ap, format); + len = vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + if (len < 0) + return -1; + + if (len < sizeof(buf)) + { + *ret = strdup(buf); + } + else + { + *ret = malloc(len + 1); /* vsnprintf doesn't count trailing '\0' */ + if (*ret != NULL) + { + va_start(ap, format); + len = vsnprintf(*ret, len + 1, format, ap); + va_end(ap); + if (len < 0) { + free(*ret); + *ret = NULL; + } + } + } + + if (*ret == NULL) + return -1; + + return len; +} +#endif /* HAVE_ASPRINTF */ + int main (int argc, char *argv[]) { Display *disp; XIM im; char *src, *dest; - int len; + int ret; if (argc != 4 && argc != 5) { fprintf (stderr, "Usage: %s <Locale> <ComposeFile> <CacheDir> [<InternalName>]\n", argv[0]); @@ -53,20 +97,20 @@ int main (int argc, char *argv[]) { return 1; } - src = malloc (strlen (argv[2]) + 14); - len = strlen (argv[3]) + 15; - if (argc == 5) - len += strlen (argv[4]) + 1; - dest = malloc (len); - if (! src || ! dest) { - perror ("* malloc"); + if (asprintf (&src, "XCOMPOSEFILE=%s", argv[2]) == -1) { + perror ("* asprintf"); return 1; } - sprintf (src, "XCOMPOSEFILE=%s", argv[2]); + if (argc == 4) - sprintf (dest, "XCOMPOSECACHE=%s", argv[3]); + ret = asprintf (&dest, "XCOMPOSECACHE=%s", argv[3]); else - sprintf (dest, "XCOMPOSECACHE=%s=%s", argv[3], argv[4]); + ret = asprintf (&dest, "XCOMPOSECACHE=%s=%s", argv[3], argv[4]); + if (ret == -1) { + perror ("* asprintf"); + return 1; + } + putenv (src); putenv (dest); #if HAVE_UNSETENV |