eci.c: replace libiconv-adapted code with own implementations so

as to fully comply with BSD license (for why Library GPL 2+ not
  compatible see https://opensource.stackexchange.com/a/6701),
  ~3% slower (maybe), +~6K extra in data
  (gb18030.c, gb2313.c & sjis.c removed, mapping .TXT files moved
  to backend/tools/data & extra ones added, 2 new PHP generators)
GUI: CODE39/EXCODE39: show/hide HIBC check digit option in addition
  to enable/disable (less confusing)
CLI: batch: pedantic check for EOF using intChar in newline fgetc()
  loop
test_args.c: don't use WIFEXITED(), WEXITSTATUS() on Windows
manual: lessen some copy/paste verbiage by referring back, other
  small tweaks/typos
This commit is contained in:
gitlost 2022-06-02 20:32:25 +01:00
parent d9f2e85246
commit ab3cf4f395
69 changed files with 61287 additions and 11905 deletions

View file

@ -1,6 +1,6 @@
/*
libzint - the open source barcode library
Copyright (C) 2021 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2021-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -27,51 +27,120 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
#include "test_big5_tab.h"
#include "../big5.h"
/* For local "private" testing using previous libiconv adaptation, not included for licensing reasons */
//#define TEST_JUST_SAY_GNO
#ifdef TEST_JUST_SAY_GNO
#include "../just_say_gno/big5_gnu.h"
#endif
INTERNAL int u_big5_test(const unsigned int u, unsigned char *dest);
// Version of `u_big5()` taking unsigned int destination for backward-compatible testing
static int u_big5_int(unsigned int u, unsigned int *d) {
unsigned char dest[2];
int ret = u_big5_test(u, dest);
if (ret) {
*d = ret == 1 ? dest[0] : ((dest[0] << 8) | dest[1]);
}
return ret;
}
// As control convert to Big5 using simple table generated from https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT plus simple processing
static int big5_wctomb_zint2(unsigned int *r, unsigned int wc) {
static int u_big5_int2(unsigned int u, unsigned int *dest) {
int tab_length = ARRAY_SIZE(test_big5_tab);
int start_i = test_big5_tab_ind[wc >> 10];
int start_i = test_big5_tab_ind[u >> 10];
int end_i = start_i + 0x800 > tab_length ? tab_length : start_i + 0x800;
int i;
if (wc < 0x80) {
return 0;
if (u < 0x80) {
*dest = u;
return 1;
}
for (i = start_i; i < end_i; i += 2) {
if (test_big5_tab[i + 1] == wc) {
*r = test_big5_tab[i];
return *r > 0xFF ? 2 : 1;
if (test_big5_tab[i + 1] == u) {
*dest = test_big5_tab[i];
return *dest > 0xFF ? 2 : 1;
}
}
return 0;
}
static void test_big5_wctomb_zint(void) {
#include <time.h>
#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC)
#define TEST_PERF_RATIO(a1, a2) (a2 ? TEST_PERF_TIME(a1) / TEST_PERF_TIME(a2) : 0)
#ifdef TEST_JUST_SAY_GNO
#define TEST_INT_PERF_ITERATIONS 100
#endif
static void test_u_big5_int(int debug) {
unsigned int i;
int ret, ret2;
unsigned int val, val2;
testStart("test_big5_wctomb_zint");
#ifdef TEST_JUST_SAY_GNO
int j;
clock_t start;
clock_t total = 0, total_gno = 0;
#else
(void)debug;
#endif
testStart("test_u_big5_int");
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_big5_int perf iterations: %d\n", TEST_INT_PERF_ITERATIONS);
}
#endif
for (i = 0; i < 0xFFFE; i++) {
if (i >= 0xD800 && i < 0xE000) { // UTF-16 surrogates
continue;
}
val = val2 = 0;
ret = big5_wctomb_zint(&val, i);
ret2 = big5_wctomb_zint2(&val2, i);
ret = u_big5_int(i, &val);
ret2 = u_big5_int2(i, &val2);
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
if (ret2) {
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
}
#ifdef TEST_JUST_SAY_GNO
if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
val2 = 0;
ret2 = big5_wctomb_zint(&val2, i);
} else {
for (j = 0; j < TEST_INT_PERF_ITERATIONS; j++) {
val = val2 = 0;
start = clock();
ret = u_big5_int(i, &val);
total += clock() - start;
start = clock();
ret2 = big5_wctomb_zint(&val2, i);
total_gno += clock() - start;
}
}
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
if (ret2) {
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
}
#endif
}
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_big5_int perf totals: new % 8gms, gno % 8gms ratio %g\n",
TEST_PERF_TIME(total), TEST_PERF_TIME(total_gno), TEST_PERF_RATIO(total, total_gno));
}
#endif
testFinish();
}
@ -92,7 +161,7 @@ static int big5_utf8(struct zint_symbol *symbol, const unsigned char source[], i
}
for (i = 0, length = *p_length; i < length; i++) {
if (!big5_wctomb_zint(b5data + i, utfdata[i])) {
if (!u_big5_int(utfdata[i], b5data + i)) {
strcpy(symbol->errtxt, "800: Invalid character in input data");
return ZINT_ERROR_INVALID_DATA;
}
@ -150,7 +219,7 @@ static void test_big5_utf8(int index) {
int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_big5_wctomb_zint", test_big5_wctomb_zint, 0, 0, 0 },
{ "test_u_big5_int", test_u_big5_int, 0, 0, 1 },
{ "test_big5_utf8", test_big5_utf8, 1, 0, 0 },
};
@ -160,3 +229,5 @@ int main(int argc, char *argv[]) {
return 0;
}
/* vim: set ts=4 sw=4 et : */

View file

@ -790,8 +790,11 @@ static void test_utf8_to_eci_utf16be(void) {
/* 7*/ { "\355\277\277", -1, ZINT_ERROR_INVALID_DATA, -1, NULL }, // U+DFFF (edbfbf) surrogate half not allowed
/* 8*/ { "\356\200\200", -1, 0, 2, "\340\000" }, // U+E000 (ee8080)
/* 9*/ { "\360\220\200\200", -1, 0, 4, "\330\000\334\000" }, // U+10000 maps to surrogate pair
/* 10*/ { "\364\217\277\277", -1, 0, 4, "\333\377\337\377" }, // U+10FFFF maps to surrogate pair
/* 11*/ { "\364\220\200\200", -1, ZINT_ERROR_INVALID_DATA, -1, NULL }, // Non-Unicode 0x110000 not allowed
/* 10*/ { "\360\220\217\277", -1, 0, 4, "\330\000\337\377" }, // U+103FF maps to surrogate pair
/* 11*/ { "\364\200\200\200", -1, 0, 4, "\333\300\334\000" }, // U+100000 maps to surrogate pair
/* 12*/ { "\364\217\260\200", -1, 0, 4, "\333\377\334\000" }, // U+10FC00 maps to surrogate pair
/* 13*/ { "\364\217\277\277", -1, 0, 4, "\333\377\337\377" }, // U+10FFFF maps to surrogate pair
/* 14*/ { "\364\220\200\200", -1, ZINT_ERROR_INVALID_DATA, -1, NULL }, // Non-Unicode 0x110000 not allowed
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
@ -848,8 +851,11 @@ static void test_utf8_to_eci_utf16le(void) {
/* 7*/ { "\355\277\277", -1, ZINT_ERROR_INVALID_DATA, -1, NULL }, // U+DFFF (edbfbf) surrogate half not allowed
/* 8*/ { "\356\200\200", -1, 0, 2, "\000\340" }, // U+E000 (ee8080)
/* 9*/ { "\360\220\200\200", -1, 0, 4, "\000\330\000\334" }, // U+10000 maps to surrogate pair
/* 10*/ { "\364\217\277\277", -1, 0, 4, "\377\333\377\337" }, // U+10FFFF maps to surrogate pair
/* 11*/ { "\364\220\200\200", -1, ZINT_ERROR_INVALID_DATA, -1, NULL }, // Non-Unicode 0x110000 not allowed
/* 10*/ { "\360\220\217\277", -1, 0, 4, "\000\330\377\337" }, // U+103FF maps to surrogate pair
/* 11*/ { "\364\200\200\200", -1, 0, 4, "\300\333\000\334" }, // U+100000 maps to surrogate pair
/* 12*/ { "\364\217\260\200", -1, 0, 4, "\377\333\000\334" }, // U+10FC00 maps to surrogate pair
/* 13*/ { "\364\217\277\277", -1, 0, 4, "\377\333\377\337" }, // U+10FFFF maps to surrogate pair
/* 14*/ { "\364\220\200\200", -1, ZINT_ERROR_INVALID_DATA, -1, NULL }, // Non-Unicode 0x110000 not allowed
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;

View file

@ -30,105 +30,123 @@
#include "testcommon.h"
#include "test_gb18030_tab.h"
#include "../gb18030.h"
#include "test_gbk_tab.h"
#include "../eci.h"
/* For local "private" testing using previous libiconv adaptation, not included for licensing reasons */
//#define TEST_JUST_SAY_GNO
#ifdef TEST_JUST_SAY_GNO
#include "../just_say_gno/gb18030_gnu.c"
#include "../just_say_gno/gb2312_gnu.c"
#endif
INTERNAL int u_gb18030_int_test(const unsigned int u, unsigned int *dest1, unsigned int *dest2);
// As control convert to GB 18030 using table generated from GB18030.TXT plus simple processing.
// The version of GB18030.TXT is libiconv-1.11/GB18030.TXT taken from https://haible.de/bruno/charsets/conversion-tables/GB18030.html
// The generated file backend/tests/test_gb18030_tab.h does not include U+10000..10FFFF codepoints to save space.
// See also backend/tests/tools/data/GB18030.TXT.README and backend/tests/tools/gen_test_tab.php.
static int gb18030_wctomb_zint2(unsigned int *r1, unsigned int *r2, unsigned int wc) {
static int u_gb18030_int2(unsigned int u, unsigned int *dest1, unsigned int *dest2) {
unsigned int c;
int tab_length, start_i, end_i;
int i;
// GB18030 two-byte extension (libiconv-1.16/lib/gb18030ext.h)
if (wc == 0x1E3F) { // GB 18030-2005 change, was PUA U+E7C7 below, see Table 3-39, p.111, Lunde 2nd ed.
*r1 = 0xA8BC;
if (u == 0x1E3F) { // GB 18030-2005 change, was PUA U+E7C7 below, see Table 3-39, p.111, Lunde 2nd ed.
*dest1 = 0xA8BC;
return 2;
}
// GB18030 four-byte extension (libiconv-1.16/lib/gb18030uni.h)
if (wc == 0xE7C7) { // PUA
*r1 = 0x8135;
*r2 = 0xF437;
if (u == 0xE7C7) { // PUA
*dest1 = 0x8135;
*dest2 = 0xF437;
return 4;
}
// GB18030 two-byte extension (libiconv-1.16/lib/gb18030ext.h)
if (wc >= 0x9FB4 && wc <= 0x9FBB) { // GB 18030-2005 change, were PUA, see Table 3-37, p.108, Lunde 2nd ed.
if (wc == 0x9FB4) {
*r1 = 0xFE59;
} else if (wc == 0x9FB5) {
*r1 = 0xFE61;
} else if (wc == 0x9FB6 || wc == 0x9FB7) {
*r1 = 0xFE66 + (wc - 0x9FB6);
} else if (wc == 0x9FB8) {
*r1 = 0xFE6D;
} else if (wc == 0x9FB9) {
*r1 = 0xFE7E;
} else if (wc == 0x9FBA) {
*r1 = 0xFE90;
if (u >= 0x9FB4 && u <= 0x9FBB) { // GB 18030-2005 change, were PUA, see Table 3-37, p.108, Lunde 2nd ed.
if (u == 0x9FB4) {
*dest1 = 0xFE59;
} else if (u == 0x9FB5) {
*dest1 = 0xFE61;
} else if (u == 0x9FB6 || u == 0x9FB7) {
*dest1 = 0xFE66 + (u - 0x9FB6);
} else if (u == 0x9FB8) {
*dest1 = 0xFE6D;
} else if (u == 0x9FB9) {
*dest1 = 0xFE7E;
} else if (u == 0x9FBA) {
*dest1 = 0xFE90;
} else {
*r1 = 0xFEA0;
*dest1 = 0xFEA0;
}
return 2;
}
// GB18030 two-byte extension (libiconv-1.16/lib/gb18030ext.h)
if (wc >= 0xFE10 && wc <= 0xFE19) { // GB 18030-2005 change, were PUA, see Table 3-37, p.108, Lunde 2nd ed.
if (wc == 0xFE10) {
*r1 = 0xA6D9;
} else if (wc == 0xFE11) {
*r1 = 0xA6DB;
} else if (wc == 0xFE12) {
*r1 = 0xA6DA;
} else if (wc >= 0xFE13 && wc <= 0xFE16) {
*r1 = 0xA6DC + (wc - 0xFE13);
} else if (wc == 0xFE17 || wc == 0xFE18) {
*r1 = 0xA6EC + (wc - 0xFE17);
if (u >= 0xFE10 && u <= 0xFE19) { // GB 18030-2005 change, were PUA, see Table 3-37, p.108, Lunde 2nd ed.
if (u == 0xFE10) {
*dest1 = 0xA6D9;
} else if (u == 0xFE11) {
*dest1 = 0xA6DB;
} else if (u == 0xFE12) {
*dest1 = 0xA6DA;
} else if (u >= 0xFE13 && u <= 0xFE16) {
*dest1 = 0xA6DC + (u - 0xFE13);
} else if (u == 0xFE17 || u == 0xFE18) {
*dest1 = 0xA6EC + (u - 0xFE17);
} else {
*r1 = 0xA6F3;
*dest1 = 0xA6F3;
}
return 2;
}
// GB18030 four-byte extension (libiconv-1.16/lib/gb18030uni.h)
if (wc >= 0xFE1A && wc <= 0xFE2F) { // These are Vertical Forms (U+FE1A..FE1F unassigned) and Combining Half Marks (U+FE20..FE2F)
if (wc >= 0xFE1A && wc <= 0xFE1D) {
c = 0x84318336 + (wc - 0xFE1A);
} else if (wc >= 0xFE1E && wc <= 0xFE27) {
c = 0x84318430 + (wc - 0xFE1E);
if (u >= 0xFE1A && u <= 0xFE2F) { // These are Vertical Forms (U+FE1A..FE1F unassigned) and Combining Half Marks (U+FE20..FE2F)
if (u >= 0xFE1A && u <= 0xFE1D) {
c = 0x84318336 + (u - 0xFE1A);
} else if (u >= 0xFE1E && u <= 0xFE27) {
c = 0x84318430 + (u - 0xFE1E);
} else {
c = 0x84318530 + (wc - 0xFE28);
c = 0x84318530 + (u - 0xFE28);
}
*r1 = c >> 16;
*r2 = c & 0xFFFF;
*dest1 = c >> 16;
*dest2 = c & 0xFFFF;
return 4;
}
// GB18030 (libiconv-1.16/lib/gb18030.h)
// Code set 3 (Unicode U+10000..U+10FFFF)
if (wc >= 0x10000 /*&& wc < 0x10400*/) { // Not being called for U+10400..U+10FFFF
c = wc - 0x10000;
*r1 = 0x9030;
*r2 = 0x8130 + (c % 10) + 0x100 * (c / 10);
if (u >= 0x10000 /*&& u < 0x10400*/) { // Not being called for U+10400..U+10FFFF
c = u - 0x10000;
*dest1 = 0x9030;
*dest2 = 0x8130 + (c % 10) + 0x100 * (c / 10);
return 4;
}
tab_length = ARRAY_SIZE(test_gb18030_tab);
start_i = test_gb18030_tab_ind[wc >> 10];
start_i = test_gb18030_tab_ind[u >> 10];
end_i = start_i + 0x800 > tab_length ? tab_length : start_i + 0x800;
for (i = start_i; i < end_i; i += 2) {
if (test_gb18030_tab[i + 1] == wc) {
if (test_gb18030_tab[i + 1] == u) {
c = test_gb18030_tab[i];
if (c <= 0xFFFF) {
*r1 = c;
*dest1 = c;
return c <= 0xFF ? 1 : 2;
}
*r1 = c >> 16;
*r2 = c & 0xFFFF;
*dest1 = c >> 16;
*dest2 = c & 0xFFFF;
return 4;
}
}
return 0;
}
static void test_gb18030_wctomb_zint(void) {
#include <time.h>
#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC)
#define TEST_PERF_RATIO(a1, a2) (a2 ? TEST_PERF_TIME(a1) / TEST_PERF_TIME(a2) : 0)
#ifdef TEST_JUST_SAY_GNO
#define TEST_INT_PERF_ITERATIONS 250
#endif
static void test_u_gb18030_int(int debug) {
int ret, ret2;
unsigned int val1_1, val1_2, val2_1, val2_2;
@ -141,34 +159,80 @@ static void test_gb18030_wctomb_zint(void) {
0xFE51, 0xFE52, 0xFE53, 0xFE6C, 0xFE76, 0xFE91
};
testStart("test_gb18030_wctomb_zint");
#ifdef TEST_JUST_SAY_GNO
int j;
clock_t start;
clock_t total = 0, total_gno = 0;
#else
(void)debug;
#endif
testStart("test_u_gb18030_int");
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_gb18030_int perf iterations: %d\n", TEST_INT_PERF_ITERATIONS);
}
#endif
for (i = 0; i < 0x10400; i++) { // Don't bother with U+10400..U+10FFFF, programmatically filled
if (i >= 0xD800 && i <= 0xDFFF) { // UTF-16 surrogates
continue;
}
val1_1 = val1_2 = val2_1 = val2_2 = 0;
ret = gb18030_wctomb_zint(&val1_1, &val1_2, i);
ret2 = gb18030_wctomb_zint2(&val2_1, &val2_2, i);
ret = u_gb18030_int_test(i, &val1_1, &val1_2);
ret2 = u_gb18030_int2(i, &val2_1, &val2_2);
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val1_1 0x%04X, val2_1 0x%04X, val1_2 0x%04X, val2_2 0x%04X\n", (int) i, i, ret, ret2, val1_1, val2_1, val1_2, val2_2);
if (ret2) {
assert_equal(val1_1, val2_1, "i:%d 0x%04X val1_1 0x%04X != val2_1 0x%04X\n", (int) i, i, val1_1, val2_1);
assert_equal(val1_2, val2_2, "i:%d 0x%04X val1_2 0x%04X != val2_2 0x%04X\n", (int) i, i, val1_2, val2_2);
}
#ifdef TEST_JUST_SAY_GNO
if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
val2_1 = val2_2 = 0;
ret2 = gb18030_wctomb_zint(&val2_1, &val2_2, i);
} else {
for (j = 0; j < TEST_INT_PERF_ITERATIONS; j++) {
val1_1 = val1_2 = val2_1 = val2_2 = 0;
start = clock();
ret = u_gb18030_int_test(i, &val1_1, &val1_2);
total += clock() - start;
start = clock();
ret2 = gb18030_wctomb_zint(&val2_1, &val2_2, i);
total_gno += clock() - start;
}
}
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val1_1 0x%04X, val2_1 0x%04X, val1_2 0x%04X, val2_2 0x%04X\n", (int) i, i, ret, ret2, val1_1, val2_1, val1_2, val2_2);
if (ret2) {
assert_equal(val1_1, val2_1, "i:%d 0x%04X val1_1 0x%04X != val2_1 0x%04X\n", (int) i, i, val1_1, val2_1);
assert_equal(val1_2, val2_2, "i:%d 0x%04X val1_2 0x%04X != val2_2 0x%04X\n", (int) i, i, val1_2, val2_2);
}
#endif
}
// u_gb18030() assumes valid Unicode so now returns a nonsense value here
val1_1 = val1_2 = 0;
ret = gb18030_wctomb_zint(&val1_1, &val1_2, 0x110000); /* Invalid Unicode codepoint */
assert_zero(ret, "0x110000 ret %d != 0, val1_1 0x%04X, val1_2 0x%04X\n", ret, val1_1, val1_2);
ret = u_gb18030_int_test(0x110000, &val1_1, &val1_2); /* Invalid Unicode codepoint */
assert_equal(ret, 4, "0x110000 ret %d != 4, val1_1 0x%04X, val1_2 0x%04X\n", ret, val1_1, val1_2);
for (i = 0; i < ARRAY_SIZE(nonpua_nonbmp); i++) {
val1_1 = val1_2 = 0;
ret = gb18030_wctomb_zint(&val1_1, &val1_2, nonpua_nonbmp[i]);
ret = u_gb18030_int_test(nonpua_nonbmp[i], &val1_1, &val1_2);
assert_equal(ret, 2, "i:%d 0x%04X ret %d != 2, val1_1 0x%04X, val1_2 0x%04X\n", (int) i, nonpua_nonbmp[i], ret, val1_1, val1_2);
assert_equal(val1_1, nonpua_nonbmp_vals[i], "i:%d 0x%04X val1_1 0x%04X != 0x%04X\n", (int) i, nonpua_nonbmp[i], val1_1, nonpua_nonbmp_vals[i]);
assert_zero(val1_2, "i:%d 0x%04X val1_2 0x%04X != 0\n", (int) i, nonpua_nonbmp[i], val1_2);
}
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_gb18030_int perf totals: new % 8gms, gno % 8gms ratio %g\n",
TEST_PERF_TIME(total), TEST_PERF_TIME(total_gno), TEST_PERF_RATIO(total, total_gno));
}
#endif
testFinish();
}
@ -350,6 +414,9 @@ static void test_gb18030_utf8_to_eci(int index) {
testFinish();
}
INTERNAL void gb18030_cpy_test(const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte);
static void test_gb18030_cpy(int index) {
struct item {
@ -390,7 +457,7 @@ static void test_gb18030_cpy(int index) {
length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length;
ret_length = length;
gb18030_cpy((unsigned char *) data[i].data, &ret_length, gbdata, data[i].full_multibyte);
gb18030_cpy_test((unsigned char *) data[i].data, &ret_length, gbdata, data[i].full_multibyte);
assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %d != %d\n", i, ret_length, data[i].ret_length);
for (j = 0; j < (int) ret_length; j++) {
assert_equal(gbdata[j], data[i].expected_gbdata[j], "i:%d gbdata[%d] %04X != %04X\n", i, j, gbdata[j], data[i].expected_gbdata[j]);
@ -400,35 +467,22 @@ static void test_gb18030_cpy(int index) {
testFinish();
}
/* For testing GBK, to exclude GB 18030 extensions */
STATIC_UNLESS_ZINT_TEST int gb18030ext_wctomb(unsigned int *r, const unsigned int wc);
STATIC_UNLESS_ZINT_TEST int gb18030uni_wctomb(unsigned int *r1, unsigned int *r2, const unsigned int wc);
INTERNAL int u_gbk_int_test(const unsigned int u, unsigned int *dest);
/* Control for GBK */
static int gbk_wctomb_zint2(unsigned int *r, unsigned int wc) {
static int u_gbk_int2(unsigned int u, unsigned int *dest) {
unsigned int c;
int tab_length, start_i, end_i;
int i;
unsigned int r1, r2;
if (gb18030ext_wctomb(&r1, wc)) {
return 0;
}
if (wc >= 0xe000 && wc <= 0xe864) {
return 0;
}
if (gb18030uni_wctomb(&r1, &r2, wc)) {
return 0;
}
tab_length = ARRAY_SIZE(test_gb18030_tab);
start_i = test_gb18030_tab_ind[wc >> 10];
tab_length = ARRAY_SIZE(test_gbk_tab);
start_i = test_gbk_tab_ind[u >> 10];
end_i = start_i + 0x800 > tab_length ? tab_length : start_i + 0x800;
for (i = start_i; i < end_i; i += 2) {
if (test_gb18030_tab[i + 1] == wc) {
c = test_gb18030_tab[i];
if (test_gbk_tab[i + 1] == u) {
c = test_gbk_tab[i];
if (c <= 0xFFFF) {
*r = c;
*dest = c;
return c <= 0xFF ? 1 : 2;
}
return 0;
@ -437,24 +491,21 @@ static int gbk_wctomb_zint2(unsigned int *r, unsigned int wc) {
return 0;
}
static void test_gbk_wctomb_zint(void) {
static void test_u_gbk_int(void) {
int ret, ret2;
unsigned int val, val2;
unsigned int i;
testStart("test_gbk_wctomb_zint");
testStart("test_u_gbk_int");
for (i = 0; i < 0xFFFE; i++) {
if (i < 0x80) { // ASCII is straight through and not dealt with by gbk_wctomb_zint()
continue;
}
if (i >= 0xD800 && i <= 0xDFFF) { // UTF-16 surrogates
continue;
}
val = val2 = 0;
ret = gbk_wctomb_zint(&val, i);
ret2 = gbk_wctomb_zint2(&val2, i);
ret = u_gbk_int_test(i, &val);
ret2 = u_gbk_int2(i, &val2);
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
if (ret2) {
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
@ -464,14 +515,102 @@ static void test_gbk_wctomb_zint(void) {
testFinish();
}
#define TEST_PERF_ITER_MILLES 50
#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000)
// Not a real test, just performance indicator
static void test_perf(int index, int debug) {
struct item {
char *data;
int ret;
char *comment;
};
struct item data[] = {
/* 0*/ { "1234567890", 0, "10 numerics" },
/* 1*/ { "条码北京條碼པེ་ཅིང།バーコード바코드", 0, "Small various code pages" },
/* 2*/ { "Summer Palace Ticket for 6 June 2015 13:00;2015年6月6日夜01時00分PM頤和園のチケット;2015년6월6일13시오후여름궁전티켓.2015年6月6号下午13:00的颐和园门票;", 0, "Small mixed ASCII/Hanzi" },
/* 3*/ { "汉信码标准\015\012中国物品编码中心\015\012北京网路畅想科技发展有限公司\015\012张成海、赵楠、黄燕滨、罗秋科、王毅、张铎、王越\015\012施煜、边峥、修兴强\015\012汉信码标准\015\012中国物品编码中心\015\012北京网路畅想科技发展有限公司", 0, "Bigger mixed" },
/* 4*/ { "本标准规定了一种矩阵式二维条码——汉信码的码制以及编译码方法。本标准中对汉信码的码图方案、信息编码方法、纠错编译码算法、信息排布方法、参考译码算法等内容进行了详细的描述汉信码可高效表示《GB 18030—2000 信息技术 信息交换用汉字编码字符集基本集的扩充》中的汉字信息,并具有数据容量大、抗畸变和抗污损能力强、外观美观等特点,适合于在我国各行业的广泛应用。 测试文本测试人施煜边峥修兴强袁娲测试目的汉字表示测试版本40\015\012", 0, "Bigger mixed" },
/* 5*/ { "本标准规定了一种矩阵式二维条码——汉信码的码制以及编译码方法。本标准中对汉信码的码图方案、信息编码方法、纠错编译码算法、信息排布方法、参考译码算法等内容进行了详细的描述汉信码可高效表示《GB 18030—2000 信息技术 信息交换用汉字编码字符集基本集的扩充》中的汉字信息,并具有数据容量大、抗畸变和抗污损能力强、外观美观等特点,适合于在我国各行业的广泛应用。 测试文本测试人施煜边峥修兴强袁娲测试目的汉字表示测试版本40\015\012本标准规定了一种矩阵式二维条码——汉信码的码制以及编译码方法。本标准中对汉信码的码图方案、信息编码方法、纠错编译码算法、信息排布方法、参考译码算法等内容进行了详细的描述汉信码可高效表示《GB 18030—2000 信息技术 信息交换用汉字编码字符集基本集的扩充》中的汉字信息,并具有数据容量大、抗畸变和抗污损能力强、外观美观等特点,适合于在我国各行业的广泛应用。 测试文本测试人施煜边峥修兴强袁娲测试目的汉字表示测试版本40\015\012本标准规定了一种矩阵式二维条码——汉信码的码制以及编译码方法。本标准中对汉信码的码图方案、信息编码方法、纠错编译码算法RS、信息排布方法、参考译码算法等内容进行了详细的描述汉信码可高效表示《GB 18030—2000 信息技术 122", 0, "Medium mixed" },
/* 6*/ { "本标准规定了一种矩阵式二维条码——汉信码的码制以及编译码方法。本标准中对汉信码的码图方案、信息编码方法、纠错编译码算法、信息排布方法、参考译码算法等内容进行了详细的描述汉信码可高效表示《GB 18030—2000 信息技术 信息交换用汉字编码字符集基本集的扩充》中的汉字信息,并具有数据容量大、抗畸变和抗污损能力强、外观美观等特点,适合于在我国各行业的广泛应用。 测试文本测试人施煜边峥修兴强袁娲测试目的汉字表示测试版本84\015\012本标准规定了一种矩阵式二维条码——汉信码的码制以及编译码方法。本标准中对汉信码的码图方案、信息编码方法、纠错编译码算法、信息排布方法、参考译码算法等内容进行了详细的描述汉信码可高效表示《GB 18030—2000 信息技术 信息交换用汉字编码字符集基本集的扩充》中的汉字信息,并具有数据容量大、抗畸变和抗污损能力强、外观美观等特点,适合于在我国各行业的广泛应用。 测试文本测试人施煜边峥修兴强袁娲测试目的汉字表示测试版本84\015\012本标准规定了一种矩阵式二维条码——汉信码的码制以及编译码方法。本标准中对汉信码的码图方案、信息编码方法、纠错编译码算法、信息排布方法、参考译码算法等内容进行了详细的描述汉信码可高效表示《GB 18030—2000 信息技术 信息交换用汉字编码字符集基本集的扩充》中的汉字信息,并具有数据容量大、抗畸变和抗污损能力强、外观美观等特点,适合于在我国各行业的广泛应用。 测试文本测试人施煜边峥修兴强袁娲测试目的汉字表示测试版本40本标准规定了一种矩阵式二维条码——汉信码的码制以及编译码方法。本标准中对汉信码的码图方", 0, "Bigger mixed" },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
struct zint_symbol symbol = {0};
int ret_length, ret_length2;
unsigned int ddata[8192];
unsigned char dest[8192];
int ret2 = 0;
#ifdef TEST_JUST_SAY_GNO
unsigned int ddata2[8192];
#endif
clock_t start;
clock_t total = 0, total_gno = 0, total_eci = 0;
clock_t diff, diff_gno, diff_eci;
int comment_max = 0;
if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
return;
}
for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment);
printf("Iterations %d\n", TEST_PERF_ITERATIONS);
for (i = 0; i < data_size; i++) {
int j;
if (index != -1 && i != index) continue;
length = (int) strlen(data[i].data);
diff = diff_gno = diff_eci = 0;
for (j = 0; j < TEST_PERF_ITERATIONS; j++) {
ret_length = ret_length2 = length;
start = clock();
ret = gb18030_utf8(&symbol, (unsigned char *) data[i].data, &ret_length, ddata);
diff += clock() - start;
#ifdef TEST_JUST_SAY_GNO
start = clock();
ret2 = gb18030_utf8_wctomb(&symbol, (unsigned char *) data[i].data, &ret_length2, ddata2);
diff_gno += clock() - start;
#endif
ret_length = length;
start = clock();
(void)utf8_to_eci(32, (unsigned char *) data[i].data, dest, &ret_length);
diff_eci += clock() - start;
}
assert_equal(ret, ret2, "i:%d ret %d != ret2 %d\n", (int) i, ret, ret2);
printf("%*s: new % 8gms, gno % 8gms ratio % 9g, eci %gms\n", comment_max, data[i].comment,
TEST_PERF_TIME(diff), TEST_PERF_TIME(diff_gno), TEST_PERF_RATIO(diff, diff_gno), TEST_PERF_TIME(diff_eci));
total += diff;
total_gno += diff_gno;
}
if (index == -1) {
printf("%*s: new % 8gms, gno % 8gms ratio % 9g, eci %gms\n", comment_max, "totals",
TEST_PERF_TIME(total), TEST_PERF_TIME(total_gno), TEST_PERF_RATIO(total, total_gno), TEST_PERF_TIME(total_eci));
}
}
int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_gb18030_wctomb_zint", test_gb18030_wctomb_zint, 0, 0, 0 },
{ "test_u_gb18030_int", test_u_gb18030_int, 0, 0, 1 },
{ "test_gb18030_utf8", test_gb18030_utf8, 1, 0, 0 },
{ "test_gb18030_utf8_to_eci", test_gb18030_utf8_to_eci, 1, 0, 0 },
{ "test_gb18030_cpy", test_gb18030_cpy, 1, 0, 0 },
{ "test_gbk_wctomb_zint", test_gbk_wctomb_zint, 0, 0, 0 },
{ "test_u_gbk_int", test_u_gbk_int, 0, 0, 0 },
{ "test_perf", test_perf, 1, 0, 1 },
};
testRun(argc, argv, funcs, ARRAY_SIZE(funcs));

View file

@ -1,6 +1,6 @@
/*
libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -27,68 +27,121 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
#include "test_gb2312_tab.h"
#include "../gb2312.h"
#include "../eci.h"
/* For local "private" testing using previous libiconv adaptation, not included for licensing reasons */
//#define TEST_JUST_SAY_GNO
#ifdef TEST_JUST_SAY_GNO
#include "../just_say_gno/gb2312_gnu.c"
#endif
INTERNAL int u_gb2312_int_test(const unsigned int u, unsigned int *d);
// As control convert to GB 2312 using simple table generated from unicode.org GB2312.TXT plus simple processing
// GB2312.TXT no longer on unicode.org site but available from https://haible.de/bruno/charsets/conversion-tables/GB2312.html
static int gb2312_wctomb_zint2(unsigned int *r, unsigned int wc) {
static int u_gb2312_int2(unsigned int u, unsigned int *d) {
int tab_length, start_i, end_i;
int i;
if (u < 0x80) {
*d = (unsigned char) u;
return 1;
}
// Shortcut
if ((wc > 0x0451 && wc < 0x2015) || (wc > 0x3229 && wc < 0x4E00) || (wc > 0x9FA0 && wc < 0xFF01) || wc > 0xFFE5) {
if ((u > 0x0451 && u < 0x2015) || (u > 0x3229 && u < 0x4E00) || (u > 0x9FA0 && u < 0xFF01) || u > 0xFFE5) {
return 0;
}
tab_length = ARRAY_SIZE(test_gb2312_tab);
start_i = test_gb2312_tab_ind[wc >> 10];
start_i = test_gb2312_tab_ind[u >> 10];
end_i = start_i + 0x800 > tab_length ? tab_length : start_i + 0x800;
for (i = start_i; i < end_i; i += 2) {
if (test_gb2312_tab[i + 1] == wc) {
*r = test_gb2312_tab[i] + 0x8080; // Table in GB 2312 not EUC-CN
if (test_gb2312_tab[i + 1] == u) {
*d = test_gb2312_tab[i] + 0x8080; // Table in GB 2312 not EUC-CN
return 2;
}
}
return 0;
}
static void test_gb2312_wctomb_zint(void) {
#include <time.h>
#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC)
#define TEST_PERF_RATIO(a1, a2) (a2 ? TEST_PERF_TIME(a1) / TEST_PERF_TIME(a2) : 0)
#ifdef TEST_JUST_SAY_GNO
#define TEST_INT_PERF_ITERATIONS 250
#endif
static void test_u_gb2312_int(int debug) {
int ret, ret2;
unsigned int val, val2;
unsigned int i;
testStart("test_gb2312_wctomb_zint");
#ifdef TEST_JUST_SAY_GNO
int j;
clock_t start;
clock_t total = 0, total_gno = 0;
#else
(void)debug;
#endif
testStart("test_u_gb2312_int");
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_gb2312_int perf iterations: %d\n", TEST_INT_PERF_ITERATIONS);
}
#endif
for (i = 0; i < 0xFFFE; i++) {
if (i < 0x80) { // ASCII is straight through and not dealt with by gb2312_wctomb_zint()
continue;
}
if (i >= 0xD800 && i <= 0xDFFF) { // UTF-16 surrogates
continue;
}
val = val2 = 0;
ret = gb2312_wctomb_zint(&val, i);
ret2 = gb2312_wctomb_zint2(&val2, i);
if (i == 0xB7) { // Extra mapping middle dot U+00B7 to 0xA1A4, duplicate of U+30FB (Katakana middle dot)
assert_equal(ret, 2, "i:%d 0x%04X ret %d != 2, val 0x%04X\n", (int) i, i, ret, val);
assert_equal(val, 0xA1A4, "i:%d 0x%04X val 0x%04X != 0xA1A4\n", (int) i, i, val);
assert_zero(ret2, "i:%d 0x%04X ret2 %d != 0, val2 0x%04X\n", (int) i, i, ret2, val2);
} else if (i == 0x2014) { // Extra mapping em dash U+2014 to 0xA1AA, duplicate of U+2015 (horizontal bar)
assert_equal(ret, 2, "i:%d 0x%04X ret %d != 2, val 0x%04X\n", (int) i, i, ret, val);
assert_equal(val, 0xA1AA, "i:%d 0x%04X val 0x%04X != 0xA1AA\n", (int) i, i, val);
assert_zero(ret2, "i:%d 0x%04X ret2 %d != 0, val2 0x%04X\n", (int) i, i, ret2, val2);
} else {
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
}
ret = u_gb2312_int_test(i, &val);
ret2 = u_gb2312_int2(i, &val2);
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
if (ret2) {
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
}
#ifdef TEST_JUST_SAY_GNO
// `gb2312_wctomb_zint()` doesn't handle ASCII; and ignore duplicate mappings, no longer done
if (i >= 0x80 && i != 0xB7 && i != 0x2014) {
if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
val2 = 0;
ret2 = gb2312_wctomb_zint(&val2, i);
} else {
for (j = 0; j < TEST_INT_PERF_ITERATIONS; j++) {
val = val2 = 0;
start = clock();
ret = u_gb2312_int_test(i, &val);
total += clock() - start;
start = clock();
ret2 = gb2312_wctomb_zint(&val2, i);
total_gno += clock() - start;
}
}
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
if (ret2) {
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
}
}
#endif
}
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_gb2312_int perf totals: new % 8gms, gno % 8gms ratio %g\n",
TEST_PERF_TIME(total), TEST_PERF_TIME(total_gno), TEST_PERF_RATIO(total, total_gno));
}
#endif
testFinish();
}
@ -117,11 +170,12 @@ static void test_gb2312_utf8(int index) {
/* 2*/ { "¤", -1, 0, 1, { 0xA1E8 }, "" },
/* 3*/ { "¥", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "" },
/* 4*/ { "", -1, 0, 1, { 0xA1A4 }, "GB2312.TXT mapping" },
/* 5*/ { "·", -1, 0, 1, { 0xA1A4 }, "GB 18030 subset mapping" },
/* 5*/ { "·", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "No longer does GB 18030 subset mapping" },
/* 6*/ { "", -1, 0, 1, { 0xA1AA }, "GB2312.TXT mapping" },
/* 7*/ { "", -1, 0, 1, { 0xA1AA }, "GB 18030 subset mapping" },
/* 8*/ { "aβc・·—é—Z", -1, 0, 9, { 'a', 0xA6C2, 'c', 0xA1A4, 0xA1A4, 0xA1AA, 0xA8A6, 0xA1AA, 'Z' }, "" },
/* 9*/ { "\200", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "Invalid UTF-8" },
/* 7*/ { "", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "No longer does GB 18030 subset mapping" },
/* 8*/ { "aβc・―é―Z", -1, 0, 8, { 'a', 0xA6C2, 'c', 0xA1A4, 0xA1AA, 0xA8A6, 0xA1AA, 'Z' }, "" },
/* 9*/ { "aβc・·—é—Z", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "No longer does GB 18030 mappings" },
/* 10*/ { "\200", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "Invalid UTF-8" },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
@ -253,6 +307,9 @@ static void test_gb2312_utf8_to_eci(int index) {
testFinish();
}
INTERNAL void gb2312_cpy_test(const unsigned char source[], int *p_length, unsigned int *ddata,
const int full_multibyte);
static void test_gb2312_cpy(int index) {
struct item {
@ -293,7 +350,7 @@ static void test_gb2312_cpy(int index) {
length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length;
ret_length = length;
gb2312_cpy((unsigned char *) data[i].data, &ret_length, gbdata, data[i].full_multibyte);
gb2312_cpy_test((unsigned char *) data[i].data, &ret_length, gbdata, data[i].full_multibyte);
assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %d != %d\n", i, ret_length, data[i].ret_length);
for (j = 0; j < (int) ret_length; j++) {
assert_equal(gbdata[j], data[i].expected_gbdata[j], "i:%d gbdata[%d] %04X != %04X\n", i, j, gbdata[j], data[i].expected_gbdata[j]);
@ -303,13 +360,110 @@ static void test_gb2312_cpy(int index) {
testFinish();
}
#define TEST_PERF_ITER_MILLES 100
#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000)
// Not a real test, just performance indicator
static void test_perf(int index, int debug) {
struct item {
char *data;
int ret;
char *comment;
};
struct item data[] = {
/* 0*/ { "1234567890", 0, "10 numerics" },
/* 1*/ { "条码北京條碼པེ་ཅིང།バーコード바코드", 0, "Small various code pages" },
/* 2*/ { "Summer Palace Ticket for 6 June 2015 13:00;2015年6月6日夜01時00分PM頤和園のチケット;2015년6월6일13시오후여름궁전티켓.2015年6月6号下午13:00的颐和园门票;", 0, "Small mixed ASCII/Hanzi" },
/* 3*/ { "汉信码标准\015\012中国物品编码中心\015\012北京网路畅想科技发展有限公司\015\012张成海、赵楠、黄燕滨、罗秋科、王毅、张铎、王越\015\012施煜、边峥、修兴强\015\012汉信码标准\015\012中国物品编码中心\015\012北京网路畅想科技发展有限公司", 0, "Bigger mixed" },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
struct zint_symbol symbol = {0};
int ret_length, ret_length2;
unsigned int ddata[8192];
unsigned char dest[8192];
int ret2 = 0;
#ifdef TEST_JUST_SAY_GNO
unsigned int ddata2[8192];
unsigned char dest2[8192];
#endif
clock_t start;
clock_t total = 0, total_gno = 0, total_eci = 0, total_eci_gno = 0;
clock_t diff, diff_gno, diff_eci, diff_eci_gno;
int comment_max = 0;
if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
return;
}
for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment);
printf("Iterations %d\n", TEST_PERF_ITERATIONS);
for (i = 0; i < data_size; i++) {
int j;
if (index != -1 && i != index) continue;
length = (int) strlen(data[i].data);
diff = diff_gno = diff_eci = diff_eci_gno = 0;
for (j = 0; j < TEST_PERF_ITERATIONS; j++) {
ret_length = ret_length2 = length;
start = clock();
ret = gb2312_utf8(&symbol, (unsigned char *) data[i].data, &ret_length, ddata);
diff += clock() - start;
#ifdef TEST_JUST_SAY_GNO
start = clock();
ret2 = gb2312_utf8_wctomb(&symbol, (unsigned char *) data[i].data, &ret_length2, ddata2);
diff_gno += clock() - start;
#endif
ret_length = ret_length2 = length;
start = clock();
(void)utf8_to_eci(29, (unsigned char *) data[i].data, dest, &ret_length);
diff_eci += clock() - start;
#ifdef TEST_JUST_SAY_GNO
start = clock();
(void)utf8_to_eci_wctomb(29, (unsigned char *) data[i].data, dest2, &ret_length2);
diff_eci_gno += clock() - start;
#endif
}
assert_equal(ret, ret2, "i:%d ret %d != ret2 %d\n", (int) i, ret, ret2);
printf("%*s: new % 8gms, gno % 8gms ratio % 9g | eci % 8gms, gno % 8gms ratio %g\n", comment_max, data[i].comment,
TEST_PERF_TIME(diff), TEST_PERF_TIME(diff_gno), TEST_PERF_RATIO(diff, diff_gno),
TEST_PERF_TIME(diff_eci), TEST_PERF_TIME(diff_eci_gno), TEST_PERF_RATIO(diff_eci, diff_eci_gno));
total += diff;
total_gno += diff_gno;
total_eci += diff_eci;
total_eci_gno += diff_eci_gno;
}
if (index == -1) {
printf("%*s: new % 8gms, gno % 8gms ratio % 9g | eci % 8gms, gno % 8gms ratio %g\n", comment_max, "totals",
TEST_PERF_TIME(total), TEST_PERF_TIME(total_gno), TEST_PERF_RATIO(total, total_gno),
TEST_PERF_TIME(total_eci), TEST_PERF_TIME(total_eci_gno), TEST_PERF_RATIO(total_eci, total_eci_gno));
}
}
int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_gb2312_wctomb_zint", test_gb2312_wctomb_zint, 0, 0, 0 },
{ "test_u_gb2312_int", test_u_gb2312_int, 0, 0, 1 },
{ "test_gb2312_utf8", test_gb2312_utf8, 1, 0, 0 },
{ "test_gb2312_utf8_to_eci", test_gb2312_utf8_to_eci, 1, 0, 0 },
{ "test_gb2312_cpy", test_gb2312_cpy, 1, 0, 0 },
{ "test_perf", test_perf, 1, 0, 1 },
};
testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
@ -318,3 +472,5 @@ int main(int argc, char *argv[]) {
return 0;
}
/* vim: set ts=4 sw=4 et : */

21989
backend/tests/test_gbk_tab.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/*
libzint - the open source barcode library
Copyright (C) 2021 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2021-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -27,72 +27,146 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
#include "test_ksx1001_tab.h"
#include "../ksx1001.h"
/* For local "private" testing using previous libiconv adaptation, not included for licensing reasons */
//#define TEST_JUST_SAY_GNO
#ifdef TEST_JUST_SAY_GNO
#include "../just_say_gno/ksx1001_gnu.h"
#endif
// As control convert to KS X 1001 using simple table generated from https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/KSC/KSX1001.TXT plus simple processing
static int ksx1001_wctomb_zint2(unsigned int *r, unsigned int wc) {
INTERNAL int u_ksx1001_test(const unsigned int u, unsigned char *dest);
// Version of `u_ksx1001()` taking unsigned int destination for backward-compatible testing
static int u_ksx1001_int(const unsigned int u, unsigned int *d) {
unsigned char dest[2];
int ret = u_ksx1001_test(u, dest);
if (ret) {
*d = ret == 1 ? dest[0] : ((dest[0] << 8) | dest[1]);
}
return ret;
}
// As control convert to KS X 1001 using simple table generated from
// https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/KSC/KSX1001.TXT plus simple processing
static int u_ksx1001_int2(unsigned int u, unsigned int *dest) {
int tab_length, start_i, end_i;
int i;
if (wc < 0x80) {
return 0;
if (u < 0x80) {
*dest = u;
return 1;
}
if (wc == 0x20AC) { // Euro sign added KS X 1001:1998
*r = 0x2266;
if (u == 0x20AC) { // Euro sign added KS X 1001:1998
*dest = 0x2266 + 0x8080;
return 2;
}
if (wc == 0xAE) { // Registered trademark added KS X 1001:1998
*r = 0x2267;
if (u == 0xAE) { // Registered trademark added KS X 1001:1998
*dest = 0x2267 + 0x8080;
return 2;
}
if (wc == 0x327E) { // Korean postal code symbol added KS X 1001:2002
*r = 0x2268;
if (u == 0x327E) { // Korean postal code symbol added KS X 1001:2002
*dest = 0x2268 + 0x8080;
return 2;
}
tab_length = ARRAY_SIZE(test_ksx1001_tab);
start_i = test_ksx1001_tab_ind[wc >> 10];
start_i = test_ksx1001_tab_ind[u >> 10];
end_i = start_i + 0x800 > tab_length ? tab_length : start_i + 0x800;
for (i = start_i; i < end_i; i += 2) {
if (test_ksx1001_tab[i + 1] == wc) {
*r = test_ksx1001_tab[i];
return *r > 0xFF ? 2 : 1;
if (test_ksx1001_tab[i + 1] == u) {
*dest = test_ksx1001_tab[i] + 0x8080;
return 2;
}
}
return 0;
}
static void test_ksx1001_wctomb_zint(void) {
#include <time.h>
#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC)
#define TEST_PERF_RATIO(a1, a2) (a2 ? TEST_PERF_TIME(a1) / TEST_PERF_TIME(a2) : 0)
#ifdef TEST_JUST_SAY_GNO
#define TEST_INT_PERF_ITERATIONS 100
#endif
static void test_u_ksx1001_int(int debug) {
int ret, ret2;
unsigned int val, val2;
unsigned i;
testStart("test_ksx1001_wctomb_zint");
#ifdef TEST_JUST_SAY_GNO
int j;
clock_t start;
clock_t total = 0, total_gno = 0;
#else
(void)debug;
#endif
testStart("test_u_ksx1001_int");
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_ksx1001_int perf iterations: %d\n", TEST_INT_PERF_ITERATIONS);
}
#endif
for (i = 0; i < 0xFFFE; i++) {
if (i >= 0xD800 && i <= 0xDFFF) { // UTF-16 surrogates
continue;
}
val = val2 = 0;
ret = ksx1001_wctomb_zint(&val, i);
ret2 = ksx1001_wctomb_zint2(&val2, i);
ret = u_ksx1001_int(i, &val);
ret2 = u_ksx1001_int2(i, &val2);
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
if (ret2) {
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
}
#ifdef TEST_JUST_SAY_GNO
if (i >= 0x80) { // `ksx1001_wctomb_zint()` doesn't handle ASCII
if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
val2 = 0;
ret2 = ksx1001_wctomb_zint(&val2, i);
} else {
for (j = 0; j < TEST_INT_PERF_ITERATIONS; j++) {
val = val2 = 0;
start = clock();
ret = u_ksx1001_int(i, &val);
total += clock() - start;
start = clock();
ret2 = ksx1001_wctomb_zint(&val2, i);
total_gno += clock() - start;
}
}
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
if (ret2) {
val2 += 0x8080; // `ksx1001_wctomb_zint()` returns pure KS X 1001 values, convert to EUC-KR
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
}
}
#endif
}
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_ksx1001_int perf totals: new % 8gms, gno % 8gms ratio %g\n",
TEST_PERF_TIME(total), TEST_PERF_TIME(total_gno), TEST_PERF_RATIO(total, total_gno));
}
#endif
testFinish();
}
int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_ksx1001_wctomb_zint", test_ksx1001_wctomb_zint, 0, 0, 0 },
{ "test_u_ksx1001_int", test_u_ksx1001_int, 0, 0, 1 },
};
testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
@ -101,3 +175,5 @@ int main(int argc, char *argv[]) {
return 0;
}
/* vim: set ts=4 sw=4 et : */

View file

@ -1,6 +1,6 @@
/*
libzint - the open source barcode library
Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -27,87 +27,142 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
#include "test_sjis_tab.h"
#include "../sjis.h"
#include "../eci.h"
/* For local "private" testing using previous libiconv adaptation, not included for licensing reasons */
//#define TEST_JUST_SAY_GNO
#ifdef TEST_JUST_SAY_GNO
#include "../just_say_gno/sjis_gnu.c"
#endif
INTERNAL int u_sjis_int_test(const unsigned int u, unsigned int *dest);
// As control convert to Shift JIS using simple table generated from https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT plus simple processing
static int sjis_wctomb_zint2(unsigned int *r, unsigned int wc) {
static int u_sjis_int2(unsigned int u, unsigned int *dest) {
int tab_length, start_i, end_i;
int i;
if (wc < 0x20 || wc == 0x7F) {
*r = wc;
if (u < 0x20 || u == 0x7F) {
*dest = u;
return 1;
}
// Shortcut
if ((wc > 0x00F7 && wc < 0x0391) || (wc > 0x0451 && wc < 0x2010) || (wc > 0x9FA0 && wc < 0xE000) || (wc > 0xE757 && wc < 0xFF01) || wc > 0xFFE5) {
if ((u > 0x00F7 && u < 0x0391) || (u > 0x0451 && u < 0x2010) || (u > 0x9FA0 && u < 0xE000) || (u > 0xE757 && u < 0xFF01) || u > 0xFFE5) {
return 0;
}
if (wc >= 0xE000 && wc <= 0xE757) { // PUA mappings, not in SHIFTJIS.TXT
if (wc <= 0xE0BB) {
*r = wc - 0xE000 + 0xF040 + (wc >= 0xE000 + 0x3F);
} else if (wc <= 0xE177) {
*r = wc - 0xE0BC + 0xF140 + (wc >= 0xE0BC + 0x3F);
} else if (wc <= 0xE233) {
*r = wc - 0xE178 + 0xF240 + (wc >= 0xE178 + 0x3F);
} else if (wc <= 0xE2EF) {
*r = wc - 0xE234 + 0xF340 + (wc >= 0xE234 + 0x3F);
} else if (wc <= 0xE3AB) {
*r = wc - 0xE2F0 + 0xF440 + (wc >= 0xE2F0 + 0x3F);
} else if (wc <= 0xE467) {
*r = wc - 0xE3AC + 0xF540 + (wc >= 0xE3AC + 0x3F);
} else if (wc <= 0xE523) {
*r = wc - 0xE468 + 0xF640 + (wc >= 0xE468 + 0x3F);
} else if (wc <= 0xE5DF) {
*r = wc - 0xE524 + 0xF740 + (wc >= 0xE524 + 0x3F);
} else if (wc <= 0xE69B) {
*r = wc - 0xE5E0 + 0xF840 + (wc >= 0xE5E0 + 0x3F);
if (u >= 0xE000 && u <= 0xE757) { // PUA mappings, not in SHIFTJIS.TXT
if (u <= 0xE0BB) {
*dest = u - 0xE000 + 0xF040 + (u >= 0xE000 + 0x3F);
} else if (u <= 0xE177) {
*dest = u - 0xE0BC + 0xF140 + (u >= 0xE0BC + 0x3F);
} else if (u <= 0xE233) {
*dest = u - 0xE178 + 0xF240 + (u >= 0xE178 + 0x3F);
} else if (u <= 0xE2EF) {
*dest = u - 0xE234 + 0xF340 + (u >= 0xE234 + 0x3F);
} else if (u <= 0xE3AB) {
*dest = u - 0xE2F0 + 0xF440 + (u >= 0xE2F0 + 0x3F);
} else if (u <= 0xE467) {
*dest = u - 0xE3AC + 0xF540 + (u >= 0xE3AC + 0x3F);
} else if (u <= 0xE523) {
*dest = u - 0xE468 + 0xF640 + (u >= 0xE468 + 0x3F);
} else if (u <= 0xE5DF) {
*dest = u - 0xE524 + 0xF740 + (u >= 0xE524 + 0x3F);
} else if (u <= 0xE69B) {
*dest = u - 0xE5E0 + 0xF840 + (u >= 0xE5E0 + 0x3F);
} else {
*r = wc - 0xE69C + 0xF940 + (wc >= 0xE69C + 0x3F);
*dest = u - 0xE69C + 0xF940 + (u >= 0xE69C + 0x3F);
}
return 2;
}
tab_length = sizeof(test_sjis_tab) / sizeof(unsigned int);
start_i = test_sjis_tab_ind[wc >> 10];
start_i = test_sjis_tab_ind[u >> 10];
end_i = start_i + 0x800 > tab_length ? tab_length : start_i + 0x800;
for (i = start_i; i < end_i; i += 2) {
if (test_sjis_tab[i + 1] == wc) {
*r = test_sjis_tab[i];
return *r > 0xFF ? 2 : 1;
if (test_sjis_tab[i + 1] == u) {
*dest = test_sjis_tab[i];
return *dest > 0xFF ? 2 : 1;
}
}
return 0;
}
static void test_sjis_wctomb_zint(void) {
#include <time.h>
#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC)
#define TEST_PERF_RATIO(a1, a2) (a2 ? TEST_PERF_TIME(a1) / TEST_PERF_TIME(a2) : 0)
#ifdef TEST_JUST_SAY_GNO
#define TEST_INT_PERF_ITERATIONS 100
#endif
static void test_u_sjis_int(int debug) {
int ret, ret2;
unsigned int val, val2;
unsigned int i;
testStart("test_sjis_wctomb_zint");
#ifdef TEST_JUST_SAY_GNO
int j;
clock_t start;
clock_t total = 0, total_gno = 0;
#else
(void)debug;
#endif
testStart("test_u_sjis_int");
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_sjis_int perf iterations: %d\n", TEST_INT_PERF_ITERATIONS);
}
#endif
for (i = 0; i < 0xFFFE; i++) {
if (i >= 0xD800 && i <= 0xDFFF) { // UTF-16 surrogates
continue;
}
val = val2 = 0;
ret = sjis_wctomb_zint(&val, i);
ret2 = sjis_wctomb_zint2(&val2, i);
if (i == 0xFF3C) { // Extra mapping full-width reverse solidus U+FF3C to 0x815F, duplicate of U+005C (backslash)
assert_equal(ret, 2, "i:%d 0x%04X ret %d != 2, val 0x%04X\n", (int) i, i, ret, val);
assert_equal(val, 0x815F, "i:%d 0x%04X val 0x%04X != 0x815F\n", (int) i, i, val);
assert_zero(ret2, "i:%d 0x%04X ret2 %d != 0, val2 0x%04X\n", (int) i, i, ret2, val2);
} else {
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
}
ret = u_sjis_int_test(i, &val);
ret2 = u_sjis_int2(i, &val2);
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
if (ret2) {
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
}
#ifdef TEST_JUST_SAY_GNO
if (i != 0xFF3C) { // Full-width reverse solidus duplicate no longer mapped to ignore
if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
val2 = 0;
ret2 = sjis_wctomb_zint(&val2, i);
} else {
for (j = 0; j < TEST_INT_PERF_ITERATIONS; j++) {
val = val2 = 0;
start = clock();
ret = u_sjis_int_test(i, &val);
total += clock() - start;
start = clock();
ret2 = sjis_wctomb_zint(&val2, i);
total_gno += clock() - start;
}
}
assert_equal(ret, ret2, "i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X\n", (int) i, i, ret, ret2, val, val2);
if (ret2) {
assert_equal(val, val2, "i:%d 0x%04X val 0x%04X != val2 0x%04X\n", (int) i, i, val, val2);
}
}
#endif
}
#ifdef TEST_JUST_SAY_GNO
if ((debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
printf("test_u_sjis_int perf totals: new % 8gms, gno % 8gms ratio %g\n",
TEST_PERF_TIME(total), TEST_PERF_TIME(total_gno), TEST_PERF_RATIO(total, total_gno));
}
#endif
testFinish();
}
@ -128,7 +183,7 @@ static void test_sjis_utf8(int index) {
// ・ U+FF65 half-width katakana, not in ISO/Win, in Shift JIS single-byte 0xA5 (\245), UTF-8 EFBDA5
// ソ U+FF7F half-width katakana, not in ISO/Win, in Shift JIS single-byte 0xBF (\277), UTF-8 EFBDBF
// ‾ U+203E overline, not in ISO/Win, in Shift JIS single-byte 0x7E (\176) (tilde), UTF-8 E280BE
// U+FF3C full-width reverse solidus, in Shift JIS 0x815F, duplicate of mapping of U+005C, UTF-8 EFBCBC
// U+FF3C full-width reverse solidus, in Shift JIS 0x815F, was duplicate of mapping of U+005C, UTF-8 EFBCBC
// 点 U+70B9 kanji, in Shift JIS 0x935F (\223\137), UTF-8 E782B9
// 茗 U+8317 kanji, in Shift JIS 0xE4AA (\344\252), UTF-8 E88C97
// テ U+30C6 katakana, in Shift JIS 0x8365 (\203\145), UTF-8 E38386
@ -138,8 +193,9 @@ static void test_sjis_utf8(int index) {
/* 1*/ { "~", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "" },
/* 2*/ { "β", -1, 0, 1, { 0x83C0 }, "" },
/* 3*/ { "¥", -1, 0, 1, { 0x5C }, "" },
/* 4*/ { "aβcЖ¥・ソ‾\\\点茗テ", -1, 0, 13, { 'a', 0x83C0, 'c', 0x8447, 0x5C, 0xA5, 0xBF, 0x7E, 0x815F, 0x815F, 0x935F, 0xE4AA, 0x8365 }, "" },
/* 5*/ { "\200", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "Invalid UTF-8" },
/* 4*/ { "aβcЖ¥・ソ‾\\点茗テ", -1, 0, 12, { 'a', 0x83C0, 'c', 0x8447, 0x5C, 0xA5, 0xBF, 0x7E, 0x815F, 0x935F, 0xE4AA, 0x8365 }, "" },
/* 5*/ { "", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "U+FF3C full-width reverse solidus no longer duplicate mapping of U+005C" },
/* 6*/ { "\200", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "Invalid UTF-8" },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
@ -310,13 +366,93 @@ static void test_sjis_cpy(int index) {
testFinish();
}
#define TEST_PERF_ITER_MILLES 100
#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000)
// Not a real test, just performance indicator
static void test_perf(int index, int debug) {
struct item {
char *data;
int ret;
char *comment;
};
struct item data[] = {
/* 0*/ { "1234567890", 0, "10 numerics" },
/* 1*/ { "貫やぐ識禁ぱい再2間変字全レ没無8裁", 0, "Small mixed" },
/* 2*/ { "貫やぐ識禁ぱい再2間変字全レ没無8裁花ほゃ過法ひなご札17能つーびれ投覧マ勝動エヨ額界よみ作皇ナヲニ打題ヌルヲ掲布益フが。入35能ト権話しこを断兆モヘ細情おじ名4減エヘイハ側機はょが意見想ハ業独案ユヲウ患職ヲ平美さ毎放どぽたけ家没べお化富べ町大シ情魚ッでれ一冬すぼめり。", 0, "Bigger mixed" },
/* 3*/ { "貫やぐ識禁ぱい再2間変字全レ没無8裁花ほゃ過法ひなご札17能つーびれ投覧マ勝動エヨ額界よみ作皇ナヲニ打題ヌルヲ掲布益フが。入35能ト権話しこを断兆モヘ細情おじ名4減エヘイハ側機はょが意見想ハ業独案ユヲウ患職ヲ平美さ毎放どぽたけ家没べお化富べ町大シ情魚ッでれ一冬すぼめり。社ト可化モマ試音ばじご育青康演ぴぎ権型固スで能麩ぜらもほ河都しちほラ収90作の年要とだむ部動ま者断チ第41一1米索焦茂げむしれ。測フ物使だて目月国スリカハ夏検にいへ児72告物ゆは載核ロアメヱ登輸どべゃ催行アフエハ議歌ワ河倫剖だ。記タケウ因載ヒイホヤ禁3輩彦関トえび肝区勝ワリロ成禁ぼよ界白ウヒキレ中島べせぜい各安うしぽリ覧生テ基一でむしゃ中新トヒキソ声碁スしび起田ア信大未ゅもばち。", 0, "Bigger mixed" },
/* 4*/ { "点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点点", 0, "784 kanji" },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
struct zint_symbol symbol = {0};
int ret_length, ret_length2;
unsigned int ddata[8192];
int ret2 = 0;
#ifdef TEST_JUST_SAY_GNO
unsigned int ddata2[8192];
#endif
clock_t start;
clock_t total = 0, total_gno = 0;
clock_t diff, diff_gno;
int comment_max = 0;
if (!(debug & ZINT_DEBUG_TEST_PERFORMANCE)) { /* -d 256 */
return;
}
for (i = 0; i < data_size; i++) if ((int) strlen(data[i].comment) > comment_max) comment_max = (int) strlen(data[i].comment);
printf("Iterations %d\n", TEST_PERF_ITERATIONS);
for (i = 0; i < data_size; i++) {
int j;
if (index != -1 && i != index) continue;
length = (int) strlen(data[i].data);
diff = diff_gno = 0;
for (j = 0; j < TEST_PERF_ITERATIONS; j++) {
ret_length = ret_length2 = length;
start = clock();
ret = sjis_utf8(&symbol, (unsigned char *) data[i].data, &ret_length, ddata);
diff += clock() - start;
#ifdef TEST_JUST_SAY_GNO
start = clock();
ret2 = sjis_utf8_wctomb(&symbol, (unsigned char *) data[i].data, &ret_length2, ddata2);
diff_gno += clock() - start;
#endif
}
assert_equal(ret, ret2, "i:%d ret %d != ret2 %d\n", (int) i, ret, ret2);
printf("%*s: new % 8gms, gno % 8gms ratio %g\n", comment_max, data[i].comment,
TEST_PERF_TIME(diff), TEST_PERF_TIME(diff_gno), TEST_PERF_RATIO(diff, diff_gno));
total += diff;
total_gno += diff_gno;
}
if (index == -1) {
printf("%*s: new % 8gms, gno % 8gms ratio %g\n", comment_max, "totals",
TEST_PERF_TIME(total), TEST_PERF_TIME(total_gno), TEST_PERF_RATIO(total, total_gno));
}
}
int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_sjis_wctomb_zint", test_sjis_wctomb_zint, 0, 0, 0 },
{ "test_u_sjis_int", test_u_sjis_int, 0, 0, 1 },
{ "test_sjis_utf8", test_sjis_utf8, 1, 0, 0 },
{ "test_sjis_utf8_to_eci", test_sjis_utf8_to_eci, 1, 0, 0 },
{ "test_sjis_cpy", test_sjis_cpy, 1, 0, 0 },
{ "test_perf", test_perf, 1, 0, 1 },
};
testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
@ -325,3 +461,5 @@ int main(int argc, char *argv[]) {
return 0;
}
/* vim: set ts=4 sw=4 et : */

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
# GB18030.TXT not included as 21MB in size. It can be downloaded from
# https://haible.de/bruno/charsets/conversion-tables/GB18030.html
# The version used is libiconv-1.11/GB18030.TXT

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -2,38 +2,41 @@
/* Generate lookup table from unicode.org mapping file (SHIFTJIS.TXT by default). */
/*
libzint - the open source barcode library
Copyright (C) 2019-2021 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2019-2022 Robin Stuart <rstuart114@gmail.com>
*/
/* To create backend/tests/test_sjis_tab.h (from backend/tests/build directory):
/* To create backend/tests/test_sjis_tab.h (from the project root directory):
*
* php ../tools/gen_test_tab.php
* php backend/tests/tools/gen_test_tab.php
*
* To create backend/tests/test_gb2312_tab.h;
*
* php ../tools/gen_test_tab.php -f GB2312.TXT -s gb2312_tab
* php backend/tests/tools/gen_test_tab.php -f GB2312.TXT -s gb2312_tab
*
* To create backend/tests/test_gbk.h;
*
* php backend/tests/tools/gen_test_tab.php -f CP936.TXT -s gbk_tab
*
* To create backend/tests/test_gb18030_tab.h (note that backend/tests/tools/data/GB18030.TXT
* will have to be downloaded first from https://haible.de/bruno/charsets/conversion-tables/GB18030.html
* using the version libiconv-1.11/GB18030.TXT):
* using the version jdk-1.4.2/GB18030.TXT):
*
* php ../tools/gen_test_tab.php -f GB18030.TXT -s gb18030_tab
* php backend/tests/tools/gen_test_tab.php -f GB18030.TXT -s gb18030_tab
*
* To create backend/tests/test_big5_tab.h;
*
* php ../tools/gen_test_tab.php -f BIG5.TXT -s big5_tab
* php backend/tests/tools/gen_test_tab.php -f BIG5.TXT -s big5_tab
*
* To create backend/tests/test_ksx1001_tab.h;
*
* php ../tools/gen_test_tab.php -f KSX1001.TXT -s ksx1001_tab
* php backend/tests/tools/gen_test_tab.php -f KSX1001.TXT -s ksx1001_tab
*
*/
/* vim: set ts=4 sw=4 et : */
$basename = basename(__FILE__);
$dirname = dirname(__FILE__);
$opts = getopt('d:f:o:s:');
$data_dirname = isset($opts['d']) ? $opts['d'] : ($dirname . '/data'); // Where to load file from.
$data_dirname = isset($opts['d']) ? $opts['d'] : ($dirname . '/../../tools/data'); // Where to load file from.
$file_name = isset($opts['f']) ? $opts['f'] : 'SHIFTJIS.TXT'; // Name of file.
$out_dirname = isset($opts['o']) ? $opts['o'] : ($dirname . '/..'); // Where to put output.
$suffix_name = isset($opts['s']) ? $opts['s'] : 'sjis_tab'; // Suffix of table and output file.
@ -93,3 +96,5 @@ foreach ($sort as $ind => $unicode) {
$out[] = '};';
file_put_contents($out_dirname . '/test_' . $suffix_name . '.h', implode("\n", $out) . "\n");
/* vim: set ts=4 sw=4 et : */