Performance improvements for linear encoding and raster output

- use fixed-length string tables (mostly) instead of (char *) pointer ones
   (saves ~40K)
 - re-use C128Table for CODABLOCKF and CODE16K
   (required removal of Stop character and extra CODE16K-only entry)
 - use pointer to destination and copy (memcpy/strcpy(), bin_append_posn())
   instead of concatenating (strcat()) (mostly)
 - replace last remaining bin_append()s with bin_append_posn();
   bin_append() removed
 - add length arg to toupper() and expand() (avoids strlen())
 - change is_sane() to use table-based flags (avoids an iteration)
 - rename lookup() to is_sane_lookup() and change to check and return posns
   and use in pointer to destination loops (avoids strcat()s)
 - remove special case PHARMA in expand() (dealt with in pharma())
 - make #define SILVER/CALCIUM/TECHNETIUM/KRSET etc static strings
 - replace strchr() -> posn()
 - CODE128: populate destination once in checksum loop; re-use and export
   some more routines (c128_set_a/b/c(), c128_put_in_set()) for sharing;
   prefix defines (SHIFTA -> C128_SHIFTA etc) and existing exported routines
 - use factor XOR toggle trick in checksum calcs (avoids branch)
 - raster.c: fill out single 1-pixel row and copy using new draw_bar_line(),
   copy_bar_line() routines; similarly in buffer_plot compare previous line &
   copy if same (same technique as used to improve non-half-integer scaling,
   significant performance increase, (c) codemonkey82);
   also done for PNG (BMP/GIF/PCX/TIFF not done)
 - raster/vector/output.c: shorten "output_" prefix -> "out_";
   sync vector to other raster changes to try to keep source files similar
 - 2of5.c: prefix "c25_"
JAPANPOST: return error if input data truncated (backward incompatible)
DAFT: max chars 50 -> 100
common.c: istwodigit() -> is_twodigit()
common.c/emf.c/output.c: use some further stripf()s (MSVC6 float variations)
library.c: new check_output_args() helper
zint.h: add BARCODE_LAST marker and use in library.c
QRCODE: remove a NOLINT (requires clang-tidy-13), one remaining
CMake: separate no-optimize from ZINT_DEBUG into new ZINT_NOOPT option
This commit is contained in:
gitlost 2021-10-20 23:05:30 +01:00
parent e8b59aa696
commit fab7435fac
72 changed files with 3501 additions and 2380 deletions

View file

@ -266,150 +266,154 @@ static void test_upca_input(int index, int debug) {
testFinish();
}
static void test_eanx_input(int index, int debug) {
static void test_eanx_input(int index, int generate, int debug) {
struct item {
int symbology;
char *data;
int ret;
char *ret_errtxt;
char *comment;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { BARCODE_EANX, "123456789012", 0 },
/* 1*/ { BARCODE_EANX, "12345678901A", ZINT_ERROR_INVALID_DATA },
/* 2*/ { BARCODE_EANX, "12345678901", 0 },
/* 3*/ { BARCODE_EANX, "1234567890128", 0 }, // EANX accepts CHK (treated as such if no leading zeroes required)
/* 4*/ { BARCODE_EANX, "1234567890120", ZINT_ERROR_INVALID_CHECK },
/* 5*/ { BARCODE_EANX, "123456789012+1", 0 },
/* 6*/ { BARCODE_EANX, "1234567890128+1", 0 },
/* 7*/ { BARCODE_EANX, "1234567890121+1", ZINT_ERROR_INVALID_CHECK },
/* 8*/ { BARCODE_EANX, "123456789012+12", 0 },
/* 9*/ { BARCODE_EANX, "1234567890128+12", 0 },
/* 10*/ { BARCODE_EANX, "1234567890122+12", ZINT_ERROR_INVALID_CHECK },
/* 11*/ { BARCODE_EANX, "12345678901234+12", ZINT_ERROR_TOO_LONG },
/* 12*/ { BARCODE_EANX, "123456789012345+12", ZINT_ERROR_TOO_LONG },
/* 13*/ { BARCODE_EANX, "1234567890123456+12", ZINT_ERROR_TOO_LONG },
/* 14*/ { BARCODE_EANX, "123456789012+123", 0 },
/* 15*/ { BARCODE_EANX, "1234567890128+123", 0 },
/* 16*/ { BARCODE_EANX, "1234567890123+123", ZINT_ERROR_INVALID_CHECK },
/* 17*/ { BARCODE_EANX, "12345678901234+123", ZINT_ERROR_TOO_LONG },
/* 18*/ { BARCODE_EANX, "123456789012345+123", ZINT_ERROR_TOO_LONG },
/* 19*/ { BARCODE_EANX, "123456789012+1234", 0 },
/* 20*/ { BARCODE_EANX, "1234567890128+1234", 0 },
/* 21*/ { BARCODE_EANX, "1234567890124+1234", ZINT_ERROR_INVALID_CHECK },
/* 22*/ { BARCODE_EANX, "12345678901234+1234", ZINT_ERROR_TOO_LONG },
/* 23*/ { BARCODE_EANX, "123456789012+12345", 0 },
/* 24*/ { BARCODE_EANX, "1234567890128+12345", 0 },
/* 25*/ { BARCODE_EANX, "12345678901234+12345", ZINT_ERROR_TOO_LONG },
/* 26*/ { BARCODE_EANX, "1234567890125+12345", ZINT_ERROR_INVALID_CHECK },
/* 27*/ { BARCODE_EANX, "123456789012+123456", ZINT_ERROR_TOO_LONG },
/* 28*/ { BARCODE_EANX, "1234567890128+123456", ZINT_ERROR_TOO_LONG },
/* 29*/ { BARCODE_EANX, "12345678901+123456", ZINT_ERROR_TOO_LONG },
/* 30*/ { BARCODE_EANX, "12345678901+1234567", ZINT_ERROR_TOO_LONG },
/* 31*/ { BARCODE_EANX, "1234567890+123456", ZINT_ERROR_TOO_LONG },
/* 32*/ { BARCODE_EANX, "1234567890+1234567", ZINT_ERROR_TOO_LONG },
/* 33*/ { BARCODE_EANX, "123456789+123456", ZINT_ERROR_TOO_LONG },
/* 34*/ { BARCODE_EANX, "123456789+1234567", ZINT_ERROR_TOO_LONG },
/* 35*/ { BARCODE_EANX, "12345678+123456", ZINT_ERROR_TOO_LONG },
/* 36*/ { BARCODE_EANX, "1234567+123456", ZINT_ERROR_TOO_LONG }, // EAN-8
/* 37*/ { BARCODE_EANX, "123456+123456", ZINT_ERROR_TOO_LONG },
/* 38*/ { BARCODE_EANX, "12345+123456", ZINT_ERROR_TOO_LONG },
/* 39*/ { BARCODE_EANX, "1234+123456", ZINT_ERROR_TOO_LONG },
/* 40*/ { BARCODE_EANX, "123+123456", ZINT_ERROR_TOO_LONG },
/* 41*/ { BARCODE_EANX, "12+123456", ZINT_ERROR_TOO_LONG },
/* 42*/ { BARCODE_EANX, "1+123456", ZINT_ERROR_TOO_LONG },
/* 43*/ { BARCODE_EANX, "1+12345678901234", ZINT_ERROR_TOO_LONG },
/* 44*/ { BARCODE_EANX, "1+12345", 0 },
/* 45*/ { BARCODE_EANX, "1+", 0 }, // EAN-2
/* 46*/ { BARCODE_EANX, "+1", 0 }, // EAN-8
/* 47*/ { BARCODE_EANX, "+", 0 }, // EAN-2
/* 48*/ { BARCODE_EANX, "1", 0 }, // EAN-2
/* 49*/ { BARCODE_EANX, "12", 0 }, // EAN-2
/* 50*/ { BARCODE_EANX, "123", 0 }, // EAN-5
/* 51*/ { BARCODE_EANX, "12345678901234", ZINT_ERROR_TOO_LONG },
/* 52*/ { BARCODE_EANX, "1234567890123A", ZINT_ERROR_INVALID_DATA },
/* 53*/ { BARCODE_EANX, "123456789012345", ZINT_ERROR_TOO_LONG },
/* 54*/ { BARCODE_EANX, "12345678901234A", ZINT_ERROR_INVALID_DATA },
/* 55*/ { BARCODE_EANX, "1234567890123456", ZINT_ERROR_TOO_LONG },
/* 56*/ { BARCODE_EANX, "12345678901234567", ZINT_ERROR_TOO_LONG },
/* 57*/ { BARCODE_EANX, "123456789012345678", ZINT_ERROR_TOO_LONG },
/* 58*/ { BARCODE_EANX, "1234567890123456789", ZINT_ERROR_TOO_LONG },
/* 59*/ { BARCODE_EANX_CHK, "1234567890128", 0 },
/* 60*/ { BARCODE_EANX_CHK, "1234567890126", ZINT_ERROR_INVALID_CHECK },
/* 61*/ { BARCODE_EANX_CHK, "123456789012A", ZINT_ERROR_INVALID_DATA },
/* 62*/ { BARCODE_EANX_CHK, "123456789012", 0 }, // Note: this is "0123456789012" with '2' happening to be the correct check digit
/* 63*/ { BARCODE_EANX_CHK, "123456789013", ZINT_ERROR_INVALID_CHECK },
/* 64*/ { BARCODE_EANX_CHK, "12345678901", ZINT_ERROR_INVALID_CHECK },
/* 65*/ { BARCODE_EANX_CHK, "12345678905", 0 },
/* 66*/ { BARCODE_EANX_CHK, "1234567890", ZINT_ERROR_INVALID_CHECK },
/* 67*/ { BARCODE_EANX_CHK, "123456789", ZINT_ERROR_INVALID_CHECK },
/* 68*/ { BARCODE_EANX_CHK, "12345678", ZINT_ERROR_INVALID_CHECK }, // EAN-8
/* 69*/ { BARCODE_EANX_CHK, "1234567", ZINT_ERROR_INVALID_CHECK },
/* 70*/ { BARCODE_EANX_CHK, "123456", ZINT_ERROR_INVALID_CHECK },
/* 71*/ { BARCODE_EANX_CHK, "12345", 0 }, // EAN-5
/* 72*/ { BARCODE_EANX_CHK, "1234", 0 },
/* 73*/ { BARCODE_EANX_CHK, "123", 0 },
/* 74*/ { BARCODE_EANX_CHK, "12", 0 }, // EAN-2
/* 75*/ { BARCODE_EANX_CHK, "1", 0 },
/* 76*/ { BARCODE_EANX_CHK, "123456789012+1", 0 },
/* 77*/ { BARCODE_EANX_CHK, "1234567890128+1", 0 },
/* 78*/ { BARCODE_EANX_CHK, "1234567890127+1", ZINT_ERROR_INVALID_CHECK },
/* 79*/ { BARCODE_EANX_CHK, "123456789012+12", 0 },
/* 80*/ { BARCODE_EANX_CHK, "1234567890128+12", 0 },
/* 81*/ { BARCODE_EANX_CHK, "1234567890129+12", ZINT_ERROR_INVALID_CHECK },
/* 82*/ { BARCODE_EANX_CHK, "123456789012+123", 0 },
/* 83*/ { BARCODE_EANX_CHK, "1234567890128+123", 0 },
/* 84*/ { BARCODE_EANX_CHK, "1234567890120+1234", ZINT_ERROR_INVALID_CHECK },
/* 85*/ { BARCODE_EANX_CHK, "123456789012+1234", 0 },
/* 86*/ { BARCODE_EANX_CHK, "1234567890128+1234", 0 },
/* 87*/ { BARCODE_EANX_CHK, "1234567890121+1234", ZINT_ERROR_INVALID_CHECK },
/* 88*/ { BARCODE_EANX_CHK, "123456789012+12345", 0 },
/* 89*/ { BARCODE_EANX_CHK, "1234567890128+12345", 0 },
/* 90*/ { BARCODE_EANX_CHK, "1234567890122+12345", ZINT_ERROR_INVALID_CHECK },
/* 91*/ { BARCODE_EANX_CHK, "1234567890122+1234A", ZINT_ERROR_INVALID_DATA },
/* 92*/ { BARCODE_EANX_CHK, "123456789012+123456", ZINT_ERROR_TOO_LONG },
/* 93*/ { BARCODE_EANX_CHK, "123456789012+12345A", ZINT_ERROR_INVALID_DATA },
/* 94*/ { BARCODE_EANX_CHK, "1234567890128+123456", ZINT_ERROR_TOO_LONG },
/* 95*/ { BARCODE_EANX_CHK, "12345678901+123456", ZINT_ERROR_TOO_LONG },
/* 96*/ { BARCODE_EANX_CHK, "12345678901+1234567", ZINT_ERROR_TOO_LONG },
/* 97*/ { BARCODE_EANX_CHK, "12345678901+12345", ZINT_ERROR_INVALID_CHECK },
/* 98*/ { BARCODE_EANX_CHK, "1234567890+12345", ZINT_ERROR_INVALID_CHECK },
/* 99*/ { BARCODE_EANX_CHK, "1234567890+123456", ZINT_ERROR_TOO_LONG },
/*100*/ { BARCODE_EANX_CHK, "123456789+12345", ZINT_ERROR_INVALID_CHECK },
/*101*/ { BARCODE_EANX_CHK, "12345678+12345", ZINT_ERROR_INVALID_CHECK }, // EAN-8
/*102*/ { BARCODE_EANX_CHK, "12345670+12345", 0 },
/*103*/ { BARCODE_EANX_CHK, "1234567+12345", ZINT_ERROR_INVALID_CHECK },
/*104*/ { BARCODE_EANX_CHK, "1234565+12345", 0 },
/*105*/ { BARCODE_EANX_CHK, "123456+12345", ZINT_ERROR_INVALID_CHECK },
/*106*/ { BARCODE_EANX_CHK, "123457+12345", 0 },
/*107*/ { BARCODE_EANX_CHK, "12345+12345", ZINT_ERROR_INVALID_CHECK },
/*108*/ { BARCODE_EANX_CHK, "12348+12345", 0 },
/*109*/ { BARCODE_EANX_CHK, "1234+12345", ZINT_ERROR_INVALID_CHECK },
/*110*/ { BARCODE_EANX_CHK, "1236+12345", 0 },
/*111*/ { BARCODE_EANX_CHK, "123+12345", 0 }, // 3 happens to be correct check digit
/*112*/ { BARCODE_EANX_CHK, "124+12345", ZINT_ERROR_INVALID_CHECK },
/*113*/ { BARCODE_EANX_CHK, "12+12345", ZINT_ERROR_INVALID_CHECK },
/*114*/ { BARCODE_EANX_CHK, "17+12345", 0 },
/*115*/ { BARCODE_EANX_CHK, "1+12345", ZINT_ERROR_INVALID_CHECK },
/*116*/ { BARCODE_EANX_CHK, "0+12345", 0 },
/*117*/ { BARCODE_EANX_CHK, "0+123456", ZINT_ERROR_TOO_LONG },
/*118*/ { BARCODE_EANX_CHK, "1+12345678901234", ZINT_ERROR_TOO_LONG },
/*119*/ { BARCODE_EANX_CHK, "0+12345678901234", ZINT_ERROR_TOO_LONG },
/*120*/ { BARCODE_EANX_CHK, "1+", 0 }, // EAN-2
/*121*/ { BARCODE_EANX_CHK, "+1", 0 }, // EAN-8
/*122*/ { BARCODE_EANX_CHK, "+", 0 }, // EAN-2
/*123*/ { BARCODE_EANX_CHK, "12345678901234", ZINT_ERROR_TOO_LONG },
/*124*/ { BARCODE_EANX_CHK, "1234567890123A", ZINT_ERROR_INVALID_DATA },
/*125*/ { BARCODE_EANX_CHK, "123456789012345", ZINT_ERROR_TOO_LONG },
/*126*/ { BARCODE_EANX_CHK, "1234567890123456", ZINT_ERROR_TOO_LONG },
/*127*/ { BARCODE_EANX_CHK, "12345678901234567", ZINT_ERROR_TOO_LONG },
/*128*/ { BARCODE_EANX_CHK, "123456789012345678", ZINT_ERROR_TOO_LONG },
/*129*/ { BARCODE_EANX_CHK, "1234567890123456789", ZINT_ERROR_TOO_LONG },
/* 0*/ { BARCODE_EANX, "123456789012", 0, "", "" },
/* 1*/ { BARCODE_EANX, "12345678901A", ZINT_ERROR_INVALID_DATA, "Error 284: Invalid character in data (digits and \"+\" only)", "" },
/* 2*/ { BARCODE_EANX, "12345678901", 0, "", "" },
/* 3*/ { BARCODE_EANX, "1234567890128", 0, "", "EANX accepts CHK (treated as such if no leading zeroes required)" },
/* 4*/ { BARCODE_EANX, "1234567890120", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '0', expecting '8'", "" },
/* 5*/ { BARCODE_EANX, "123456789012+1", 0, "", "" },
/* 6*/ { BARCODE_EANX, "1234567890128+1", 0, "", "" },
/* 7*/ { BARCODE_EANX, "1234567890121+1", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '1', expecting '8'", "" },
/* 8*/ { BARCODE_EANX, "123456789012+12", 0, "", "" },
/* 9*/ { BARCODE_EANX, "1234567890128+12", 0, "", "" },
/* 10*/ { BARCODE_EANX, "1234567890122+12", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '2', expecting '8'", "" },
/* 11*/ { BARCODE_EANX, "12345678901234+12", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 12*/ { BARCODE_EANX, "123456789012345+12", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 13*/ { BARCODE_EANX, "1234567890123456+12", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 14*/ { BARCODE_EANX, "123456789012+123", 0, "", "" },
/* 15*/ { BARCODE_EANX, "1234567890128+123", 0, "", "" },
/* 16*/ { BARCODE_EANX, "1234567890123+123", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '3', expecting '8'", "" },
/* 17*/ { BARCODE_EANX, "12345678901234+123", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 18*/ { BARCODE_EANX, "123456789012345+123", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 19*/ { BARCODE_EANX, "123456789012+1234", 0, "", "" },
/* 20*/ { BARCODE_EANX, "1234567890128+1234", 0, "", "" },
/* 21*/ { BARCODE_EANX, "1234567890124+1234", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '4', expecting '8'", "" },
/* 22*/ { BARCODE_EANX, "12345678901234+1234", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 23*/ { BARCODE_EANX, "123456789012+12345", 0, "", "" },
/* 24*/ { BARCODE_EANX, "1234567890128+12345", 0, "", "" },
/* 25*/ { BARCODE_EANX, "12345678901234+12345", ZINT_ERROR_TOO_LONG, "Error 283: Input too long (19 character maximum)", "" },
/* 26*/ { BARCODE_EANX, "1234567890125+12345", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '5', expecting '8'", "" },
/* 27*/ { BARCODE_EANX, "123456789012+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 28*/ { BARCODE_EANX, "1234567890128+123456", ZINT_ERROR_TOO_LONG, "Error 283: Input too long (19 character maximum)", "" },
/* 29*/ { BARCODE_EANX, "12345678901+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 30*/ { BARCODE_EANX, "12345678901+1234567", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 31*/ { BARCODE_EANX, "1234567890+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 32*/ { BARCODE_EANX, "1234567890+1234567", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 33*/ { BARCODE_EANX, "123456789+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 34*/ { BARCODE_EANX, "123456789+1234567", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 35*/ { BARCODE_EANX, "12345678+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 36*/ { BARCODE_EANX, "1234567+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "EAN-8" },
/* 37*/ { BARCODE_EANX, "123456+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 38*/ { BARCODE_EANX, "12345+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 39*/ { BARCODE_EANX, "1234+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 40*/ { BARCODE_EANX, "123+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 41*/ { BARCODE_EANX, "12+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 42*/ { BARCODE_EANX, "1+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 43*/ { BARCODE_EANX, "1+12345678901234", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 44*/ { BARCODE_EANX, "1+12345", 0, "", "" },
/* 45*/ { BARCODE_EANX, "1+", 0, "", "EAN-2" },
/* 46*/ { BARCODE_EANX, "+1", 0, "", "EAN-8" },
/* 47*/ { BARCODE_EANX, "+", 0, "", "EAN-2" },
/* 48*/ { BARCODE_EANX, "1", 0, "", "EAN-2" },
/* 49*/ { BARCODE_EANX, "12", 0, "", "EAN-2" },
/* 50*/ { BARCODE_EANX, "123", 0, "", "EAN-5" },
/* 51*/ { BARCODE_EANX, "12345678901234", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 52*/ { BARCODE_EANX, "1234567890123A", ZINT_ERROR_INVALID_DATA, "Error 284: Invalid character in data (digits and \"+\" only)", "" },
/* 53*/ { BARCODE_EANX, "123456789012345", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 54*/ { BARCODE_EANX, "12345678901234A", ZINT_ERROR_INVALID_DATA, "Error 284: Invalid character in data (digits and \"+\" only)", "" },
/* 55*/ { BARCODE_EANX, "1234567890123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 56*/ { BARCODE_EANX, "12345678901234567", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 57*/ { BARCODE_EANX, "123456789012345678", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 58*/ { BARCODE_EANX, "1234567890123456789", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/* 59*/ { BARCODE_EANX_CHK, "1234567890128", 0, "", "" },
/* 60*/ { BARCODE_EANX_CHK, "1234567890126", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '6', expecting '8'", "" },
/* 61*/ { BARCODE_EANX_CHK, "123456789012A", ZINT_ERROR_INVALID_DATA, "Error 284: Invalid character in data (digits and \"+\" only)", "" },
/* 62*/ { BARCODE_EANX_CHK, "123456789012", 0, "", "Note: this is '0123456789012' with '2' happening to be the correct check digit" },
/* 63*/ { BARCODE_EANX_CHK, "123456789013", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '3', expecting '2'", "" },
/* 64*/ { BARCODE_EANX_CHK, "12345678901", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '1', expecting '5'", "" },
/* 65*/ { BARCODE_EANX_CHK, "12345678905", 0, "", "" },
/* 66*/ { BARCODE_EANX_CHK, "1234567890", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '0', expecting '5'", "" },
/* 67*/ { BARCODE_EANX_CHK, "123456789", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '9', expecting '4'", "" },
/* 68*/ { BARCODE_EANX_CHK, "12345678", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '8', expecting '0'", "EAN-8" },
/* 69*/ { BARCODE_EANX_CHK, "1234567", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '7', expecting '5'", "" },
/* 70*/ { BARCODE_EANX_CHK, "123456", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '6', expecting '7'", "" },
/* 71*/ { BARCODE_EANX_CHK, "12345", 0, "", "EAN-5" },
/* 72*/ { BARCODE_EANX_CHK, "1234", 0, "", "" },
/* 73*/ { BARCODE_EANX_CHK, "123", 0, "", "" },
/* 74*/ { BARCODE_EANX_CHK, "12", 0, "", "EAN-2" },
/* 75*/ { BARCODE_EANX_CHK, "1", 0, "", "" },
/* 76*/ { BARCODE_EANX_CHK, "123456789012+1", 0, "", "" },
/* 77*/ { BARCODE_EANX_CHK, "1234567890128+1", 0, "", "" },
/* 78*/ { BARCODE_EANX_CHK, "1234567890127+1", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '7', expecting '8'", "" },
/* 79*/ { BARCODE_EANX_CHK, "123456789012+12", 0, "", "" },
/* 80*/ { BARCODE_EANX_CHK, "1234567890128+12", 0, "", "" },
/* 81*/ { BARCODE_EANX_CHK, "1234567890129+12", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '9', expecting '8'", "" },
/* 82*/ { BARCODE_EANX_CHK, "123456789012+123", 0, "", "" },
/* 83*/ { BARCODE_EANX_CHK, "1234567890128+123", 0, "", "" },
/* 84*/ { BARCODE_EANX_CHK, "1234567890120+1234", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '0', expecting '8'", "" },
/* 85*/ { BARCODE_EANX_CHK, "123456789012+1234", 0, "", "" },
/* 86*/ { BARCODE_EANX_CHK, "1234567890128+1234", 0, "", "" },
/* 87*/ { BARCODE_EANX_CHK, "1234567890121+1234", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '1', expecting '8'", "" },
/* 88*/ { BARCODE_EANX_CHK, "123456789012+12345", 0, "", "" },
/* 89*/ { BARCODE_EANX_CHK, "1234567890128+12345", 0, "", "" },
/* 90*/ { BARCODE_EANX_CHK, "1234567890122+12345", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '2', expecting '8'", "" },
/* 91*/ { BARCODE_EANX_CHK, "1234567890122+1234A", ZINT_ERROR_INVALID_DATA, "Error 284: Invalid character in data (digits and \"+\" only)", "" },
/* 92*/ { BARCODE_EANX_CHK, "123456789012+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 93*/ { BARCODE_EANX_CHK, "123456789012+12345A", ZINT_ERROR_INVALID_DATA, "Error 284: Invalid character in data (digits and \"+\" only)", "" },
/* 94*/ { BARCODE_EANX_CHK, "1234567890128+123456", ZINT_ERROR_TOO_LONG, "Error 283: Input too long (19 character maximum)", "" },
/* 95*/ { BARCODE_EANX_CHK, "12345678901+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 96*/ { BARCODE_EANX_CHK, "12345678901+1234567", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 97*/ { BARCODE_EANX_CHK, "12345678901+12345", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '1', expecting '5'", "" },
/* 98*/ { BARCODE_EANX_CHK, "1234567890+12345", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '0', expecting '5'", "" },
/* 99*/ { BARCODE_EANX_CHK, "1234567890+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/*100*/ { BARCODE_EANX_CHK, "123456789+12345", ZINT_ERROR_INVALID_CHECK, "Error 275: Invalid check digit '9', expecting '4'", "" },
/*101*/ { BARCODE_EANX_CHK, "12345678+12345", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '8', expecting '0'", "EAN-8" },
/*102*/ { BARCODE_EANX_CHK, "12345670+12345", 0, "", "" },
/*103*/ { BARCODE_EANX_CHK, "1234567+12345", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '7', expecting '5'", "" },
/*104*/ { BARCODE_EANX_CHK, "1234565+12345", 0, "", "" },
/*105*/ { BARCODE_EANX_CHK, "123456+12345", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '6', expecting '7'", "" },
/*106*/ { BARCODE_EANX_CHK, "123457+12345", 0, "", "" },
/*107*/ { BARCODE_EANX_CHK, "12345+12345", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '5', expecting '8'", "" },
/*108*/ { BARCODE_EANX_CHK, "12348+12345", 0, "", "" },
/*109*/ { BARCODE_EANX_CHK, "1234+12345", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '4', expecting '6'", "" },
/*110*/ { BARCODE_EANX_CHK, "1236+12345", 0, "", "" },
/*111*/ { BARCODE_EANX_CHK, "123+12345", 0, "", "3 happens to be correct check digit" },
/*112*/ { BARCODE_EANX_CHK, "124+12345", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '4', expecting '3'", "" },
/*113*/ { BARCODE_EANX_CHK, "12+12345", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '2', expecting '7'", "" },
/*114*/ { BARCODE_EANX_CHK, "17+12345", 0, "", "" },
/*115*/ { BARCODE_EANX_CHK, "1+12345", ZINT_ERROR_INVALID_CHECK, "Error 276: Invalid check digit '1', expecting '0'", "" },
/*116*/ { BARCODE_EANX_CHK, "0+12345", 0, "", "" },
/*117*/ { BARCODE_EANX_CHK, "0+123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/*118*/ { BARCODE_EANX_CHK, "1+12345678901234", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/*119*/ { BARCODE_EANX_CHK, "0+12345678901234", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (5 character maximum for add-on)", "" },
/*120*/ { BARCODE_EANX_CHK, "1+", 0, "", "EAN-2" },
/*121*/ { BARCODE_EANX_CHK, "+1", 0, "", "EAN-8" },
/*122*/ { BARCODE_EANX_CHK, "+", 0, "", "EAN-2" },
/*123*/ { BARCODE_EANX_CHK, "12345678901234", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/*124*/ { BARCODE_EANX_CHK, "1234567890123A", ZINT_ERROR_INVALID_DATA, "Error 284: Invalid character in data (digits and \"+\" only)", "" },
/*125*/ { BARCODE_EANX_CHK, "123456789012345", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/*126*/ { BARCODE_EANX_CHK, "1234567890123456", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/*127*/ { BARCODE_EANX_CHK, "12345678901234567", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/*128*/ { BARCODE_EANX_CHK, "123456789012345678", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
/*129*/ { BARCODE_EANX_CHK, "1234567890123456789", ZINT_ERROR_TOO_LONG, "Error 294: Input too long (13 character maximum)", "" },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
struct zint_symbol *symbol;
char errtxt_escaped[256];
testStart("test_eanx_input");
for (i = 0; i < data_size; i++) {
@ -422,7 +426,16 @@ static void test_eanx_input(int index, int debug) {
length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
printf(" /*%3d*/ { %s, \"%s\", %s, \"%s\", \"%s\" },\n",
i, testUtilBarcodeName(data[i].symbology), data[i].data, testUtilErrorName(data[i].ret),
testUtilEscape(symbol->errtxt, (int) strlen(symbol->errtxt), errtxt_escaped, sizeof(errtxt_escaped)),
data[i].comment);
} else {
assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
assert_zero(strcmp(symbol->errtxt, data[i].ret_errtxt), "i:%d errtxt %s != %s\n", i, symbol->errtxt, data[i].ret_errtxt);
}
ZBarcode_Delete(symbol);
}
@ -430,125 +443,129 @@ static void test_eanx_input(int index, int debug) {
testFinish();
}
static void test_isbn_input(int index, int debug) {
static void test_isbn_input(int index, int generate, int debug) {
struct item {
char *data;
int ret_encode;
int ret_vector;
char *ret_errtxt;
char *comment;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "0", 0, 0 }, // Left zero-padded if < 10 chars
/* 1*/ { "1", ZINT_ERROR_INVALID_CHECK, -1 },
/* 2*/ { "X", ZINT_ERROR_INVALID_CHECK, -1 },
/* 3*/ { "12", ZINT_ERROR_INVALID_CHECK, -1 },
/* 4*/ { "19", 0, 0, },
/* 5*/ { "X9", ZINT_ERROR_INVALID_DATA, -1 },
/* 6*/ { "123", ZINT_ERROR_INVALID_CHECK, -1 },
/* 7*/ { "124", 0, 0, },
/* 8*/ { "1X4", ZINT_ERROR_INVALID_DATA, -1 },
/* 9*/ { "1234", ZINT_ERROR_INVALID_CHECK, -1 },
/* 10*/ { "1236", 0, 0, },
/* 11*/ { "12X6", ZINT_ERROR_INVALID_DATA, -1 },
/* 12*/ { "12345", ZINT_ERROR_INVALID_CHECK, -1 },
/* 13*/ { "12343", 0, 0, },
/* 14*/ { "123X3", ZINT_ERROR_INVALID_DATA, -1 },
/* 15*/ { "123456", ZINT_ERROR_INVALID_CHECK, -1 },
/* 16*/ { "123455", 0, 0, },
/* 17*/ { "1234X5", ZINT_ERROR_INVALID_DATA, -1 },
/* 18*/ { "1234567", ZINT_ERROR_INVALID_CHECK, -1 },
/* 19*/ { "1234560", 0, 0, },
/* 20*/ { "12345X0", ZINT_ERROR_INVALID_DATA, -1 },
/* 21*/ { "12345678", ZINT_ERROR_INVALID_CHECK, -1 },
/* 22*/ { "12345679", 0, 0 }, // 9 is correct check digit
/* 23*/ { "98765434", 0, 0 }, // 4 is correct check digit
/* 24*/ { "123456X9", ZINT_ERROR_INVALID_DATA, -1 },
/* 25*/ { "123456789", 0, 0 },
/* 26*/ { "340013817", ZINT_ERROR_INVALID_CHECK, -1 },
/* 27*/ { "340013818", 0, 0 }, // 8 is correct check digit
/* 28*/ { "902888455", 0, 0 }, // 5 is correct check digit
/* 29*/ { "9028884X5", ZINT_ERROR_INVALID_DATA, -1 },
/* 30*/ { "0123456789", 0, 0 },
/* 31*/ { "1234567890", ZINT_ERROR_INVALID_CHECK, -1 },
/* 32*/ { "123456789X", 0, 0 }, // X is correct check digit
/* 33*/ { "123456789x", 0, 0 }, // x is correct check digit
/* 34*/ { "8175257660", 0, 0 }, // 0 is correct check digit
/* 35*/ { "0590764845", 0, 0 }, // 5 is correct check digit
/* 36*/ { "0906495741", 0, 0 }, // 1 is correct check digit
/* 37*/ { "0140430016", 0, 0 }, // 6 is correct check digit
/* 38*/ { "0571086187", 0, 0 }, // 7 is correct check digit
/* 39*/ { "0486600882", 0, 0 }, // 2 is correct check digit
/* 40*/ { "04866008X2", ZINT_ERROR_INVALID_DATA, -1 },
/* 41*/ { "123456789A", ZINT_ERROR_INVALID_DATA, -1 },
/* 42*/ { "12345678901", ZINT_ERROR_TOO_LONG, -1 },
/* 43*/ { "1234567890A", ZINT_ERROR_INVALID_DATA, -1 },
/* 44*/ { "123456789012", ZINT_ERROR_TOO_LONG, -1 },
/* 45*/ { "12345678901", ZINT_ERROR_TOO_LONG, -1 },
/* 46*/ { "123456789012", ZINT_ERROR_TOO_LONG, -1 },
/* 47*/ { "1234567890123", ZINT_ERROR_INVALID_DATA, -1 },
/* 48*/ { "9784567890123", ZINT_ERROR_INVALID_CHECK, -1 },
/* 49*/ { "9784567890120", 0, 0 }, // 0 is correct check digit
/* 50*/ { "9783161484100", 0, 0 }, // 0 is correct check digit
/* 51*/ { "9781846688225", 0, 0 }, // 5 is correct check digit
/* 52*/ { "9781847657954", 0, 0 }, // 4 is correct check digit
/* 53*/ { "9781846688188", 0, 0 }, // 8 is correct check digit
/* 54*/ { "9781847659293", 0, 0 }, // 3 is correct check digit
/* 55*/ { "97845678901201", ZINT_ERROR_TOO_LONG, -1 },
/* 56*/ { "978456789012012", ZINT_ERROR_TOO_LONG, -1 },
/* 57*/ { "3954994+12", 0, 0 },
/* 58*/ { "3954994+1X", ZINT_ERROR_INVALID_DATA, -1 },
/* 59*/ { "39549X4+12", ZINT_ERROR_INVALID_DATA, -1 },
/* 60*/ { "3954994+12345", 0, 0 },
/* 61*/ { "3954994+1234X", ZINT_ERROR_INVALID_DATA, -1 },
/* 62*/ { "39549X4+12345", ZINT_ERROR_INVALID_DATA, -1 },
/* 63*/ { "3954994+123456", ZINT_ERROR_TOO_LONG, -1 },
/* 64*/ { "3954994+", 0, 0 },
/* 65*/ { "3954X94+", ZINT_ERROR_INVALID_DATA, -1 },
/* 66*/ { "61954993+1", 0, 0 },
/* 67*/ { "61954993+X", ZINT_ERROR_INVALID_DATA, -1 },
/* 68*/ { "619549X3+1", ZINT_ERROR_INVALID_DATA, -1 },
/* 69*/ { "61954992+123", ZINT_ERROR_INVALID_CHECK, -1 },
/* 70*/ { "61954993+123", 0, 0 },
/* 71*/ { "61954993+12X", ZINT_ERROR_INVALID_DATA, -1 },
/* 72*/ { "619549X3+123", ZINT_ERROR_INVALID_DATA, -1 },
/* 73*/ { "361954990+12", ZINT_ERROR_INVALID_CHECK, -1 },
/* 74*/ { "361954999+12", 0, 0 },
/* 75*/ { "361954999+1X", ZINT_ERROR_INVALID_DATA, -1 },
/* 76*/ { "3619549X9+12", ZINT_ERROR_INVALID_DATA, -1 },
/* 77*/ { "361954999+1234", 0, 0 },
/* 78*/ { "361954999+123X", ZINT_ERROR_INVALID_DATA, -1 },
/* 79*/ { "3619549X9+1234", ZINT_ERROR_INVALID_DATA, -1 },
/* 80*/ { "1999000030+12", ZINT_ERROR_INVALID_CHECK, -1 },
/* 81*/ { "199900003X+12", 0, 0 },
/* 82*/ { "199900003x+12", 0, 0 },
/* 83*/ { "19990000XX+12", ZINT_ERROR_INVALID_DATA, -1 },
/* 84*/ { "199900003X+1X", ZINT_ERROR_INVALID_DATA, -1 },
/* 85*/ { "1999000031+12345", ZINT_ERROR_INVALID_CHECK, -1 },
/* 86*/ { "199900003X+12345", 0, 0 },
/* 87*/ { "199900003x+12345", 0, 0 },
/* 88*/ { "199900003X+1234X", ZINT_ERROR_INVALID_DATA, -1 },
/* 89*/ { "19990000XX+12345", ZINT_ERROR_INVALID_DATA, -1 },
/* 90*/ { "199900003X+1234A", ZINT_ERROR_INVALID_DATA, -1 },
/* 91*/ { "9791234567895+12", ZINT_ERROR_INVALID_CHECK, -1 },
/* 92*/ { "9791234567896+12", 0, 0 },
/* 93*/ { "9791234567896+1X", ZINT_ERROR_INVALID_DATA, -1 },
/* 94*/ { "97912345678X6+12", ZINT_ERROR_INVALID_DATA, -1 },
/* 95*/ { "9791234567897+12345", ZINT_ERROR_INVALID_CHECK, -1 },
/* 96*/ { "9791234567896+12345", 0, 0 },
/* 97*/ { "9791234567896+1234X", ZINT_ERROR_INVALID_DATA, -1 },
/* 98*/ { "979123456X896+12345", ZINT_ERROR_INVALID_DATA, -1 },
/* 99*/ { "9791234567892+", ZINT_ERROR_INVALID_CHECK, -1 },
/*100*/ { "9791234567896+", 0, 0 },
/*101*/ { "97912345678X6+", ZINT_ERROR_INVALID_DATA, -1 },
/*102*/ { "97912345678961+", ZINT_ERROR_TOO_LONG, -1 },
/*103*/ { "97912345678961+12345", ZINT_ERROR_TOO_LONG, -1 },
/*104*/ { "9791234567896+123456", ZINT_ERROR_TOO_LONG, -1 },
/* 0*/ { "0", 0, 0, "", "Left zero-padded if < 10 chars" },
/* 1*/ { "1", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '1', expecting '0'", "" },
/* 2*/ { "X", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit 'X', expecting '0'", "" },
/* 3*/ { "12", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '2', expecting '9'", "" },
/* 4*/ { "19", 0, 0, "", "" },
/* 5*/ { "X9", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 6*/ { "123", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '3', expecting '4'", "" },
/* 7*/ { "124", 0, 0, "", "" },
/* 8*/ { "1X4", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 9*/ { "1234", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '4', expecting '6'", "" },
/* 10*/ { "1236", 0, 0, "", "" },
/* 11*/ { "12X6", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 12*/ { "12345", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '5', expecting '3'", "" },
/* 13*/ { "12343", 0, 0, "", "" },
/* 14*/ { "123X3", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 15*/ { "123456", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '6', expecting '5'", "" },
/* 16*/ { "123455", 0, 0, "", "" },
/* 17*/ { "1234X5", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 18*/ { "1234567", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '7', expecting '0'", "" },
/* 19*/ { "1234560", 0, 0, "", "" },
/* 20*/ { "12345X0", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 21*/ { "12345678", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '8', expecting '9'", "" },
/* 22*/ { "12345679", 0, 0, "", "9 is correct check digit" },
/* 23*/ { "98765434", 0, 0, "", "4 is correct check digit" },
/* 24*/ { "123456X9", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 25*/ { "123456789", 0, 0, "", "" },
/* 26*/ { "340013817", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '7', expecting '8'", "" },
/* 27*/ { "340013818", 0, 0, "", "8 is correct check digit" },
/* 28*/ { "902888455", 0, 0, "", "5 is correct check digit" },
/* 29*/ { "9028884X5", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 30*/ { "0123456789", 0, 0, "", "" },
/* 31*/ { "1234567890", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid ISBN check digit '0', expecting 'X'", "" },
/* 32*/ { "123456789X", 0, 0, "", "X is correct check digit" },
/* 33*/ { "123456789x", 0, 0, "", "x is correct check digit" },
/* 34*/ { "8175257660", 0, 0, "", "0 is correct check digit" },
/* 35*/ { "0590764845", 0, 0, "", "5 is correct check digit" },
/* 36*/ { "0906495741", 0, 0, "", "1 is correct check digit" },
/* 37*/ { "0140430016", 0, 0, "", "6 is correct check digit" },
/* 38*/ { "0571086187", 0, 0, "", "7 is correct check digit" },
/* 39*/ { "0486600882", 0, 0, "", "2 is correct check digit" },
/* 40*/ { "04866008X2", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 41*/ { "123456789A", ZINT_ERROR_INVALID_DATA, -1, "Error 285: Invalid character in data (digits, \"X\" and \"+\" only)", "" },
/* 42*/ { "12345678901", ZINT_ERROR_TOO_LONG, -1, "Error 278: Input wrong length (9, 10, or 13 characters only)", "" },
/* 43*/ { "1234567890A", ZINT_ERROR_INVALID_DATA, -1, "Error 285: Invalid character in data (digits, \"X\" and \"+\" only)", "" },
/* 44*/ { "123456789012", ZINT_ERROR_TOO_LONG, -1, "Error 278: Input wrong length (9, 10, or 13 characters only)", "" },
/* 45*/ { "12345678901", ZINT_ERROR_TOO_LONG, -1, "Error 278: Input wrong length (9, 10, or 13 characters only)", "" },
/* 46*/ { "123456789012", ZINT_ERROR_TOO_LONG, -1, "Error 278: Input wrong length (9, 10, or 13 characters only)", "" },
/* 47*/ { "1234567890123", ZINT_ERROR_INVALID_DATA, -1, "Error 279: Invalid ISBN (must begin with \"978\" or \"979\")", "" },
/* 48*/ { "9784567890123", ZINT_ERROR_INVALID_CHECK, -1, "Error 280: Invalid ISBN check digit '3', expecting '0'", "" },
/* 49*/ { "9784567890120", 0, 0, "", "0 is correct check digit" },
/* 50*/ { "9783161484100", 0, 0, "", "0 is correct check digit" },
/* 51*/ { "9781846688225", 0, 0, "", "5 is correct check digit" },
/* 52*/ { "9781847657954", 0, 0, "", "4 is correct check digit" },
/* 53*/ { "9781846688188", 0, 0, "", "8 is correct check digit" },
/* 54*/ { "9781847659293", 0, 0, "", "3 is correct check digit" },
/* 55*/ { "97845678901201", ZINT_ERROR_TOO_LONG, -1, "Error 294: Input too long (13 character maximum)", "" },
/* 56*/ { "978456789012012", ZINT_ERROR_TOO_LONG, -1, "Error 294: Input too long (13 character maximum)", "" },
/* 57*/ { "3954994+12", 0, 0, "", "" },
/* 58*/ { "3954994+1X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 59*/ { "39549X4+12", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 60*/ { "3954994+12345", 0, 0, "", "" },
/* 61*/ { "3954994+1234X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 62*/ { "39549X4+12345", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 63*/ { "3954994+123456", ZINT_ERROR_TOO_LONG, -1, "Error 294: Input too long (5 character maximum for add-on)", "" },
/* 64*/ { "3954994+", 0, 0, "", "" },
/* 65*/ { "3954X94+", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 66*/ { "61954993+1", 0, 0, "", "" },
/* 67*/ { "61954993+X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 68*/ { "619549X3+1", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 69*/ { "61954992+123", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '2', expecting '3'", "" },
/* 70*/ { "61954993+123", 0, 0, "", "" },
/* 71*/ { "61954993+12X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 72*/ { "619549X3+123", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 73*/ { "361954990+12", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid SBN check digit '0', expecting '9'", "" },
/* 74*/ { "361954999+12", 0, 0, "", "" },
/* 75*/ { "361954999+1X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 76*/ { "3619549X9+12", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 77*/ { "361954999+1234", 0, 0, "", "" },
/* 78*/ { "361954999+123X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 79*/ { "3619549X9+1234", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 80*/ { "1999000030+12", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid ISBN check digit '0', expecting 'X'", "" },
/* 81*/ { "199900003X+12", 0, 0, "", "" },
/* 82*/ { "199900003x+12", 0, 0, "", "" },
/* 83*/ { "19990000XX+12", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 84*/ { "199900003X+1X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 85*/ { "1999000031+12345", ZINT_ERROR_INVALID_CHECK, -1, "Error 281: Invalid ISBN check digit '1', expecting 'X'", "" },
/* 86*/ { "199900003X+12345", 0, 0, "", "" },
/* 87*/ { "199900003x+12345", 0, 0, "", "" },
/* 88*/ { "199900003X+1234X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 89*/ { "19990000XX+12345", ZINT_ERROR_INVALID_DATA, -1, "Error 296: Invalid character in data, \"X\" allowed in last position only", "" },
/* 90*/ { "199900003X+1234A", ZINT_ERROR_INVALID_DATA, -1, "Error 285: Invalid character in data (digits, \"X\" and \"+\" only)", "" },
/* 91*/ { "9791234567895+12", ZINT_ERROR_INVALID_CHECK, -1, "Error 280: Invalid ISBN check digit '5', expecting '6'", "" },
/* 92*/ { "9791234567896+12", 0, 0, "", "" },
/* 93*/ { "9791234567896+1X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 94*/ { "97912345678X6+12", ZINT_ERROR_INVALID_DATA, -1, "Error 282: Invalid character in data, \"X\" not allowed in ISBN-13", "" },
/* 95*/ { "9791234567897+12345", ZINT_ERROR_INVALID_CHECK, -1, "Error 280: Invalid ISBN check digit '7', expecting '6'", "" },
/* 96*/ { "9791234567896+12345", 0, 0, "", "" },
/* 97*/ { "9791234567896+1234X", ZINT_ERROR_INVALID_DATA, -1, "Error 295: Invalid add-on data (digits only)", "" },
/* 98*/ { "979123456X896+12345", ZINT_ERROR_INVALID_DATA, -1, "Error 282: Invalid character in data, \"X\" not allowed in ISBN-13", "" },
/* 99*/ { "9791234567892+", ZINT_ERROR_INVALID_CHECK, -1, "Error 280: Invalid ISBN check digit '2', expecting '6'", "" },
/*100*/ { "9791234567896+", 0, 0, "", "" },
/*101*/ { "97912345678X6+", ZINT_ERROR_INVALID_DATA, -1, "Error 282: Invalid character in data, \"X\" not allowed in ISBN-13", "" },
/*102*/ { "97912345678961+", ZINT_ERROR_TOO_LONG, -1, "Error 294: Input too long (13 character maximum)", "" },
/*103*/ { "97912345678961+12345", ZINT_ERROR_TOO_LONG, -1, "Error 283: Input too long (19 character maximum)", "" },
/*104*/ { "9791234567896+123456", ZINT_ERROR_TOO_LONG, -1, "Error 283: Input too long (19 character maximum)", "" },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
struct zint_symbol *symbol;
char errtxt_escaped[256];
testStart("test_isbn_input");
for (i = 0; i < data_size; i++) {
@ -562,11 +579,20 @@ static void test_isbn_input(int index, int debug) {
length = testUtilSetSymbol(symbol, BARCODE_ISBNX, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret_encode, symbol->errtxt);
if (data[i].ret_vector != -1) {
ret = ZBarcode_Buffer_Vector(symbol, 0);
assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d (%s)\n", i, ret, data[i].ret_vector, symbol->errtxt);
if (generate) {
printf(" /*%3d*/ { \"%s\", %s, %d, \"%s\", \"%s\" },\n",
i, data[i].data, testUtilErrorName(data[i].ret_encode), data[i].ret_vector,
testUtilEscape(symbol->errtxt, (int) strlen(symbol->errtxt), errtxt_escaped, sizeof(errtxt_escaped)),
data[i].comment);
} else {
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret_encode, symbol->errtxt);
assert_zero(strcmp(symbol->errtxt, data[i].ret_errtxt), "i:%d errtxt %s != %s\n", i, symbol->errtxt, data[i].ret_errtxt);
if (data[i].ret_vector != -1) {
ret = ZBarcode_Buffer_Vector(symbol, 0);
assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d (%s)\n", i, ret, data[i].ret_vector, symbol->errtxt);
}
}
ZBarcode_Delete(symbol);
@ -955,18 +981,127 @@ static void test_fuzz(int index, int debug) {
testFinish();
}
#include <time.h>
#define TEST_PERF_ITER_MILLES 10
#define TEST_PERF_ITERATIONS (TEST_PERF_ITER_MILLES * 1000)
#define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC)
// Not a real test, just performance indicator
static void test_perf(int index, int debug) {
struct item {
int symbology;
int option_2;
char *data;
int ret;
int expected_rows;
int expected_width;
char *comment;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { BARCODE_EANX, -1, "123456789012+12345", 0, 1, 149, "EAN-13 add-on 5" },
/* 1*/ { BARCODE_EANX, -1, "123456789012", 0, 1, 95, "EAN-13 no add-on" },
/* 2*/ { BARCODE_UPCA, -1, "12345678901+12345", 0, 1, 151, "UPC-A add-on 5" },
/* 3*/ { BARCODE_UPCA, -1, "12345678901", 0, 1, 95, "UPC-A no add-on" },
/* 4*/ { BARCODE_EANX, -1, "1234567+12345", 0, 1, 121, "EAN-8 add-on 5" },
/* 5*/ { BARCODE_EANX, -1, "1234567", 0, 1, 67, "EAN-8 no add-on" },
/* 6*/ { BARCODE_UPCE, -1, "1234567+12", 0, 1, 78, "UPC-E add-on 2" },
/* 7*/ { BARCODE_UPCE, -1, "1234567", 0, 1, 51, "UPC-E no add-on" },
/* 8*/ { BARCODE_EANX, -1, "12345", 0, 1, 47, "EAN-5" },
/* 9*/ { BARCODE_EANX, -1, "12", 0, 1, 20, "EAN-2" },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
struct zint_symbol *symbol;
clock_t start;
clock_t total_create = 0, total_encode = 0, total_buffer = 0, total_buf_inter = 0, total_print = 0;
clock_t diff_create, diff_encode, diff_buffer, diff_buf_inter, diff_print;
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;
diff_create = diff_encode = diff_buffer = diff_buf_inter = diff_print = 0;
for (j = 0; j < TEST_PERF_ITERATIONS; j++) {
start = clock();
symbol = ZBarcode_Create();
diff_create += clock() - start;
assert_nonnull(symbol, "Symbol not created\n");
length = testUtilSetSymbol(symbol, data[i].symbology, DATA_MODE, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
start = clock();
ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
diff_encode += clock() - start;
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data);
start = clock();
ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/);
diff_buffer += clock() - start;
assert_zero(ret, "i:%d ZBarcode_Buffer ret %d != 0 (%s)\n", i, ret, symbol->errtxt);
symbol->output_options |= OUT_BUFFER_INTERMEDIATE;
start = clock();
ret = ZBarcode_Buffer(symbol, 0 /*rotate_angle*/);
diff_buf_inter += clock() - start;
assert_zero(ret, "i:%d ZBarcode_Buffer OUT_BUFFER_INTERMEDIATE ret %d != 0 (%s)\n", i, ret, symbol->errtxt);
symbol->output_options &= ~OUT_BUFFER_INTERMEDIATE; // Undo
start = clock();
ret = ZBarcode_Print(symbol, 0 /*rotate_angle*/);
diff_print += clock() - start;
assert_zero(ret, "i:%d ZBarcode_Print ret %d != 0 (%s)\n", i, ret, symbol->errtxt);
assert_zero(remove(symbol->outfile), "i:%d remove(%s) != 0\n", i, symbol->outfile);
ZBarcode_Delete(symbol);
}
printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, data[i].comment,
TEST_PERF_TIME(diff_encode), TEST_PERF_TIME(diff_buffer), TEST_PERF_TIME(diff_buf_inter), TEST_PERF_TIME(diff_print), TEST_PERF_TIME(diff_create));
total_create += diff_create;
total_encode += diff_encode;
total_buffer += diff_buffer;
total_buf_inter += diff_buf_inter;
total_print += diff_print;
}
if (index == -1) {
printf("%*s: encode % 8gms, buffer % 8gms, buf_inter % 8gms, print % 8gms, create % 8gms\n", comment_max, "totals",
TEST_PERF_TIME(total_encode), TEST_PERF_TIME(total_buffer), TEST_PERF_TIME(total_buf_inter), TEST_PERF_TIME(total_print), TEST_PERF_TIME(total_create));
}
}
int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_upce_input", test_upce_input, 1, 0, 1 },
{ "test_upca_print", test_upca_print, 1, 0, 1 },
{ "test_upca_input", test_upca_input, 1, 0, 1 },
{ "test_eanx_input", test_eanx_input, 1, 0, 1 },
{ "test_isbn_input", test_isbn_input, 1, 0, 1 },
{ "test_eanx_input", test_eanx_input, 1, 1, 1 },
{ "test_isbn_input", test_isbn_input, 1, 1, 1 },
{ "test_hrt", test_hrt, 1, 0, 1 },
{ "test_vector_same", test_vector_same, 1, 0, 1 },
{ "test_encode", test_encode, 1, 1, 1 },
{ "test_fuzz", test_fuzz, 1, 0, 1 },
{ "test_perf", test_perf, 1, 0, 1 },
};
testRun(argc, argv, funcs, ARRAY_SIZE(funcs));