Spróbowałem skompilować pod MSVC libgadu z wersją mojej łaty wysłanej
tutaj i okazało się, że z jakiegoś powodu MSVC zaczyna traktować
va_copy jako nazwę funkcji (mimo że definicja preprocesora jest moim
zdaniem poprawna) i oczywiście nie udaje mu się zlinkować biblioteki.
Niezbyt chce mi się dochodzić powodu, więc załączam alternatywną
wersję łaty. I czekam na opinie, bo wypadałoby na jakieś rozwiązanie
wreszcie się zdecydować :).

Pozdrawiam,
Bartosz
From 66d9395294ac894512d77029087a2745e9c7de34 Mon Sep 17 00:00:00 2001
From: Bartosz Brachaczek <b.brachac...@gmail.com>
Date: Sat, 29 Oct 2011 01:40:33 +0200
Subject: [PATCH 1/2] Popraw gg_vsaprintf() dla nie-C99

---
 src/common.c |   66 ++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 39 insertions(+), 27 deletions(-)

diff --git a/src/common.c b/src/common.c
index 700a261..978ab99 100644
--- a/src/common.c
+++ b/src/common.c
@@ -56,59 +56,71 @@
  */
 char *gg_vsaprintf(const char *format, va_list ap)
 {
-	int size = 0;
+	int size;
 	char *buf = NULL;
-
-#ifdef GG_CONFIG_HAVE_VA_COPY
-	va_list aq;
-
-	va_copy(aq, ap);
-#else
-#  ifdef GG_CONFIG_HAVE___VA_COPY
+#if defined(GG_CONFIG_HAVE_VA_COPY) || defined(GG_CONFIG_HAVE___VA_COPY)
 	va_list aq;
-
-	__va_copy(aq, ap);
-#  endif
 #endif
 
 #ifndef GG_CONFIG_HAVE_C99_VSNPRINTF
 	{
-		int res;
+		int res = 0;
 		char *tmp;
 
 		size = 128;
 		do {
-			size *= 2;
+			if (res > size) {
+				/* Jednak zachowanie zgodne z C99. */
+				size = res + 1;
+			} else {
+				size *= 2;
+			}
+
 			if (!(tmp = realloc(buf, size))) {
 				free(buf);
 				return NULL;
 			}
+
 			buf = tmp;
+
+#  if defined(GG_CONFIG_HAVE_VA_COPY) || defined(GG_CONFIG_HAVE___VA_COPY)
+#    ifdef GG_CONFIG_HAVE_VA_COPY
+			va_copy(aq, ap);
+#    else
+			__va_copy(aq, ap);
+#    endif
+			res = vsnprintf(buf, size, format, aq);
+			va_end(aq);
+#  else
 			res = vsnprintf(buf, size, format, ap);
-		} while (res == size - 1 || res == -1);
+#  endif
+		} while (res >= size || res < 0);
 	}
 #else
 	{
 		char tmp[2];
 
+#  if defined(GG_CONFIG_HAVE_VA_COPY)
+		va_copy(aq, ap);
+#  elif defined(GG_CONFIG_HAVE___VA_COPY)
+		__va_copy(aq, ap);
+#  endif
+
 		/* libce Solarisa przy buforze NULL zawsze zwracają -1, więc
 		 * musimy podać coś istniejącego jako cel printf()owania. */
-		size = vsnprintf(tmp, sizeof(tmp), format, ap);
-		if (!(buf = malloc(size + 1)))
+		size = vsnprintf(tmp, sizeof(tmp), format, ap) + 1;
+		if (!(buf = malloc(size))) {
+#  if defined(GG_CONFIG_HAVE_VA_COPY) || defined(GG_CONFIG_HAVE___VA_COPY)
+			va_end(aq);
+#  endif
 			return NULL;
-	}
-#endif
+		}
 
-#ifdef GG_CONFIG_HAVE_VA_COPY
-	vsnprintf(buf, size + 1, format, aq);
-	va_end(aq);
-#else
-#  ifdef GG_CONFIG_HAVE___VA_COPY
-	vsnprintf(buf, size + 1, format, aq);
-	va_end(aq);
-#  else
-	vsnprintf(buf, size + 1, format, ap);
+		vsnprintf(buf, size, format, aq);
+#  if defined(GG_CONFIG_HAVE_VA_COPY) || defined(GG_CONFIG_HAVE___VA_COPY)
+		va_end(aq);
 #  endif
+	}
 #endif
 
 	return buf;
-- 
1.7.7.1

From 22a252b9e24d8ace3e4982b7a214015454e9f0e5 Mon Sep 17 00:00:00 2001
From: Bartosz Brachaczek <b.brachac...@gmail.com>
Date: Fri, 28 Oct 2011 23:41:01 +0200
Subject: [PATCH 2/2] =?UTF-8?q?Dodaj=20obs=C5=82ug=C4=99=20=5Fvscprintf()=20?=
 =?UTF-8?q?dost=C4=99pnego=20w=20MSVC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 include/libgadu.h.in |    4 ++++
 src/common.c         |   26 +++++++++++++++-----------
 2 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/include/libgadu.h.in b/include/libgadu.h.in
index 5ea6c07..e2d7bfb 100644
--- a/include/libgadu.h.in
+++ b/include/libgadu.h.in
@@ -68,6 +68,10 @@ extern "C" {
 /* Defined if this machine has C99-compiliant vsnprintf(). */
 #undef GG_CONFIG_HAVE_C99_VSNPRINTF
 
+#ifdef _MSC_VER
+#define GG_CONFIG_HAVE__VSCPRINTF
+#endif
+
 /* Defined if this machine has va_copy(). */
 #undef GG_CONFIG_HAVE_VA_COPY
 
diff --git a/src/common.c b/src/common.c
index 978ab99..5fc656b 100644
--- a/src/common.c
+++ b/src/common.c
@@ -62,7 +62,7 @@ char *gg_vsaprintf(const char *format, va_list ap)
 	va_list aq;
 #endif
 
-#ifndef GG_CONFIG_HAVE_C99_VSNPRINTF
+#if !defined(GG_CONFIG_HAVE_C99_VSNPRINTF) && !defined(GG_CONFIG_HAVE__VSCPRINTF)
 	{
 		int res = 0;
 		char *tmp;
@@ -97,30 +97,34 @@ char *gg_vsaprintf(const char *format, va_list ap)
 		} while (res >= size || res < 0);
 	}
 #else
-	{
-		char tmp[2];
-
 #  if defined(GG_CONFIG_HAVE_VA_COPY)
 		va_copy(aq, ap);
 #  elif defined(GG_CONFIG_HAVE___VA_COPY)
 		__va_copy(aq, ap);
 #  endif
 
+#  if defined(GG_CONFIG_HAVE__VSCPRINTF)
+	size = _vscprintf(format, aq) + 1;
+#  else
+	{
+		char tmp[2];
+
 		/* libce Solarisa przy buforze NULL zawsze zwracają -1, więc
 		 * musimy podać coś istniejącego jako cel printf()owania. */
 		size = vsnprintf(tmp, sizeof(tmp), format, ap) + 1;
-		if (!(buf = malloc(size))) {
-#  if defined(GG_CONFIG_HAVE_VA_COPY) || defined(GG_CONFIG_HAVE___VA_COPY)
-			va_end(aq);
+	}
 #  endif
-			return NULL;
-		}
-
-		vsnprintf(buf, size, format, aq);
+	if (!(buf = malloc(size))) {
 #  if defined(GG_CONFIG_HAVE_VA_COPY) || defined(GG_CONFIG_HAVE___VA_COPY)
 		va_end(aq);
 #  endif
+		return NULL;
 	}
+
+	vsnprintf(buf, size, format, aq);
+#  if defined(GG_CONFIG_HAVE_VA_COPY) || defined(GG_CONFIG_HAVE___VA_COPY)
+	va_end(aq);
+#  endif
 #endif
 
 	return buf;
-- 
1.7.7.1

_______________________________________________
libgadu-devel mailing list
libgadu-devel@lists.ziew.org
http://lists.ziew.org/mailman/listinfo/libgadu-devel

Reply via email to