AC_CHECK_HEADERS(getopt.h)
fi
-mutt_cv_snprintf=no
SNPRINTFOBJS=""
-AC_CHECK_FUNCS(snprintf, , [mutt_cv_snprintf=yes])
-AC_CHECK_FUNCS(vsnprintf, , [mutt_cv_snprintf=yes])
-if test $mutt_cv_snprintf = yes; then
+AC_CHECK_FUNC(snprintf, [mutt_cv_func_snprintf=yes], [mutt_cv_func_snprintf=no])
+AC_CHECK_FUNC(vsnprintf, [mutt_cv_func_vsnprintf=yes], [mutt_cv_func_vsnprintf=no])
+if test $mutt_cv_func_snprintf = yes; then
+AC_CACHE_CHECK([whether your system's snprintf is C99 compliant],
+ [mutt_cv_c99_snprintf],
+ AC_TRY_RUN([
+#include <stdio.h>
+int main()
+{
+changequote(, )dnl
+ char buf[8];
+ int len = snprintf(buf, 4, "1234567");
+ return (len != 7 || buf[3] != '\0');
+changequote([, ])dnl
+}
+ ], mutt_cv_c99_snprintf=yes, mutt_cv_c99_snprintf=no, mutt_cv_c99_snprintf=no))
+else
+ mutt_cv_c99_snprintf=no
+fi
+if test $mutt_cv_func_vsnprintf = yes; then
+AC_CACHE_CHECK([whether your system's vsnprintf is C99 compliant],
+ [mutt_cv_c99_vsnprintf],
+ AC_TRY_RUN([
+#include <stdarg.h>
+#include <stdio.h>
+int foo(const char *fmt, ...)
+{
+changequote(, )dnl
+ char buf[8];
+ int len;
+ va_list ap;
+ va_start(ap, fmt);
+ len = vsnprintf(buf, 4, fmt, ap);
+ va_end(ap);
+ return (len != 7 || buf[3] != '\0');
+changequote([, ])dnl
+}
+
+int main()
+{
+ return foo("%s", "1234567");
+}
+ ], mutt_cv_c99_vsnprintf=yes, mutt_cv_c99_vsnprintf=no, mutt_cv_c99_vsnprintf=no))
+else
+ mutt_cv_c99_vsnprintf=no
+fi
+if test $mutt_cv_c99_snprintf = yes; then
+ AC_DEFINE(HAVE_SNPRINTF, 1, [ Define to 1 if you have a C99 compliant snprintf function. ])
+fi
+if test $mutt_cv_c99_vsnprintf = yes; then
+ AC_DEFINE(HAVE_VSNPRINTF, 1, [ Define to 1 if you have a C99 compliant vsnprintf function. ])
+fi
+if test $mutt_cv_c99_snprintf = no -o $mutt_cv_c99_vsnprintf = no; then
AC_LIBOBJ(snprintf)
fi
* missing. Some systems only have snprintf() but not vsnprintf(), so
* the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
*
+ * Holger Weiss <holger@zedat.fu-berlin.de> 07/23/06 for mutt 1.5.13
+ * A C99 compliant [v]snprintf() returns the number of characters that
+ * would have been written to a sufficiently sized buffer (excluding
+ * the '\0'). Mutt now relies on this behaviour, but the original
+ * code simply returned the length of the resulting output string, so
+ * that's been fixed.
+ *
**************************************************************/
#if HAVE_CONFIG_H
/*int snprintf (char *str, size_t count, const char *fmt, ...);*/
/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
-static void dopr (char *buffer, size_t maxlen, const char *format,
+static int dopr (char *buffer, size_t maxlen, const char *format,
va_list args);
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
#undef MAX
#define MAX(p,q) ((p >= q) ? p : q)
-static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
+static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
{
char ch;
long value;
while (state != DP_S_DONE)
{
- if ((ch == '\0') || (currlen >= maxlen))
+ if (ch == '\0')
state = DP_S_DONE;
switch(state)
break;
case 's':
strvalue = va_arg (args, char *);
- if (max < 0)
- max = maxlen; /* ie, no max */
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
break;
case 'p':
buffer[currlen] = '\0';
else
buffer[maxlen - 1] = '\0';
+
+ return (int)currlen;
}
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justify */
- while ((padlen > 0) && (cnt < max))
+ while ((padlen > 0) && (max == -1 || cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
++cnt;
}
- while (*value && (cnt < max))
+ while (*value && (max == -1 || cnt < max))
{
dopr_outch (buffer, currlen, maxlen, *value++);
++cnt;
}
- while ((padlen < 0) && (cnt < max))
+ while ((padlen < 0) && (max == -1 || cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
{
if (*currlen < maxlen)
- buffer[(*currlen)++] = c;
+ buffer[*currlen] = c;
+ (*currlen)++;
}
#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
str[0] = 0;
- dopr(str, count, fmt, args);
- return(strlen(str));
+ return(dopr(str, count, fmt, args));
}
#endif /* !HAVE_VSNPRINTF */
size_t count;
char *fmt;
#endif
+ int len;
VA_LOCAL_DECL;
VA_START (fmt);
VA_SHIFT (str, char *);
VA_SHIFT (count, size_t );
VA_SHIFT (fmt, char *);
- (void) vsnprintf(str, count, fmt, ap);
+ len = vsnprintf(str, count, fmt, ap);
VA_END;
- return(strlen(str));
+ return(len);
}
#ifdef TEST_SNPRINTF