Added int_vasprintf from Recai Oktas

SVN revision: 988
This commit is contained in:
2004-07-28 12:52:30 +00:00
parent c8df845f20
commit b6414381b9
+103 -20
View File
@@ -6,6 +6,9 @@
Contents: Web server program for Electronic Logbook ELOG
$Log$
Revision 1.409 2004/07/28 12:52:30 midas
Added int_vasprintf from Recai Oktas
Revision 1.408 2004/07/28 12:00:38 midas
Fixed bug with invalid sizeof(list)
@@ -733,7 +736,104 @@ char *stristr(const char *str, const char *pattern)
/*----------------------- Message handling -------------------------*/
#ifdef OS_UNIX
/* Have vasprintf? (seems that only libc6 based Linux has this) */
#ifdef __linux__
# define HAVE_VASPRINTF
#endif
#ifndef HAVE_VASPRINTF
/* vasprintf implementation taken (and adapted) from GNU libiberty */
static int int_vasprintf(char **result, const char *format, va_list args)
{
const char *p = format;
/* Add one to make sure that it is never zero, which might cause malloc
to return NULL. */
int total_width = strlen(format) + 1;
va_list ap;
#ifdef va_copy
va_copy(ap, args);
#else
memcpy(&ap, &args, sizeof(va_list));
#endif
while (*p != '\0') {
if (*p++ == '%') {
while (strchr("-+ #0", *p))
++p;
if (*p == '*') {
++p;
total_width += abs(va_arg(ap, int));
} else
total_width += strtoul(p, (char **) &p, 10);
if (*p == '.') {
++p;
if (*p == '*') {
++p;
total_width += abs(va_arg(ap, int));
} else
total_width += strtoul(p, (char **) &p, 10);
}
while (strchr("hlL", *p))
++p;
/*
* Should be big enough for any format specifier
* except %s and floats.
*/
total_width += 30;
switch (*p) {
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
case 'c':
(void) va_arg(ap, int);
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
(void) va_arg(ap, double);
/*
* Since an ieee double can have an exponent of 307, we'll
* make the buffer wide enough to cover the gross case.
*/
total_width += 307;
break;
case 's':
total_width += strlen(va_arg(ap, char *));
break;
case 'p':
case 'n':
(void) va_arg(ap, char *);
break;
}
p++;
}
}
#ifdef va_copy
va_end(ap);
#endif
*result = (char *) malloc(total_width);
if (*result != NULL)
return vsprintf(*result, format, args);
else
return -1;
}
#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
int vasprintf(char **result, const char *format, _BSD_VA_LIST_ args)
#else
int vasprintf(char **result, const char *format, va_list args)
#endif
{
return int_vasprintf(result, format, args);
}
#endif /* ! HAVE_VASPRINTF */
/* Safe replacement for vasprintf (adapted code from Samba) */
int xvasprintf(char **ptr, const char *format, va_list ap)
@@ -776,23 +876,6 @@ void eprintf(const char *format, ...)
free(msg);
}
#else /* OS_UNIX */
/* Driver for printf_handler, drop-in replacement for printf */
void eprintf(const char *format, ...)
{
va_list ap;
char msg[10000];
va_start(ap, format);
vsprintf(msg, format, ap);
va_end(ap);
(*printf_handler) (msg);
}
#endif
/* Driver for fputs_handler, drop-in replacement for fputs(buf, fd) */
void efputs(const char *buf)
{
@@ -850,7 +933,7 @@ void fputs_stderr(const char *buf)
fputs(buf, stderr);
}
/* Redirect all messages handled with eprintf/efputs
/* Redirect all messages handled with eprintf/efputs
to syslog (Unix) or event log (Windows) */
void redirect_to_syslog(void)
{
@@ -19984,7 +20067,7 @@ int read_password(char *pwd, int size)
} while (1);
str[n] = 0;
strlcpy(pwd, str, size);
return n;
}