Add test routines for internationalization routines.
LICENSE MIT
Reviewed-on: http://gerrit.openafs.org/218
Tested-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
$(DEL) $(LOGON_DLLFILE)
mkdir:
+
+############################################################################
+# Tests
+
+{test}.c{$(OUT)\}.obj:
+ $(C2OBJ) $<
+
+test::
+
+test:: btreetest
+
+btreetest: "$(OUT)\btreetest.exe"
+ "$(OUT)\btreetest.exe"
+
+$(OUT)\btreetest.exe: \
+ $(OUT)\btreetest.obj \
+ $(OUT)\cm_btree.obj \
+ $(OUT)\cm_nls.obj \
+ $(OUT)\cm_utils.obj \
+ $(DESTDIR)\lib\libosi.lib
+ $(EXECONLINK)
+ $(_VC_MANIFEST_EMBED_EXE)
+ $(EXEPREP)
--- /dev/null
+#include<windows.h>
+#include<stdio.h>
+#include<wchar.h>
+#include<strsafe.h>
+
+#include "..\afsd.h"
+
+#define paste(a,b) a ## b
+#define _L(a) paste(L,a)
+
+#define TRACE1 wprintf
+
+/* Setup and Fakery ... */
+osi_log_t * afsd_logp;
+
+void cm_SetFid(cm_fid_t *fidp, afs_uint32 cell, afs_uint32 volume, afs_uint32 vnode, afs_uint32 unique)
+{
+ fidp->cell = cell;
+ fidp->volume = volume;
+ fidp->vnode = vnode;
+ fidp->unique = unique;
+ fidp->hash = ((cell & 0xF) << 28) | ((volume & 0x3F) << 22) | ((vnode & 0x7FF) << 11) | (unique & 0x7FF);
+}
+
+cm_scache_t *cm_FindSCache(cm_fid_t *fidp)
+{
+ return NULL;
+}
+
+void cm_ReleaseSCache(cm_scache_t *scp)
+{
+}
+
+
+long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp,
+ osi_hyper_t *startOffsetp, cm_user_t *userp, cm_req_t *reqp,
+ cm_scache_t **retscp)
+{
+ return 0;
+}
+
+void
+afsi_log(char *pattern, ...)
+{
+ char s[256], t[100], d[100], u[512];
+ va_list ap;
+ va_start(ap, pattern);
+
+ StringCbVPrintfA(s, sizeof(s), pattern, ap);
+ GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));
+ GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, d, sizeof(d));
+ StringCbPrintfA(u, sizeof(u), "%s %s: %s\r\n", d, t, s);
+ printf("%s", u);
+}
+
+
+static int initialize_tests(void)
+{
+ osi_Init();
+ cm_InitNormalization();
+
+ if (!cm_InitBPlusDir()) {
+ TRACE1(L"Can't initialize BPlusDir\n");
+ return 1;
+ }
+
+ afsd_logp = osi_LogCreate("fakelog", 100);
+
+ return 0;
+}
+
+int n_succeeded = 0;
+int n_failed = 0;
+
+int n_subSucceeded = 0;
+int n_subFailed = 0;
+
+static int runtest(wchar_t * testname, int (*f)(void))
+{
+ int rv = 0;
+
+ n_subSucceeded = 0;
+ n_subFailed = 0;
+
+ TRACE1(L"Begin test %s\n", testname);
+ f();
+ TRACE1(L"End test %s\n", testname);
+ TRACE1(L"Subtests Succeeded %d, Failed %d\n", n_subSucceeded, n_subFailed);
+
+ if (n_subFailed)
+ n_failed++;
+ else
+ n_succeeded++;
+
+ return rv;
+}
+
+#define RUNTEST(f) runtest(_L(#f), f)
+
+#define IS_NOT_NULL(v) (((v) != NULL)? n_subSucceeded++: (TRACE1(L"Failed %s\n", _L(#v)), n_subFailed++))
+#define IS(e) ((e)? n_subSucceeded++ : (TRACE1(L"Failed %s\n", _L(#e)), n_subFailed++))
+#define CHECK_IF(e) do { if (e) { n_subSucceeded++; } else { TRACE1(L"Failed %s\n", _L(#e)); n_subFailed++; return 1; }} while (0)
+
+/**************************************************************/
+/* Actual tests */
+
+struct strings {
+ const fschar_t * str;
+ const clientchar_t * lookup;
+ int rc;
+};
+
+struct strings simple[] = {
+ {"abc", L"ABC", CM_ERROR_INEXACT_MATCH},
+ {"A", L"A", 0},
+ {".", L".", 0},
+ {"567", L"567", 0},
+ {"b", L"B", CM_ERROR_INEXACT_MATCH},
+ {"d", L"D", CM_ERROR_INEXACT_MATCH},
+ {"àáâ", L"\x00c0\x00c1\x00c2", CM_ERROR_INEXACT_MATCH},
+ {"Ŷ", L"\x0177", CM_ERROR_INEXACT_MATCH},
+ {"a\xef\xac\xb4",L"a\xfb34",0},
+ {"b\xd7\x94\xd6\xbc",L"b\xfb34",0},
+ {"c\xef\xac\xb4",L"c\x05d4\x05bc",0},
+ {"d\xd7\x94\xd6\xbc",L"d\x05d4\x05bc",0},
+};
+
+void init_scache(cm_scache_t * scp, cm_fid_t * fidp)
+{
+ memset(scp, 0, sizeof(cm_scache_t));
+ scp->magic = CM_SCACHE_MAGIC;
+ lock_InitializeRWLock(&scp->rw, "cm_scache_t rw");
+ lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock");
+ lock_InitializeRWLock(&scp->dirlock, "cm_scache_t dirlock");
+ scp->serverLock = -1;
+ scp->fid = *fidp;
+ scp->refCount = 1;
+}
+
+int simple_test(void)
+{
+ Tree * t;
+ int i;
+
+ t = initBtree(64, MAX_FANOUT, cm_BPlusCompareNormalizedKeys);
+ CHECK_IF(t != NULL);
+
+ for (i=0; i < lengthof(simple); i++) {
+ normchar_t * norm;
+ keyT key;
+ dataT data;
+
+ norm = cm_FsStringToNormStringAlloc(simple[i].str, -1, NULL);
+ CHECK_IF(norm != NULL);
+
+ key.name = norm;
+
+ data.cname = cm_FsStringToClientStringAlloc(simple[i].str, -1, NULL);
+ data.fsname = cm_FsStrDup(simple[i].str);
+ data.shortform = FALSE;
+ cm_SetFid(&data.fid, 1, 2, i, 4);
+
+ insert(t, key, data);
+
+ if (!cm_Is8Dot3(data.cname)) {
+ wchar_t wshortName[13];
+ cm_dirFid_t dfid;
+
+ dfid.vnode = i;
+ dfid.unique = 0;
+
+ cm_Gen8Dot3NameIntW(data.cname, &dfid, wshortName, NULL);
+
+ key.name = wshortName;
+ data.cname = cm_FsStringToClientStringAlloc(simple[i].str, -1, NULL);
+ data.fsname = cm_FsStrDup(simple[i].str);
+ data.shortform = TRUE;
+
+ insert(t, key, data);
+ }
+
+ free(norm);
+ }
+
+ for (i=0; i < lengthof(simple); i++) {
+ int rc = EINVAL;
+ normchar_t * entry = NULL;
+ keyT key = {NULL};
+ Nptr leafNode = NONODE;
+ cm_fid_t fid;
+ cm_fid_t * cfid = &fid;
+
+ TRACE1(L"Test row %d\n", i);
+
+ entry = cm_ClientStringToNormStringAlloc(simple[i].lookup, -1, NULL);
+ key.name = entry;
+
+ leafNode = bplus_Lookup(t, key);
+ if (leafNode != NONODE) {
+ int slot;
+ Nptr firstDataNode, dataNode, nextDataNode;
+ int exact = 0;
+ int count = 0;
+
+ slot = getSlot(t, leafNode);
+ if (slot <= BTERROR) {
+ rc = (slot == BTERROR ? EINVAL : ENOENT);
+ goto done;
+ }
+ firstDataNode = getnode(leafNode, slot);
+
+ for ( dataNode = firstDataNode; dataNode; dataNode = nextDataNode) {
+ count++;
+ if (!comparekeys(t)(key, getdatakey(dataNode), EXACT_MATCH) ) {
+ exact = 1;
+ break;
+ }
+ nextDataNode = getdatanext(dataNode);
+ }
+
+ if (exact) {
+ *cfid = getdatavalue(dataNode).fid;
+ rc = 0;
+ } else if (count == 1) {
+ *cfid = getdatavalue(firstDataNode).fid;
+ rc = CM_ERROR_INEXACT_MATCH;
+ } else {
+ rc = CM_ERROR_AMBIGUOUS_FILENAME;
+ }
+ } else {
+ rc = ENOENT;
+ }
+
+ done:
+ if (entry)
+ free(entry);
+
+ IS(rc == simple[i].rc);
+ if (rc == simple[i].rc)
+ IS(fid.vnode == i);
+ }
+}
+
+
+int wmain(int argc, wchar_t ** argv)
+{
+ TRACE1(L"\n\nRunning BPLUS tests...\n\n");
+ if (initialize_tests())
+ return 1;
+
+ RUNTEST(simple_test);
+
+ TRACE1(L"\nDone\n");
+ TRACE1(L"# of test Succeeded: %d\n", n_succeeded);
+ TRACE1(L"# of test Failed: %d\n", n_failed);
+
+ return 0;
+}
--- /dev/null
+#include<stdio.h>
+#include<wchar.h>
+#include "..\cm_nls.h"
+
+#define elements_in(a) (sizeof(a)/sizeof(a[0]))
+
+struct norm_pair {
+ const cm_unichar_t * left;
+ const cm_normchar_t * right;
+};
+
+struct norm_pair normalization_pairs[] = {
+ { L"abcdefghijklmnopq", L"abcdefghijklmnopq" },
+ { L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234",
+
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234"
+ L"abcdefghijklmnopqrstuvwxyz1234" },
+ { L"12839481flalfoo_)()(*&#@(*&",
+ L"12839481flalfoo_)()(*&#@(*&" }
+};
+
+void dumputf8(const unsigned char * s) {
+ while (*s) {
+ printf("%02X ", (int) *s++);
+ }
+}
+
+void dumpunicode(const wchar_t * s) {
+ while (*s) {
+ printf("%04X ", (int) *s++);
+ }
+}
+
+int cm_NormalizeStringAllocTest(void)
+{
+ int i;
+
+ for (i=0; i < elements_in(normalization_pairs); i++) {
+ cm_normchar_t * nstr;
+ int cchdest = 0;
+
+ printf ("Test #%d:", i);
+
+ nstr = cm_NormalizeStringAlloc(normalization_pairs[i].left, -1, &cchdest);
+
+ if (nstr == NULL) {
+ printf ("FAILED! returned a NULL\n");
+ return 1;
+ }
+
+ if (wcscmp(nstr, normalization_pairs[i].right)) {
+ printf ("FAILED: Expected [");
+ dumpunicode(normalization_pairs[i].right);
+ printf ("] Received [");
+ dumpunicode(nstr);
+ printf ("]\n");
+ return 1;
+ }
+
+ if (wcslen(nstr) != cchdest - 1) {
+ printf ("FAILED: Length is wrong\n");
+ return 1;
+ }
+
+ printf ("PASS\n");
+
+ free (nstr);
+ }
+
+ return 0;
+}
+
+typedef struct norm_test_entry {
+ const wchar_t * str;
+ const wchar_t * nfc;
+ const wchar_t * nfd;
+ const wchar_t * nfkc;
+ const wchar_t * nfkd;
+} norm_test_entry;
+
+extern norm_test_entry norm_tests[];
+extern int n_norm_tests;
+
+int cm_NormalizeStringTest(void)
+{
+ int i;
+ int n_failed = 0;
+
+ for (i=0; i < n_norm_tests; i++) {
+ cm_normchar_t * nfc;
+
+ nfc = cm_NormalizeStringAlloc(norm_tests[i].nfd, -1, NULL);
+ if (nfc == NULL) {
+ printf ("FAILED: returned a NULL\n");
+ return 1;
+ }
+
+ if (wcscmp(nfc, norm_tests[i].nfc)) {
+ printf ("FAILED: Expected [");
+ dumpunicode(norm_tests[i].nfc);
+ printf ("] Received [");
+ dumpunicode(nfc);
+ printf ("]\n");
+ n_failed ++;
+ }
+
+ free(nfc);
+ }
+
+ if (n_failed)
+ printf ("Number of failed tests: %d\n", n_failed);
+
+ return 0;
+}
+
+typedef struct conv_test_entry {
+ const cm_utf8char_t * str;
+ const cm_unichar_t * wstr;
+} conv_test_entry;
+
+#define CTEST(a) { a, L ## a }
+
+conv_test_entry conv_tests[] = {
+ CTEST(""),
+ CTEST("a"),
+ CTEST("abcdefghijkl"),
+ CTEST("osidfja*(2312835"),
+ {"\xee\x80\x80", L"\xe000"},
+ {"\xef\xbf\xbd", L"\xfffd"},
+ {"\xf0\x9f\xbf\xbf", L"\xd83f\xdfff"}, /* Surrogates */
+ {"\xF1\x9F\xBF\xBE", L"\xD93F\xDFFE"},
+ {"\xf0\x90\x80\x80", L"\xd800\xdc00"},
+};
+
+int cm_Utf16ToUtf8AllocTest(void)
+{
+ int i;
+
+ for (i=0; i < sizeof(conv_tests)/sizeof(conv_tests[0]); i++) {
+ cm_utf8char_t * c;
+ int len = 0;
+
+ printf ("Test #%d:", i);
+
+ c = cm_Utf16ToUtf8Alloc(conv_tests[i].wstr, -1, &len);
+
+ if (c == NULL) {
+ printf ("FAILED: returned NULL\n");
+ return 1;
+ }
+
+ if (strlen(c) + 1 != len) {
+ printf ("FAILED: Returned wrong length [%d]. Actual length [%d]\n", len,
+ strlen(c) + 1);
+ return 1;
+ }
+
+ if (strcmp(c, conv_tests[i].str)) {
+ printf ("FAILED: Expected [");
+ dumputf8(conv_tests[i].str);
+ printf ("]. Returned [");
+ dumputf8(c);
+ printf ("]\n");
+ return 1;
+ }
+
+ printf("PASS\n");
+
+ free(c);
+ }
+
+ return 0;
+}
+
+int cm_Utf16ToUtf8Test(void)
+{
+ int i;
+ cm_utf8char_t c[1024];
+
+ for (i=0; i < sizeof(conv_tests)/sizeof(conv_tests[0]); i++) {
+ int len;
+
+ printf ("Test #%d:", i);
+
+ len = cm_Utf16ToUtf8(conv_tests[i].wstr, -1, c, sizeof(c)/sizeof(c[0]));
+
+ if (len == 0) {
+ printf ("FAILED: returned 0\n");
+ return 1;
+ }
+
+ if (strlen(c) + 1 != len) {
+ printf ("FAILED: Returned wrong length [%d]. Actual length [%d]\n", len,
+ strlen(c) + 1);
+ return 1;
+ }
+
+ if (strcmp(c, conv_tests[i].str)) {
+ printf ("FAILED: Expected [%s]. Returned [%s]\n", conv_tests[i].str, c);
+ return 1;
+ }
+
+ printf("PASS\n");
+ }
+
+ return 0;
+}
+
+int cm_Utf8ToUtf16AllocTest(void)
+{
+ int i;
+
+ for (i=0; i < sizeof(conv_tests)/sizeof(conv_tests[0]); i++) {
+ cm_unichar_t * c;
+ int len = 0;
+
+ printf ("Test #%d:", i);
+
+ c = cm_Utf8ToUtf16Alloc(conv_tests[i].str, -1, &len);
+
+ if (c == NULL) {
+ printf ("FAILED: returned NULL\n");
+ return 1;
+ }
+
+ if (wcslen(c) + 1 != len) {
+ printf ("FAILED: Returned wrong length [%d]. Actual length [%d]\n", len,
+ wcslen(c) + 1);
+ return 1;
+ }
+
+ if (wcscmp(c, conv_tests[i].wstr)) {
+ printf ("FAILED: Expected [");
+ dumpunicode(conv_tests[i].wstr);
+ printf ("]. Returned [");
+ dumpunicode(c);
+ printf ("]\n");
+ return 1;
+ }
+
+ printf("PASS\n");
+
+ free(c);
+ }
+
+ return 0;
+}
+
+int cm_Utf8ToUtf16Test(void)
+{
+ int i;
+ cm_unichar_t c[1024];
+
+ for (i=0; i < sizeof(conv_tests)/sizeof(conv_tests[0]); i++) {
+ int len = 0;
+
+ printf ("Test #%d:", i);
+
+ len = cm_Utf8ToUtf16(conv_tests[i].str, -1, c, sizeof(c)/sizeof(c[0]));
+
+ if (len == 0) {
+ printf ("FAILED: returned 0\n");
+ return 1;
+ }
+
+ if (wcslen(c) + 1 != len) {
+ printf ("FAILED: Returned wrong length [%d]. Actual length [%d]\n", len,
+ wcslen(c) + 1);
+ return 1;
+ }
+
+ if (wcscmp(c, conv_tests[i].wstr)) {
+ printf ("FAILED: Expected [");
+ dumpunicode(conv_tests[i].wstr);
+ printf ("]. Returned [");
+ dumpunicode(c);
+ printf ("]\n");
+ return 1;
+ }
+
+ printf("PASS\n");
+ }
+
+ return 0;
+}
+
+int main(int argc, char ** argv)
+{
+ int trv;
+
+ cm_InitNormalization();
+
+#define RUNTEST(f) printf("Begin " #f "\n"); trv = f(); printf ("End " #f "\n\n"); if (trv != 0) return trv;
+
+ RUNTEST(cm_NormalizeStringAllocTest);
+ RUNTEST(cm_NormalizeStringTest);
+ RUNTEST(cm_Utf16ToUtf8AllocTest);
+ RUNTEST(cm_Utf16ToUtf8Test);
+ RUNTEST(cm_Utf8ToUtf16AllocTest);
+ RUNTEST(cm_Utf8ToUtf16Test);
+ return 0;
+}
--- /dev/null
+#include<windows.h>
+#include<wchar.h>
+#include<strsafe.h>
+#include "..\cm_nls.h"
+
+typedef struct wtest_pair {
+ const wchar_t * str1;
+ const wchar_t * str2;
+ int comparison_result;
+} wtest_pair;
+
+wtest_pair wtest_pairs[] = {
+ { L"abc", L"aBc", 0 },
+ { L"Abc", L"Acb", -1 },
+ { L"", L"", 0 },
+ { L"", L"", 0 },
+ { L"", L"", 0 },
+ { L"", L"", 0 },
+ { L"", L"", 0 },
+ { L"", L"", 0 },
+};
+
+typedef struct utf8test_pair {
+ const char * str1;
+ const char * str2;
+ int comparison_result;
+} utf8test_pair;
+
+utf8test_pair utf8test_pairs[] = {
+ {"abc", "abc", 0},
+ {"abc", "AbC", 0},
+ {"abc", "ABC", 0},
+ {"ÆOn", "æoN", 0},
+ {"Ǽaaa", "ǽaaa", 0},
+ {"Ằ ", "ằ ", 0},
+ {"Ĺ378", "ĺ378", 0},
+ {"Abc", "Acb", -1},
+ {"ǼaEa", "ǽaaa", 1},
+ {"ùÒz±", "ÙòZ±", 0},
+ {"ÀÁÂÃÄÅÆÇÈÉÊË", "àáâãäåæçèéêë", 0},
+ {"", "", 0},
+ {"", "", 0},
+};
+
+int wmain(int argc, wchar_t ** argv)
+{
+
+ int i;
+
+ printf("Starting test--\n");
+ for (i=0; i<sizeof(utf8test_pairs)/sizeof(utf8test_pairs[0]); i++) {
+ printf("Comparing [%s] and [%s]:", utf8test_pairs[i].str1, utf8test_pairs[i].str2);
+ printf("strcmp=%d, stricmp=%d, cm_stricmp_utf=%d, expected=%d\n",
+ strcmp(utf8test_pairs[i].str1, utf8test_pairs[i].str2),
+ stricmp(utf8test_pairs[i].str1, utf8test_pairs[i].str2),
+ cm_stricmp_utf8(utf8test_pairs[i].str1, utf8test_pairs[i].str2),
+ utf8test_pairs[i].comparison_result);
+ }
+ printf("End of test\n");
+
+ printf("String navigation test\n");
+ {
+ char * str="abcdefghijklДڰ١╚☼ﮓﮚﻂﺧﱞ⅔";
+ /* 1111111111222*/
+ /* 01234567890123456789012 */
+ char * strend;
+ char * p;
+ int i;
+
+ strend = str + strlen(str);
+
+ printf ("Forward direction:\n");
+
+ for (i=0, p=str; *p && p <= strend; p = char_next_utf8(p)) {
+ printf ("Char %d at offset %d\n", i++, p-str);
+ }
+
+ printf ("Reverse direction:\n");
+
+ for (i=23,p=strend; p >= str; p = char_prev_utf8(p)) {
+ printf ("Char %d at offset %d\n", i--, p-str);
+ }
+
+ }
+ printf("End of test\n");
+
+ printf("Strupr test\n");
+ for (i=0; i<sizeof(utf8test_pairs)/sizeof(utf8test_pairs[0]); i++) {
+ char tbuf[MAX_PATH];
+
+ strcpy(tbuf, utf8test_pairs[i].str1);
+ strupr_utf8(tbuf, sizeof(tbuf));
+ printf("Original [%s]->[%s]", utf8test_pairs[i].str1, tbuf);
+
+ strcpy(tbuf, utf8test_pairs[i].str2);
+ strupr_utf8(tbuf, sizeof(tbuf));
+ printf(" [%s]->[%s]\n", utf8test_pairs[i].str2, tbuf);
+ }
+ printf("End of test\n");
+
+ return 0;
+}