#include "config.h"
#include "ansidecl.h"
#include <stdarg.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "libiberty.h"
int
vsnprintf (char *s, size_t n, const char *format, va_list ap)
{
char *buf = 0;
int result = vasprintf (&buf, format, ap);
if (!buf)
return -1;
if (result < 0)
{
free (buf);
return -1;
}
result = strlen (buf);
if (n > 0)
{
if ((long) n > result)
memcpy (s, buf, result+1);
else
{
memcpy (s, buf, n-1);
s[n - 1] = 0;
}
}
free (buf);
return result;
}
#ifdef TEST
#define CLEAR(BUF) do { memset ((BUF), 'X', sizeof (BUF)); (BUF)[14] = '\0'; } while (0)
#define VERIFY(P) do { if (!(P)) abort(); } while (0)
static int ATTRIBUTE_PRINTF_3
checkit (char *s, size_t n, const char *format, ...)
{
int result;
VA_OPEN (ap, format);
VA_FIXEDARG (ap, char *, s);
VA_FIXEDARG (ap, size_t, n);
VA_FIXEDARG (ap, const char *, format);
result = vsnprintf (s, n, format, ap);
VA_CLOSE (ap);
return result;
}
extern int main (void);
int
main (void)
{
char buf[128];
int status;
CLEAR (buf);
status = checkit (buf, 10, "%s:%d", "foobar", 9);
VERIFY (status==8 && memcmp (buf, "foobar:9\0XXXXX\0", 15) == 0);
CLEAR (buf);
status = checkit (buf, 9, "%s:%d", "foobar", 9);
VERIFY (status==8 && memcmp (buf, "foobar:9\0XXXXX\0", 15) == 0);
CLEAR (buf);
status = checkit (buf, 8, "%s:%d", "foobar", 9);
VERIFY (status==8 && memcmp (buf, "foobar:\0XXXXXX\0", 15) == 0);
CLEAR (buf);
status = checkit (buf, 7, "%s:%d", "foobar", 9);
VERIFY (status==8 && memcmp (buf, "foobar\0XXXXXXX\0", 15) == 0);
CLEAR (buf);
status = checkit (buf, 6, "%s:%d", "foobar", 9);
VERIFY (status==8 && memcmp (buf, "fooba\0XXXXXXXX\0", 15) == 0);
CLEAR (buf);
status = checkit (buf, 2, "%s:%d", "foobar", 9);
VERIFY (status==8 && memcmp (buf, "f\0XXXXXXXXXXXX\0", 15) == 0);
CLEAR (buf);
status = checkit (buf, 1, "%s:%d", "foobar", 9);
VERIFY (status==8 && memcmp (buf, "\0XXXXXXXXXXXXX\0", 15) == 0);
CLEAR (buf);
status = checkit (buf, 0, "%s:%d", "foobar", 9);
VERIFY (status==8 && memcmp (buf, "XXXXXXXXXXXXXX\0", 15) == 0);
return 0;
}
#endif