#include #include #include #include #include #include #define R(f) \ do { \ qse_printf (QSE_T("== %s ==\n"), QSE_T(#f)); \ if (f() == -1) return -1; \ } while (0) static int test1 () { qse_str_t* s1; s1 = qse_str_open (QSE_MMGR_GETDFL(), 0, 5); if (s1 == QSE_NULL) { qse_printf (QSE_T("cannot open a string\n")); return -1; } qse_printf (QSE_T("LEN=%u\n"), (unsigned)qse_str_ncat (s1, QSE_T("i love you this is great"), 24)); qse_printf (QSE_T("LEN=%u CAPA=%u [%.*s]\n"), (unsigned)QSE_STR_LEN(s1), (unsigned)QSE_STR_CAPA(s1), (int)QSE_STR_LEN(s1), QSE_STR_PTR(s1)); qse_str_close (s1); return 0; } static int test2 () { qse_str_t s1; qse_str_init (&s1, QSE_MMGR_GETDFL(), 5); qse_printf (QSE_T("LEN=%u\n"), (unsigned)qse_str_ncat (&s1, QSE_T("i love you this is great"), 24)); qse_printf (QSE_T("LEN=%u CAPA=%u [%.*s]\n"), (unsigned)QSE_STR_LEN(&s1), (unsigned)QSE_STR_CAPA(&s1), (int)QSE_STR_LEN(&s1), QSE_STR_PTR(&s1)); qse_str_fini (&s1); return 0; } static qse_size_t resize_str_1 (qse_str_t* str, qse_size_t hint) { return QSE_STR_CAPA(str) + 1; } static qse_size_t resize_str_2 (qse_str_t* str, qse_size_t hint) { return hint; } static qse_size_t resize_str_3 (qse_str_t* str, qse_size_t hint) { return hint * 2 + hint / 2; } static qse_size_t resize_str_4 (qse_str_t* str, qse_size_t hint) { return 0; } static int test3 () { qse_str_t s1; int i; qse_str_init (&s1, QSE_MMGR_GETDFL(), 5); for (i = 0; i < 9; i++) { if (i == 0) qse_str_setsizer (&s1, resize_str_1); if (i == 1) { qse_str_setsizer (&s1, resize_str_2); qse_str_clear (&s1); } if (i == 2) qse_str_setsizer (&s1, resize_str_3); if (i == 3) qse_str_setsizer (&s1, resize_str_4); if (i == 8) qse_str_setsizer (&s1, resize_str_2); if (qse_str_ncat (&s1, QSE_T("i love you this is great"), 24) == (qse_size_t)-1) { qse_printf (QSE_T("cannot add string\n")); qse_str_fini (&s1); return -1; } qse_printf (QSE_T("LEN=%u CAPA=%u [%.*s]\n"), (unsigned)QSE_STR_LEN(&s1), (unsigned)QSE_STR_CAPA(&s1), (int)QSE_STR_LEN(&s1), QSE_STR_PTR(&s1)); } qse_str_fini (&s1); return 0; } static int test4 () { qse_str_t s1; qse_xstr_t out; qse_str_init (&s1, QSE_MMGR_GETDFL(), 0); if (qse_str_yield (&s1, &out, 0) == -1) { qse_printf (QSE_T("cannot yield string\n")); qse_str_fini (&s1); return -1; } qse_printf (QSE_T("out.ptr=%p LEN=%u [.*s]\n"), out.ptr, (unsigned)out.len, (int)out.len, out.ptr); if (qse_str_ncat (&s1, QSE_T("i love you this is great"), 24) == (qse_size_t)-1) { qse_printf (QSE_T("cannot add string\n")); qse_str_fini (&s1); return -1; } if (qse_str_yield (&s1, &out, 0) == -1) { qse_printf (QSE_T("cannot yield string\n")); qse_str_fini (&s1); return -1; } qse_printf (QSE_T("out.ptr=%p LEN=%u, [%.*s]\n"), out.ptr, (unsigned)out.len, (int)out.len, out.ptr); qse_str_fini (&s1); QSE_MMGR_FREE (QSE_MMGR_GETDFL(), out.ptr); return 0; } static int test5 (void) { int i; const qse_mchar_t* x[] = { "\0\0\0", "뛰어 올라봐. 멀리멀리 잘난척하기는", "Fly to the universe" }; for (i = 0; i < QSE_COUNTOF(x); i++) { qse_size_t k = strlen(x[i]); qse_size_t j = 0; qse_wchar_t wc; qse_wchar_t buf[10]; if (k == 0) k = 3; /* for x[0] */ qse_printf (QSE_T("[")); while (j < k) { qse_size_t wlen = QSE_COUNTOF(buf); qse_size_t y = qse_mbsntowcsn (&x[i][j], k-j, buf, &wlen); if (y <= 0) { qse_printf (QSE_T("***illegal or incomplete sequence***")); break; } if (wlen > 0 && buf[0] == QSE_T('\0')) { while (wlen > 0 && buf[--wlen] == QSE_T('\0')) { qse_printf (QSE_T("\\0")); } } else { qse_printf (QSE_T("%.*s"), (int)wlen, buf); } j += y; } qse_printf (QSE_T("] => %d bytes\n"), (int)k); } return 0; } static int test6 (void) { int i; const qse_mchar_t* x[] = { "", "뛰어 올라봐. 멀리멀리 잘난척하기는", "Fly to the universe. eat my shorts." }; qse_wchar_t buf[5]; qse_wchar_t buf2[50]; for (i = 0; i < QSE_COUNTOF(x); i++) { qse_size_t n; qse_size_t wlen = QSE_COUNTOF(buf); n = qse_mbstowcs (x[i], buf, &wlen); qse_printf (QSE_T("[%S]=>"),x[i]); #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("[%S] %d chars %d bytes\n"), buf, (int)wlen, (int)n); #else qse_printf (QSE_T("[%s] %d chars %d bytes\n"), buf, (int)wlen, (int)n); #endif } qse_printf (QSE_T("-----------------\n")); for (i = 0; i < QSE_COUNTOF(x); i++) { qse_size_t n; qse_size_t wlen = QSE_COUNTOF(buf2); n = qse_mbstowcs (x[i], buf2, &wlen); #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("[%S] %d chars %d bytes\n"), buf2, (int)wlen, (int)n); #else qse_printf (QSE_T("[%s] %d chars %d bytes\n"), buf2, (int)wlen, (int)n); #endif } return 0; } static int test7 (void) { const qse_wchar_t* x[] = { L"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?", L"Fly to the universe, kick you ass" }; qse_mchar_t buf[15]; int i, j; for (i = 0; i < QSE_COUNTOF(x); i++) { size_t len = wcslen(x[i]); qse_size_t n; if (len == 0) len = 20; /* for x[0] */ qse_printf (QSE_T("[")); for (j = 0; j < len; j += n) { qse_size_t mlen = sizeof(buf); n = qse_wcsntombsn (&x[i][j], len-j, buf, &mlen); if (n <= 0) { qse_printf (QSE_T("***illegal character or buffer not large***")); break; } if (mlen > 0 && buf[0] == QSE_T('\0')) { while (mlen > 0 && buf[--mlen] == QSE_T('\0')) { qse_printf (QSE_T("\\0")); } } else { #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("%.*s"), (int)mlen, buf); #else #ifdef _WIN32 qse_printf (QSE_T("%.*S"), (int)mlen, buf); #else /* at least on linux and macosx, wprintf seems * to taks preceision as the number of wide * characters with %s. */ qse_printf (QSE_T("%.*S"), n, buf); #endif #endif } } qse_printf (QSE_T("] => %d chars\n"), (int)len); } return 0; } static int test8 (void) { const qse_wchar_t* x[] = { L"", L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?", L"Fly to the universe, kick you ass" }; qse_mchar_t buf[10]; qse_mchar_t buf2[100]; int i, j; for (i = 0; i < QSE_COUNTOF(x); i++) { qse_size_t n; qse_size_t mlen = sizeof(buf); memset (buf, 'A', sizeof(buf)); n = qse_wcstombs (x[i], buf, &mlen); #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("[%s] chars=%d bytes=%d\n"), buf, (int)n, (int)mlen); #else qse_printf (QSE_T("[%S] chars=%d bytes=%d\n"), buf, (int)n, (int)mlen); #endif } qse_printf (QSE_T("-----------------\n")); for (i = 0; i < QSE_COUNTOF(x); i++) { qse_size_t n; qse_size_t mlen = sizeof(buf2); memset (buf2, 'A', sizeof(buf2)); n = qse_wcstombs (x[i], buf2, &mlen); #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("[%s] chars=%d bytes=%d\n"), buf2, (int)n, (int)mlen); #else qse_printf (QSE_T("[%S] chars=%d bytes=%d\n"), buf2, (int)n, (int)mlen); #endif } qse_printf (QSE_T("-----------------\n")); for (i = 0; i < QSE_COUNTOF(x); i++) { qse_size_t n; const qse_wchar_t* p = x[i]; while (1) { memset (buf, 'A', sizeof(buf)); qse_size_t mlen = sizeof(buf); n = qse_wcstombs (p, buf, &mlen); if (n == 0) break; #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("[%s] chars=%d bytes=%d\n"), buf, (int)n, (int)mlen); #else qse_printf (QSE_T("[%S] chars=%d bytes=%d\n"), buf, (int)n, (int)mlen); #endif p += n; } } return 0; } static int test9 (void) { char buf[24]; int i; const qse_wchar_t* x[] = { L"", L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?", L"A\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?", L"AB\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?", L"ABC\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?", L"ABCD\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4?", L"ABCDEFGHIJKLMNOPQRSTUV", L"ABCDEFGHIJKLMNOPQRSTUVW", L"ABCDEFGHIJKLMNOPQRSTUVWX", L"ABCDEFGHIJKLMNOPQRSTUVWXY", L"ABCDEFGHIJKLMNOPQRSTUVWXYZ" }; for (i = 0; i < QSE_COUNTOF(x); i++) { #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("[%S] => "), x[i]); #else qse_printf (QSE_T("[%s] => "), x[i]); #endif if (qse_wcstombs_strict (x[i], buf, QSE_COUNTOF(buf)) == -1) { qse_printf (QSE_T("ERROR\n")); } else { #ifdef QSE_CHAR_IS_MCHAR qse_printf (QSE_T("[%s]\n"), buf); #else qse_printf (QSE_T("[%S]\n"), buf); #endif } } return 0; } static int test10 (void) { qse_char_t buf[1000]; qse_strfcpy (buf, QSE_T("${2}${1}${0}"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222")); qse_printf (QSE_T("buf=[%s]\n"), buf); qse_strfcpy (buf, QSE_T("${2}/${1}/${0}"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222")); qse_printf (QSE_T("buf=[%s]\n"), buf); qse_strfcpy (buf, QSE_T("/${2}/${1}/${0}/"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222")); qse_printf (QSE_T("buf=[%s]\n"), buf); qse_strfcpy (buf, QSE_T("/$${2}/$${1}/$${0}/"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222")); qse_printf (QSE_T("buf=[%s]\n"), buf); qse_strfcpy (buf, QSE_T("/${2/${1}/${0}/"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222")); qse_printf (QSE_T("buf=[%s]\n"), buf); qse_strfcpy (buf, QSE_T("/$2}/${1}/${0}/"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222")); qse_printf (QSE_T("buf=[%s]\n"), buf); qse_strfcpy (buf, QSE_T("/${2}/${1}/${0}/${3}/${4}/${5}/${6}/${7}/${8}/${9}/${10}/${11}/"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222"), QSE_T("33333"), QSE_T("44444"), QSE_T("55555"), QSE_T("66666"), QSE_T("77777"), QSE_T("88888"), QSE_T("99999"), QSE_T("aaaaa"), QSE_T("bbbbb")); qse_printf (QSE_T("buf=[%s]\n"), buf); qse_strfcpy (buf, QSE_T("/${2}/${1}/${0}/${2}/${1}/${0}/"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222")); qse_printf (QSE_T("buf=[%s]\n"), buf); qse_strfcpy (buf, QSE_T("/${002}/${001}/${000}/"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222")); qse_printf (QSE_T("buf=[%s]\n"), buf); return 0; } static int test11 (void) { qse_char_t buf[20]; int i, j; for (i = 0; i <= QSE_COUNTOF(buf); i++) { qse_strcpy (buf, QSE_T("AAAAAAAAAAAAAAAAAAA")); qse_strxfcpy (buf, i, QSE_T("${2}${1}${0}"), QSE_T("00000"), QSE_T("11111"), QSE_T("22222")); qse_printf (QSE_T("bufsize=%02d, buf=[%-20s] "), i, buf); qse_printf (QSE_T("[")); for (j = 0; j < QSE_COUNTOF(buf); j++) { if (buf[j] == QSE_T('\0')) qse_printf (QSE_T("*")); else qse_printf (QSE_T("%c"), buf[j]); } qse_printf (QSE_T("]\n")); } return 0; } int main () { setlocale (LC_ALL, ""); qse_printf (QSE_T("--------------------------------------------------------------------------------\n")); qse_printf (QSE_T("Set the environment LANG to a Unicode locale such as UTF-8 if you see the illegal XXXXX errors. If you see such errors in Unicode locales, this program might be buggy. It is normal to see such messages in non-Unicode locales as it uses Unicode data\n")); qse_printf (QSE_T("--------------------------------------------------------------------------------\n")); R (test1); R (test2); R (test3); R (test4); R (test5); R (test6); R (test7); R (test8); R (test9); R (test10); R (test11); return 0; }