2004-04-22 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / gpgme / vasprintf.c
index 9e39966..77113a3 100644 (file)
@@ -26,6 +26,19 @@ Boston, MA 02111-1307, USA.  */
 #include <stdlib.h>
 #include <stdarg.h>
 
+
+#ifndef va_copy /* According to POSIX, va_copy is a macro. */
+#if defined (__GNUC__) && defined (__PPC__) \
+     && (defined (_CALL_SYSV) || defined (_WIN32))
+#define va_copy(d, s) (*(d) = *(s))
+#elif defined (MUST_COPY_VA_BYVAL)
+#define va_copy(d, s) ((d) = (s))
+#else 
+#define va_copy(d, s) memcpy ((d), (s), sizeof (va_list))
+#endif 
+#endif 
+
+
 #ifdef TEST
 int global_total_width;
 #endif
@@ -44,8 +57,7 @@ int_vasprintf (result, format, args)
   int total_width = strlen (format) + 1;
   va_list ap;
 
-  /* FIXME: use va_copy() */
-  memcpy (&ap, args, sizeof (va_list));
+  va_copy (ap, *args);
 
   while (*p != '\0')
     {
@@ -97,7 +109,13 @@ int_vasprintf (result, format, args)
              total_width += 307;
              break;
            case 's':
-             total_width += strlen (va_arg (ap, char *));
+              {
+                char *tmp = va_arg (ap, char *);
+                if (tmp)
+                  total_width += strlen (tmp);
+                else /* in case the vsprintf does prints a text */
+                  total_width += 25; /* e.g. "(null pointer reference)" */
+              }
              break;
            case 'p':
            case 'n':