mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
add an implentation of asprintf() for xen
Also needed to fix vsnprintf() et al so it can be called with a NULL buf (and zero size, of course). Signed-off-by: Paul Durrant <paul.durrant@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
a0731ccab2
commit
780e918a2e
3 files changed
+91
-29
No files matched your search
+86
-29
@@ -192,45 +192,45 @@ static char *number(
|
||||
size -= precision;
|
||||
if (!(type&(ZEROPAD+LEFT))) {
|
||||
while(size-->0) {
|
||||
if (buf <= end)
|
||||
if (buf < end)
|
||||
*buf = ' ';
|
||||
++buf;
|
||||
}
|
||||
}
|
||||
if (sign) {
|
||||
if (buf <= end)
|
||||
if (buf < end)
|
||||
*buf = sign;
|
||||
++buf;
|
||||
}
|
||||
if (type & SPECIAL) {
|
||||
if (buf <= end)
|
||||
if (buf < end)
|
||||
*buf = '0';
|
||||
++buf;
|
||||
if (base == 16) {
|
||||
if (buf <= end)
|
||||
if (buf < end)
|
||||
*buf = digits[33];
|
||||
++buf;
|
||||
}
|
||||
}
|
||||
if (!(type & LEFT)) {
|
||||
while (size-- > 0) {
|
||||
if (buf <= end)
|
||||
if (buf < end)
|
||||
*buf = c;
|
||||
++buf;
|
||||
}
|
||||
}
|
||||
while (i < precision--) {
|
||||
if (buf <= end)
|
||||
if (buf < end)
|
||||
*buf = '0';
|
||||
++buf;
|
||||
}
|
||||
while (i-- > 0) {
|
||||
if (buf <= end)
|
||||
if (buf < end)
|
||||
*buf = tmp[i];
|
||||
++buf;
|
||||
}
|
||||
while (size-- > 0) {
|
||||
if (buf <= end)
|
||||
if (buf < end)
|
||||
*buf = ' ';
|
||||
++buf;
|
||||
}
|
||||
@@ -244,18 +244,18 @@ static char *string(char *str, char *end, const char *s,
|
||||
|
||||
if (!(flags & LEFT)) {
|
||||
while (len < field_width--) {
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = *s;
|
||||
++str; ++s;
|
||||
}
|
||||
while (len < field_width--) {
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
@@ -294,7 +294,7 @@ static char *pointer(char *str, char *end, const char **fmt_ptr,
|
||||
{
|
||||
/* Print '+<offset>/<len>' */
|
||||
str = number(str, end, sym_offset, 16, -1, -1, SPECIAL|SIGN|PLUS);
|
||||
if ( str <= end )
|
||||
if ( str < end )
|
||||
*str = '/';
|
||||
++str;
|
||||
str = number(str, end, sym_size, 16, -1, -1, SPECIAL);
|
||||
@@ -308,10 +308,10 @@ static char *pointer(char *str, char *end, const char **fmt_ptr,
|
||||
const struct vcpu *v = arg;
|
||||
|
||||
++*fmt_ptr;
|
||||
if ( str <= end )
|
||||
if ( str < end )
|
||||
*str = 'd';
|
||||
str = number(str + 1, end, v->domain->domain_id, 10, -1, -1, 0);
|
||||
if ( str <= end )
|
||||
if ( str < end )
|
||||
*str = 'v';
|
||||
return number(str + 1, end, v->vcpu_id, 10, -1, -1, 0);
|
||||
}
|
||||
@@ -365,16 +365,16 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||
BUG_ON(((int)size < 0) || ((unsigned int)size != size));
|
||||
|
||||
str = buf;
|
||||
end = buf + size - 1;
|
||||
end = buf + size;
|
||||
|
||||
if (end < buf - 1) {
|
||||
if (end < buf) {
|
||||
end = ((void *) -1);
|
||||
size = end - buf + 1;
|
||||
size = end - buf;
|
||||
}
|
||||
|
||||
for (; *fmt ; ++fmt) {
|
||||
if (*fmt != '%') {
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = *fmt;
|
||||
++str;
|
||||
continue;
|
||||
@@ -440,17 +440,17 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||
case 'c':
|
||||
if (!(flags & LEFT)) {
|
||||
while (--field_width > 0) {
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
}
|
||||
c = (unsigned char) va_arg(args, int);
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = c;
|
||||
++str;
|
||||
while (--field_width > 0) {
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = ' ';
|
||||
++str;
|
||||
}
|
||||
@@ -485,7 +485,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||
continue;
|
||||
|
||||
case '%':
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = '%';
|
||||
++str;
|
||||
continue;
|
||||
@@ -508,11 +508,11 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = '%';
|
||||
++str;
|
||||
if (*fmt) {
|
||||
if (str <= end)
|
||||
if (str < end)
|
||||
*str = *fmt;
|
||||
++str;
|
||||
} else {
|
||||
@@ -541,11 +541,14 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||
str = number(str, end, num, base,
|
||||
field_width, precision, flags);
|
||||
}
|
||||
if (str <= end)
|
||||
*str = '\0';
|
||||
else if (size > 0)
|
||||
/* don't write out a null byte if the buf size is zero */
|
||||
*end = '\0';
|
||||
|
||||
/* don't write out a null byte if the buf size is zero */
|
||||
if (size > 0) {
|
||||
if (str < end)
|
||||
*str = '\0';
|
||||
else
|
||||
end[-1] = '\0';
|
||||
}
|
||||
/* the trailing null byte doesn't count towards the total
|
||||
* ++str;
|
||||
*/
|
||||
@@ -631,6 +634,60 @@ int scnprintf(char * buf, size_t size, const char *fmt, ...)
|
||||
}
|
||||
EXPORT_SYMBOL(scnprintf);
|
||||
|
||||
/**
|
||||
* vasprintf - Format a string and allocate a buffer to place it in
|
||||
*
|
||||
* @bufp: Pointer to a pointer to receive the allocated buffer
|
||||
* @fmt: The format string to use
|
||||
* @args: Arguments for the format string
|
||||
*
|
||||
* -ENOMEM is returned on failure and @bufp is not touched.
|
||||
* On success, 0 is returned. The buffer passed back is
|
||||
* guaranteed to be null terminated. The memory is allocated
|
||||
* from xenheap, so the buffer should be freed with xfree().
|
||||
*/
|
||||
int vasprintf(char **bufp, const char *fmt, va_list args)
|
||||
{
|
||||
va_list args_copy;
|
||||
size_t size;
|
||||
char *buf;
|
||||
|
||||
va_copy(args_copy, args);
|
||||
size = vsnprintf(NULL, 0, fmt, args_copy);
|
||||
va_end(args_copy);
|
||||
|
||||
buf = xmalloc_array(char, ++size);
|
||||
if ( !buf )
|
||||
return -ENOMEM;
|
||||
|
||||
(void) vsnprintf(buf, size, fmt, args);
|
||||
|
||||
*bufp = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* asprintf - Format a string and place it in a buffer
|
||||
* @bufp: Pointer to a pointer to receive the allocated buffer
|
||||
* @fmt: The format string to use
|
||||
* @...: Arguments for the format string
|
||||
*
|
||||
* -ENOMEM is returned on failure and @bufp is not touched.
|
||||
* On success, 0 is returned. The buffer passed back is
|
||||
* guaranteed to be null terminated. The memory is allocated
|
||||
* from xenheap, so the buffer should be freed with xfree().
|
||||
*/
|
||||
int asprintf(char **bufp, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i=vasprintf(bufp,fmt,args);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
@@ -104,6 +104,10 @@ extern int scnprintf(char * buf, size_t size, const char * fmt, ...)
|
||||
__attribute__ ((format (printf, 3, 4)));
|
||||
extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||
__attribute__ ((format (printf, 3, 0)));
|
||||
extern int asprintf(char ** bufp, const char * fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
extern int vasprintf(char ** bufp, const char * fmt, va_list args)
|
||||
__attribute__ ((format (printf, 2, 0)));
|
||||
|
||||
long simple_strtol(
|
||||
const char *cp,const char **endp, unsigned int base);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __XEN_STDARG_H__
|
||||
|
||||
typedef __builtin_va_list va_list;
|
||||
#define va_copy(dest, src) __builtin_va_copy((dest), (src))
|
||||
#define va_start(ap, last) __builtin_va_start((ap), (last))
|
||||
#define va_end(ap) __builtin_va_end(ap)
|
||||
#define va_arg __builtin_va_arg
|
||||
|
||||