From eaaeab8dcb5538515d3f5c549fa7fb316ed97106 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 11 Jul 2010 12:52:55 +0200 Subject: [PATCH] Update to master's bsnprintf.c --- bacula/src/lib/bsnprintf.c | 129 ++++++++++++++++++++++++++++++++++--- 1 file changed, 119 insertions(+), 10 deletions(-) diff --git a/bacula/src/lib/bsnprintf.c b/bacula/src/lib/bsnprintf.c index d1d60dbc11..e55b749b79 100644 --- a/bacula/src/lib/bsnprintf.c +++ b/bacula/src/lib/bsnprintf.c @@ -43,6 +43,8 @@ #include "bacula.h" +#include + #define FP_OUTPUT 1 /* Bacula uses floating point */ /* Define the following if you want all the features of @@ -63,6 +65,8 @@ int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args); static int32_t fmtstr(char *buffer, int32_t currlen, int32_t maxlen, const char *value, int flags, int min, int max); +static int32_t fmtwstr(char *buffer, int32_t currlen, int32_t maxlen, + const wchar_t *value, int flags, int min, int max); static int32_t fmtint(char *buffer, int32_t currlen, int32_t maxlen, int64_t value, int base, int min, int max, int flags); @@ -106,10 +110,12 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, #define DP_F_DOT (1 << 7) /* Conversion Flags */ -#define DP_C_INT16 1 -#define DP_C_INT32 2 -#define DP_C_LDOUBLE 3 -#define DP_C_INT64 4 +#define DP_C_INT16 1 +#define DP_C_INT32 2 +#define DP_C_LDOUBLE 3 +#define DP_C_INT64 4 +#define DP_C_WCHAR 5 /* wide characters */ +#define DP_C_SIZE_T 6 #define char_to_int(p) ((p)- '0') #undef MAX @@ -139,6 +145,7 @@ int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args) char ch; int64_t value; char *strvalue; + wchar_t *wstrvalue; int min; int max; int state; @@ -237,11 +244,17 @@ int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args) case 'l': cflags = DP_C_INT32; ch = *format++; - if (ch == 'l') { /* It's a long long */ + if (ch == 's') { + cflags = DP_C_WCHAR; + } else if (ch == 'l') { /* It's a long long */ cflags = DP_C_INT64; ch = *format++; } break; + case 'z': + cflags = DP_C_SIZE_T; + ch = *format++; + break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; @@ -265,6 +278,8 @@ int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args) value = va_arg(args, int32_t); } else if (cflags == DP_C_INT64) { value = va_arg(args, int64_t); + } else if (cflags == DP_C_SIZE_T) { + value = va_arg(args, ssize_t); } else { value = va_arg(args, int); } @@ -291,6 +306,8 @@ int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args) value = va_arg(args, uint32_t); } else if (cflags == DP_C_INT64) { value = va_arg(args, uint64_t); + } else if (cflags == DP_C_SIZE_T) { + value = va_arg(args, size_t); } else { value = va_arg(args, unsigned int); } @@ -329,8 +346,20 @@ int bvsnprintf(char *buffer, int32_t maxlen, const char *format, va_list args) outch(ch); break; case 's': - strvalue = va_arg(args, char *); - currlen = fmtstr(buffer, currlen, maxlen, strvalue, flags, min, max); + if (cflags != DP_C_WCHAR) { + strvalue = va_arg(args, char *); + if (!strvalue) { + strvalue = (char *)""; + } + currlen = fmtstr(buffer, currlen, maxlen, strvalue, flags, min, max); + } else { + /* %ls means to edit wide characters */ + wstrvalue = va_arg(args, wchar_t *); + if (!wstrvalue) { + wstrvalue = (wchar_t *)L""; + } + currlen = fmtwstr(buffer, currlen, maxlen, wstrvalue, flags, min, max); + } break; case 'p': flags |= DP_F_UNSIGNED; @@ -414,9 +443,6 @@ static int32_t fmtstr(char *buffer, int32_t currlen, int32_t maxlen, } else if (max < 0) { max = maxlen; } - if (!value) { - value = ""; - } strln = strlen(value); if (strln > max) { strln = max; /* truncate to max */ @@ -445,6 +471,48 @@ static int32_t fmtstr(char *buffer, int32_t currlen, int32_t maxlen, return currlen; } +static int32_t fmtwstr(char *buffer, int32_t currlen, int32_t maxlen, + const wchar_t *value, int flags, int min, int max) +{ + int padlen, strln; /* amount to pad */ + int cnt = 0; + char ch; + + + if (flags & DP_F_DOT && max < 0) { /* Max not specified */ + max = 0; + } else if (max < 0) { + max = maxlen; + } + strln = wcslen(value); + if (strln > max) { + strln = max; /* truncate to max */ + } + padlen = min - strln; + if (padlen < 0) { + padlen = 0; + } + if (flags & DP_F_MINUS) { + padlen = -padlen; /* Left Justify */ + } + + while (padlen > 0) { + outch(' '); + --padlen; + } + while (*value && (cnt < max)) { + + ch = (*value++) & 0xff; + outch(ch); + ++cnt; + } + while (padlen < 0) { + outch(' '); + ++padlen; + } + return currlen; +} + /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ static int32_t fmtint(char *buffer, int32_t currlen, int32_t maxlen, @@ -684,6 +752,7 @@ static int32_t fmtfp(char *buffer, int32_t currlen, int32_t maxlen, if (!result) { r_length = 0; + dummy[0] = 0; result = dummy; } else { r_length = strlen(result); @@ -886,6 +955,25 @@ int main(int argc, char *argv[]) }; const char *s_nums[] = { "abc", "def", "ghi", "123", "4567", "a", "bb", "ccccccc", NULL}; + const char *ls_fmt[] = { + "%-1.8ls", + "%1.8ls", + "%123.9ls", + "%5.8ls", + "%10.5ls", + "% 10.3ls", + "%+22.1ls", + "%01.3ls", + "%ls", + "%10ls", + "%3ls", + "%3.0ls", + "%3.ls", + NULL + }; + const wchar_t *ls_nums[] = { L"abc", L"def", L"ghi", L"123", L"4567", L"a", L"bb", L"ccccccc", NULL}; + + int x, y; int fail = 0; @@ -967,6 +1055,27 @@ int main(int argc, char *argv[]) } } + for (x = 0; ls_fmt[x] != NULL; x++) { + for (y = 0; ls_nums[y] != 0; y++) { + int pcount, bcount; + bcount = bsnprintf(buf1, sizeof(buf1), ls_fmt[x], ls_nums[y]); + printf("%s\n", buf1); + pcount = sprintf(buf2, ls_fmt[x], ls_nums[y]); + if (bcount != pcount) { + printf("bsnprintf count %d doesn't match sprintf count %d\n", + bcount, pcount); + } + if (strcmp(buf1, buf2)) { + printf + ("bsnprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + ls_fmt[x], buf1, buf2); + fail++; + } + num++; + } + } + + printf("%d tests failed out of %d.\n", fail, num); -- 2.39.5