From: James Harper Date: Sat, 27 Mar 2010 12:56:25 +0000 (+0100) Subject: Apply James' wide char patch X-Git-Tag: Release-7.0.0~2032 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6b5a7f5bc741bd4f8bbb910f9850d0eba1b4cd35;p=bacula%2Fbacula Apply James' wide char patch --- diff --git a/bacula/src/lib/bsnprintf.c b/bacula/src/lib/bsnprintf.c index d1d60dbc11..5fa592610b 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,11 @@ 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 char_to_int(p) ((p)- '0') #undef MAX @@ -139,6 +144,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,7 +243,9 @@ 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++; } @@ -329,8 +337,14 @@ 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 *); + currlen = fmtstr(buffer, currlen, maxlen, strvalue, flags, min, max); + } else { + /* %ls means to edit wide characters */ + wstrvalue = va_arg(args, wchar_t *); + currlen = fmtwstr(buffer, currlen, maxlen, wstrvalue, flags, min, max); + } break; case 'p': flags |= DP_F_UNSIGNED; @@ -445,6 +459,51 @@ 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; + } + if (!value) { + value = L""; + } + 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, @@ -886,6 +945,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 +1045,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);