[poppler] qt4/src/poppler-qiodeviceoutstream.cc: open_memstream is non-portable
Jonathan Kew
jonathan_kew at sil.org
Mon Jan 28 04:48:03 PST 2008
The document saving code in the Qt4 wrapper uses open_memstream(),
which is not available on all platforms. I would recommend using
vasprintf() instead, which I suspect is more widely supported, but
this is also a GNU extension and may not be available everywhere. So
a fallback approach using vsnprintf() is also needed.
Proposed changes below....
--
Jonathan
--
diff --git a/configure.ac b/configure.ac
index 99ffbda..602171a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,6 +17,9 @@ AC_PROG_CXX
AC_PROG_INSTALL
AC_CHECK_FUNC(gettimeofday, AC_DEFINE(HAVE_GETTIMEOFDAY, 1,
[Defines if gettimeofday is available on your system]))
AC_CHECK_FUNC(localtime_r, AC_DEFINE(HAVE_LOCALTIME_R, 1, [Defines
if localtime_r is available on your system]))
+AC_CHECK_FUNC(strndup, AC_DEFINE(HAVE_STRNDUP, 1, [Defines if
strndup is available on your system]))
+AC_CHECK_FUNC(vasprintf, AC_DEFINE(HAVE_VASPRINTF, 1, [Defines if
vasprintf is available on your system]))
+AC_CHECK_FUNC(open_memstream, AC_DEFINE(HAVE_OPEN_MEMSTREAM, 1,
[Defines if open_memstream is available on your system]))
dnl Enable these unconditionally.
AC_DEFINE([OPI_SUPPORT], [1], [Generate OPI comments in PS output.])
diff --git a/qt4/src/poppler-qiodeviceoutstream.cc b/qt4/src/poppler-
qiodeviceoutstream.cc
index 11fab97..6772c1d 100644
--- a/qt4/src/poppler-qiodeviceoutstream.cc
+++ b/qt4/src/poppler-qiodeviceoutstream.cc
@@ -57,13 +57,43 @@ void QIODeviceOutStream::put(char c)
void QIODeviceOutStream::printf(const char *format, ...)
{
va_list ap;
- va_start(ap, format);
char* buf = 0;
+#ifdef HAVE_VASPRINTF
+ int bufsize;
+ va_start(ap, format);
+ bufsize = vasprintf(&buf, format, ap);
+ va_end(ap);
+ if (bufsize < 0)
+ return; /* failed to allocate memory */
+#else
+#ifdef HAVE_OPEN_MEMSTREAM
size_t bufsize = 0;
FILE* stream = open_memstream(&buf, &bufsize);
+ va_start(ap, format);
vfprintf(stream, format, ap);
va_end(ap);
fclose(stream);
+#else /* do it the hard way - based on docs at linux.about.com */
+ size_t bufsize = 100;
+ if ((buf = (char*)malloc(bufsize)) == NULL)
+ return;
+ while (1) {
+ va_start(ap, format);
+ int n = vsnprintf(buf, bufsize, format, ap);
+ va_end(ap);
+ if (n > -1 && (size_t)n < bufsize) {
+ bufsize = n;
+ break;
+ }
+ if (n > -1)
+ bufsize = n + 1; /* allocate exactly what is needed */
+ else
+ bufsize *= 2; /* else try twice the old size */
+ if ((buf = (char*)realloc(buf, bufsize)) == NULL)
+ return; /* failure! */
+ }
+#endif
+#endif
m_device->write(buf, bufsize);
free(buf);
}
More information about the poppler
mailing list