diff options
Diffstat (limited to 'Utilities/cmlibarchive/libarchive/archive_string_sprintf.c')
-rw-r--r-- | Utilities/cmlibarchive/libarchive/archive_string_sprintf.c | 204 |
1 files changed, 113 insertions, 91 deletions
diff --git a/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c index cd5017b..7d7d971 100644 --- a/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c +++ b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c @@ -24,7 +24,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_string_sprintf.c,v 1.10 2008/03/14 22:00:09 kientzle Exp $"); +__FBSDID("$FreeBSD: head/lib/libarchive/archive_string_sprintf.c 189435 2009-03-06 05:14:55Z kientzle $"); /* * The use of printf()-family functions can be troublesome @@ -51,31 +51,34 @@ __FBSDID("$FreeBSD: src/lib/libarchive/archive_string_sprintf.c,v 1.10 2008/03/1 static void append_uint(struct archive_string *as, uintmax_t d, unsigned base) { - static const char *digits = "0123456789abcdef"; - if (d >= base) - append_uint(as, d/base, base); - archive_strappend_char(as, digits[d % base]); + static const char *digits = "0123456789abcdef"; + if (d >= base) + append_uint(as, d/base, base); + archive_strappend_char(as, digits[d % base]); } static void append_int(struct archive_string *as, intmax_t d, unsigned base) { - if (d < 0) { - archive_strappend_char(as, '-'); - d = -d; - } - append_uint(as, d, base); + uintmax_t ud; + + if (d < 0) { + archive_strappend_char(as, '-'); + ud = (d == INTMAX_MIN) ? (uintmax_t)(INTMAX_MAX) + 1 : (uintmax_t)(-d); + } else + ud = d; + append_uint(as, ud, base); } void -__archive_string_sprintf(struct archive_string *as, const char *fmt, ...) +archive_string_sprintf(struct archive_string *as, const char *fmt, ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - archive_string_vsprintf(as, fmt, ap); - va_end(ap); + va_start(ap, fmt); + archive_string_vsprintf(as, fmt, ap); + va_end(ap); } /* @@ -83,82 +86,101 @@ __archive_string_sprintf(struct archive_string *as, const char *fmt, ...) * necessary. */ void -__archive_string_vsprintf(struct archive_string *as, const char *fmt, +archive_string_vsprintf(struct archive_string *as, const char *fmt, va_list ap) { - char long_flag; - intmax_t s; /* Signed integer temp. */ - uintmax_t u; /* Unsigned integer temp. */ - const char *p, *p2; - - if (__archive_string_ensure(as, 64) == NULL) - __archive_errx(1, "Out of memory"); - - if (fmt == NULL) { - as->s[0] = 0; - return; - } - - for (p = fmt; *p != '\0'; p++) { - const char *saved_p = p; - - if (*p != '%') { - archive_strappend_char(as, *p); - continue; - } - - p++; - - long_flag = '\0'; - switch(*p) { - case 'j': - long_flag = 'j'; - p++; - break; - case 'l': - long_flag = 'l'; - p++; - break; - } - - switch (*p) { - case '%': - __archive_strappend_char(as, '%'); - break; - case 'c': - s = va_arg(ap, int); - __archive_strappend_char(as, s); - break; - case 'd': - switch(long_flag) { - case 'j': s = va_arg(ap, intmax_t); break; - case 'l': s = va_arg(ap, long); break; - default: s = va_arg(ap, int); break; - } - append_int(as, s, 10); - break; - case 's': - p2 = va_arg(ap, char *); - archive_strcat(as, p2); - break; - case 'o': case 'u': case 'x': case 'X': - /* Common handling for unsigned integer formats. */ - switch(long_flag) { - case 'j': u = va_arg(ap, uintmax_t); break; - case 'l': u = va_arg(ap, unsigned long); break; - default: u = va_arg(ap, unsigned int); break; - } - /* Format it in the correct base. */ - switch (*p) { - case 'o': append_uint(as, u, 8); break; - case 'u': append_uint(as, u, 10); break; - default: append_uint(as, u, 16); break; - } - break; - default: - /* Rewind and print the initial '%' literally. */ - p = saved_p; - archive_strappend_char(as, *p); - } - } + char long_flag; + intmax_t s; /* Signed integer temp. */ + uintmax_t u; /* Unsigned integer temp. */ + const char *p, *p2; + const wchar_t *pw; + + if (archive_string_ensure(as, 64) == NULL) + __archive_errx(1, "Out of memory"); + + if (fmt == NULL) { + as->s[0] = 0; + return; + } + + for (p = fmt; *p != '\0'; p++) { + const char *saved_p = p; + + if (*p != '%') { + archive_strappend_char(as, *p); + continue; + } + + p++; + + long_flag = '\0'; + switch(*p) { + case 'j': + case 'l': + case 'z': + long_flag = *p; + p++; + break; + } + + switch (*p) { + case '%': + archive_strappend_char(as, '%'); + break; + case 'c': + s = va_arg(ap, int); + archive_strappend_char(as, s); + break; + case 'd': + switch(long_flag) { + case 'j': s = va_arg(ap, intmax_t); break; + case 'l': s = va_arg(ap, long); break; + case 'z': s = va_arg(ap, ssize_t); break; + default: s = va_arg(ap, int); break; + } + append_int(as, s, 10); + break; + case 's': + switch(long_flag) { + case 'l': + pw = va_arg(ap, wchar_t *); + if (pw == NULL) + pw = L"(null)"; + archive_string_append_from_wcs(as, pw, wcslen(pw)); + break; + default: + p2 = va_arg(ap, char *); + if (p2 == NULL) + p2 = "(null)"; + archive_strcat(as, p2); + break; + } + break; + case 'S': + pw = va_arg(ap, wchar_t *); + if (pw == NULL) + pw = L"(null)"; + archive_string_append_from_wcs(as, pw, wcslen(pw)); + break; + case 'o': case 'u': case 'x': case 'X': + /* Common handling for unsigned integer formats. */ + switch(long_flag) { + case 'j': u = va_arg(ap, uintmax_t); break; + case 'l': u = va_arg(ap, unsigned long); break; + case 'z': u = va_arg(ap, size_t); break; + default: u = va_arg(ap, unsigned int); break; + } + /* Format it in the correct base. */ + switch (*p) { + case 'o': append_uint(as, u, 8); break; + case 'u': append_uint(as, u, 10); break; + default: append_uint(as, u, 16); break; + } + break; + default: + /* Rewind and print the initial '%' literally. */ + p = saved_p; + archive_strappend_char(as, *p); + } + } } |