summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Coopersmith <alan.coopersmith@oracle.com>2014-02-18 22:18:00 -0800
committerAlan Coopersmith <alan.coopersmith@oracle.com>2014-02-25 23:22:44 -0800
commitf232f4ddb260dabdc4e99551a55015a536e2f827 (patch)
treeb4949a56d25786e62069c6a6f746f9e3a68746b3
parent92bbcc067e4c9d9883521c80cd298f6459ec4a54 (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.ac7
-rw-r--r--mkcomposecache.c66
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