summary refs log tree commit diff
diff options
context:
space:
mode:
authorClint Adams <clint@users.sourceforge.net>2000-09-16 18:57:45 +0000
committerClint Adams <clint@users.sourceforge.net>2000-09-16 18:57:45 +0000
commit2742cb14ce02354f6c9a2a2a61f793f9a1932924 (patch)
tree7c098832770e48dcc5d4c2cb27c32ed464fb3720
parent73e23c7999196642fcf3448013b4e37b03044e8c (diff)
downloadzsh-2742cb14ce02354f6c9a2a2a61f793f9a1932924.tar.gz
zsh-2742cb14ce02354f6c9a2a2a61f793f9a1932924.tar.xz
zsh-2742cb14ce02354f6c9a2a2a61f793f9a1932924.zip
12814: zasprintf
-rw-r--r--ChangeLog6
-rw-r--r--Src/compat.c74
-rw-r--r--Src/init.c8
-rw-r--r--Src/system.h20
-rw-r--r--configure.in3
5 files changed, 108 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 435540f2e..102dd5888 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2000-09-16  Clint Adams  <schizo@debian.org>
+
+	* 12814: configure.in, Src/compat.c, Src/init.c, Src/system.h:
+	implement zasprintf and use it in lieu of sprintf with a
+	static buffer in sourcehome().
+
 2000-09-15  Bart Schaefer  <schaefer@zsh.org>
 
 	* unposted: Doc/Zsh/contrib.yo: Missing hunk from 12765 (replace
diff --git a/Src/compat.c b/Src/compat.c
index 8cfb8a3a5..0c7009b5f 100644
--- a/Src/compat.c
+++ b/Src/compat.c
@@ -407,6 +407,80 @@ zchdir(char *dir)
 #endif
 }
 
+#ifndef HAVE_ASPRINTF
+/**/
+# ifndef USE_VARARGS
+/**/
+mod_export int
+zasprintf(char **strp, const char *format, int arg1, int arg2)
+{
+    char *buf;
+    
+    buf = (char *)zalloc(PATH_MAX);
+
+    snprintf(buf, PATH_MAX, format, arg1, arg2);
+    *strp = buf;
+    return strlen(buf);
+}
+
+/**/
+# else
+
+/**/
+#  ifdef PREFER_STDARG
+
+/**/
+mod_export int
+zasprintf(char **strp, const char *format, ...)
+{
+
+/**/
+#  else
+
+/**/
+#   if __GNUC__ > 1
+/* Doing this the "right way" will effect a broken compat.epro file.      *
+ * This kludge should work with gcc2 until a better solution is available */
+
+/**/
+mod_export int
+zasprintf(char **strp, const char *format, __builtin_va_alist_t __builtin_va_alist, __va_ellipsis)
+{
+	
+/**/
+#    else
+#    error varargs prototyping kludge failed
+/**/
+#    endif
+
+/**/
+#  endif
+    va_list arg;
+
+    char *buf;
+    
+    buf = (char *)zalloc(PATH_MAX);
+
+# ifdef PREFER_STDARG
+    va_start(arg, format);
+# else
+    va_start(arg);
+# endif
+
+#ifdef HAVE_VSNPRINTF
+    vsnprintf(buf, PATH_MAX, format, arg);
+#else
+#error You have varargs but no vsnprintf
+#endif
+    va_end (arg);
+    
+    *strp = buf;
+    return strlen(buf);
+}
+/**/
+# endif
+#endif
+
 /*
  * How to print out a 64 bit integer.  This isn't needed (1) if longs
  * are 64 bit, since ordinary %ld will work (2) if we couldn't find a
diff --git a/Src/init.c b/Src/init.c
index e3e8f734e..0c82e47ef 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -1020,18 +1020,22 @@ source(char *s)
 void
 sourcehome(char *s)
 {
-    char buf[PATH_MAX];
+    char *buf;
     char *h;
 
     if (emulation == EMULATE_SH || emulation == EMULATE_KSH ||
 	!(h = getsparam("ZDOTDIR")))
 	h = home;
+/* Let source() complain if it's too long */
+#if 0
     if (strlen(h) + strlen(s) + 1 >= PATH_MAX) {
 	zerr("path too long: %s", s, 0);
 	return;
     }
-    sprintf(buf, "%s/%s", h, s);
+#endif
+    zasprintf(&buf, "%s/%s", h, s);
     source(buf);
+    zsfree(buf);
 }
 
 /**/
diff --git a/Src/system.h b/Src/system.h
index 93e82a728..fc85efdb4 100644
--- a/Src/system.h
+++ b/Src/system.h
@@ -227,6 +227,26 @@ struct timezone {
 # define zopenmax() ((long) OPEN_MAX)
 #endif
 
+#if defined (__STDC__) && defined (HAVE_STDARG_H)
+# define PREFER_STDARG
+# define USE_VARARGS
+# include <stdarg.h>
+#else
+# ifdef HAVE_VARARGS_H
+#  define PREFER_VARARGS
+#  define USE_VARARGS
+#  include <varargs.h>
+# endif
+#endif
+
+#ifdef HAVE_ASPRINTF
+# ifdef __GNUC__
+# define zasprintf(X,F,A...) asprintf(X,F, ## A)
+# else
+# define zasprintf asprintf
+# endif
+#endif
+
 #ifdef HAVE_FCNTL_H
 # include <fcntl.h>
 #else
diff --git a/configure.in b/configure.in
index fa268707f..09592640b 100644
--- a/configure.in
+++ b/configure.in
@@ -451,7 +451,7 @@ AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \
 		 limits.h fcntl.h libc.h sys/utsname.h sys/resource.h \
 		 locale.h errno.h stdlib.h unistd.h sys/capability.h \
 		 utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h \
-		 linux/tasks.h netinet/in_systm.h)
+		 linux/tasks.h netinet/in_systm.h stdarg.h varargs.h)
 if test $dynamic = yes; then
   AC_CHECK_HEADERS(dlfcn.h)
   AC_CHECK_HEADERS(dl.h)
@@ -860,6 +860,7 @@ AC_CHECK_FUNCS(strftime difftime gettimeofday \
 	       initgroups nis_list \
 	       setuid seteuid setreuid setresuid setsid \
 	       memcpy memmove strstr strerror \
+	       snprintf vsnprintf asprintf \
 	       cap_get_proc \
 	       getrlimit \
 	       setlocale \