From 4a8cac2a5a636b56380d6b59b96598e3647537e3 Mon Sep 17 00:00:00 2001 From: gitlost Date: Thu, 10 Jun 2021 11:15:39 +0100 Subject: [PATCH] CODEONE/DATAMATRIX/MAILMARK/PLESSEY: fix some 32-bit/portability bugs PLESSEY: add options NCR weighted mod-10, hide check digit(s) in HRT test suite: now runnable under MSVC 2019, 2017, 2015, MinGW/MSYS win32/README: update with MSVC 2019 and CMake instructions --- CMakeLists.txt | 74 +-- backend/CMakeLists.txt | 5 +- backend/bmp.c | 27 +- backend/code1.c | 26 +- backend/code49.c | 8 +- backend/common.c | 2 +- backend/common.h | 47 +- backend/dmatrix.c | 16 +- backend/emf.c | 79 ++-- backend/gif.c | 10 +- backend/imail.c | 8 +- backend/library.c | 8 +- backend/mailmark.c | 93 ++-- backend/output.c | 6 +- backend/pcx.c | 19 +- backend/plessey.c | 491 +++++++------------- backend/png.c | 11 +- backend/postal.c | 14 +- backend/ps.c | 36 +- backend/qr.c | 2 +- backend/raster.c | 14 +- backend/svg.c | 51 +- backend/tests/CMakeLists.txt | 3 +- backend/tests/README | 43 +- backend/tests/test_big5.c | 4 +- backend/tests/test_bmp.c | 4 +- backend/tests/test_eci.c | 3 +- backend/tests/test_emf.c | 6 +- backend/tests/test_large.c | 52 ++- backend/tests/test_library.c | 34 +- backend/tests/test_plessey.c | 82 ++-- backend/tests/test_png.c | 4 +- backend/tests/test_print.c | 12 +- backend/tests/test_ps.c | 6 +- backend/tests/test_svg.c | 4 +- backend/tests/test_tif.c | 4 +- backend/tests/test_vector.c | 6 +- backend/tests/testcommon.c | 56 ++- backend/tests/testcommon.h | 47 +- backend/tests/tools/run_bwipp_tests.sh | 4 +- backend/tif.c | 5 +- backend/ultra.c | 80 ++-- backend/vector.c | 14 +- backend/zint.h | 18 +- cmake/zint_add_test.cmake | 4 +- docs/manual.txt | 17 +- frontend/CMakeLists.txt | 9 +- frontend/main.c | 6 +- frontend/tests/README | 4 +- frontend/tests/test_args.c | 318 ++++++++----- frontend_qt/grpMSICheck.ui | 37 +- frontend_qt/mainWindow.ui | 4 +- frontend_qt/mainwindow.cpp | 65 ++- frontend_qt/mainwindow.h | 1 + frontend_qt/qzint.cpp | 6 + win32/README | 111 ++++- win32/vs2008/zint.vcproj | 6 +- win32/vs2015/libzint.vcxproj | 2 + win32/vs2015/zint.vcxproj | 6 +- win32/vs2019/zint.vcxproj | 8 +- win32/zint.vcxproj | 6 +- win32/zint_cmdline_vc6/readme.txt | 20 +- win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp | 4 +- 63 files changed, 1189 insertions(+), 983 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 29ca251e..fa8e0b1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ -# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > +# Copyright (C) 2008 by BogDan Vatra < bogdan@licentia.eu > +# Copyright (C) 2009-2021 Robin Stuart # vim: set ts=4 sw=4 et : cmake_minimum_required(VERSION 3.5) @@ -31,19 +32,21 @@ include(SetPaths.cmake) include(CheckCXXCompilerFlag) include(CheckFunctionExists) -check_cxx_compiler_flag("-Wall" CXX_COMPILER_FLAG_WALL) -if(CXX_COMPILER_FLAG_WALL) - add_compile_options("-Wall") -endif() +if(NOT MSVC) # Use default warnings if MSVC otherwise inundated + check_cxx_compiler_flag("-Wall" CXX_COMPILER_FLAG_WALL) + if(CXX_COMPILER_FLAG_WALL) + add_compile_options("-Wall") + endif() -check_cxx_compiler_flag("-Wextra" CXX_COMPILER_FLAG_WEXTRA) -if(CXX_COMPILER_FLAG_WEXTRA) - add_compile_options("-Wextra") -endif() + check_cxx_compiler_flag("-Wextra" CXX_COMPILER_FLAG_WEXTRA) + if(CXX_COMPILER_FLAG_WEXTRA) + add_compile_options("-Wextra") + endif() -check_cxx_compiler_flag("-Wpedantic" CXX_COMPILER_FLAG_WPEDANTIC) -if(CXX_COMPILER_FLAG_WPEDANTIC) - add_compile_options("-Wpedantic") + check_cxx_compiler_flag("-Wpedantic" CXX_COMPILER_FLAG_WPEDANTIC) + if(CXX_COMPILER_FLAG_WPEDANTIC) + add_compile_options("-Wpedantic") + endif() endif() if(ZINT_DEBUG) @@ -61,39 +64,40 @@ if(ZINT_TEST) enable_testing() endif() -if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(ZINT_SANITIZE) add_compile_options(-fsanitize=undefined -fsanitize=address) link_libraries(-fsanitize=undefined -fsanitize=address) - # Gives warning on MainWindow::setupUI() and retries (and takes forever) if var-tracking-assignments enabled - add_compile_options(-fno-var-tracking-assignments) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + # Gives warning on MainWindow::setupUI() and retries (& takes forever) if var-tracking-assignments enabled + add_compile_options(-fno-var-tracking-assignments) + endif() endif() endif() -IF(APPLE) - IF (UNIVERSAL) # TODO: make universal binary - IF(NOT ZINT_HAS_BEEN_RUN_BEFORE) - IF(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) - SET(CMAKE_OSX_ARCHITECTURES "ppc;i386;ppc64;x86_64" CACHE STRING "Build architectures for OSX" FORCE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING "Flags used by the compiler during all build types." FORCE) - ELSE(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) - IF(EXISTS /Developer/SDKs/MacOSX10.4u.sdk OR EXISTS /SDKs/MacOSX10.4u.sdk) - SET(CMAKE_OSX_ARCHITECTURES "ppc;i386" CACHE STRING "Build architectures for OSX" FORCE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING "Flags used by the compiler during all build types." FORCE) - ENDIF(EXISTS /Developer/SDKs/MacOSX10.4u.sdk OR EXISTS /SDKs/MacOSX10.4u.sdk) - ENDIF(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) +if(APPLE) + if(UNIVERSAL) # TODO: make universal binary + if(NOT ZINT_HAS_BEEN_RUN_BEFORE) + if(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) + set(CMAKE_OSX_ARCHITECTURES "ppc;i386;ppc64;x86_64" CACHE STRING "Build architectures for OSX" FORCE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING + "Flags used by the compiler during all build types." FORCE) + elseif(EXISTS /Developer/SDKs/MacOSX10.4u.sdk OR EXISTS /SDKs/MacOSX10.4u.sdk) + set(CMAKE_OSX_ARCHITECTURES "ppc;i386" CACHE STRING "Build architectures for OSX" FORCE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING + "Flags used by the compiler during all build types." FORCE) + endif() message("Build architectures for OSX:${CMAKE_OSX_ARCHITECTURES}") - ENDIF(NOT ZINT_HAS_BEEN_RUN_BEFORE) - - ELSE (UNIVERSAL) - SET(CMAKE_OSX_SYSROOT "/") - ENDIF (UNIVERSAL) -ENDIF(APPLE) + endif() + else() + set(CMAKE_OSX_SYSROOT "/") + endif() +endif() check_function_exists(getopt HAVE_GETOPT) if(NOT HAVE_GETOPT) add_subdirectory(getopt) -endif(NOT HAVE_GETOPT) +endif() add_subdirectory(backend) add_subdirectory(frontend) @@ -137,7 +141,7 @@ configure_file( add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") -# staniek: don't install +# staniek: don't install if(DATA_INSTALL_DIR) set(CMAKE_MODULES_INSTALL_PATH ${DATA_INSTALL_DIR}/cmake/modules) else() diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index d1b4ea9d..28f7dd8e 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -1,4 +1,5 @@ -# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > +# Copyright (C) 2008 by BogDan Vatra < bogdan@licentia.eu > +# Copyright (C) 2009-2021 Robin Stuart # vim: set ts=4 sw=4 et : project(zint) @@ -63,4 +64,4 @@ install(FILES zint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel) if(ZINT_TEST) add_subdirectory(tests) -endif(ZINT_TEST) +endif() diff --git a/backend/bmp.c b/backend/bmp.c index b750c654..14f35a83 100644 --- a/backend/bmp.c +++ b/backend/bmp.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2009 - 2020 Robin Stuart + Copyright (C) 2009 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -31,6 +31,7 @@ */ /* vim: set ts=4 sw=4 et : */ +#include #include #include "common.h" #include "bmp.h" /* Bitmap header structure */ @@ -63,8 +64,8 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) } row_size = 4 * ((bits_per_pixel * symbol->bitmap_width + 31) / 32); data_size = symbol->bitmap_height * row_size; - data_offset = sizeof (bitmap_file_header_t) + sizeof (bitmap_info_header_t); - data_offset += (colour_count * (sizeof(color_ref_t))); + data_offset = sizeof(bitmap_file_header_t) + sizeof(bitmap_info_header_t); + data_offset += colour_count * sizeof(color_ref_t); file_size = data_offset + data_size; bitmap_file_start = (unsigned char *) malloc(file_size); @@ -84,7 +85,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) bg_color_ref.green = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); bg_color_ref.blue = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); bg_color_ref.reserved = 0x00; - + for (i = 0; i < 8; i++) { ultra_color_ref[i].red = colour_to_red(i + 1); ultra_color_ref[i].green = colour_to_green(i + 1); @@ -143,7 +144,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) file_header.reserved = 0; file_header.data_offset = data_offset; - info_header.header_size = sizeof (bitmap_info_header_t); + info_header.header_size = sizeof(bitmap_info_header_t); info_header.width = symbol->bitmap_width; info_header.height = symbol->bitmap_height; info_header.colour_planes = 1; @@ -154,12 +155,12 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) info_header.vert_res = 0; info_header.colours = colour_count; info_header.important_colours = colour_count; - + bmp_posn = bitmap_file_start; - memcpy(bitmap_file_start, &file_header, sizeof (bitmap_file_header_t)); - bmp_posn += sizeof (bitmap_file_header_t); - memcpy(bmp_posn, &info_header, sizeof (bitmap_info_header_t)); - + memcpy(bitmap_file_start, &file_header, sizeof(bitmap_file_header_t)); + bmp_posn += sizeof(bitmap_file_header_t); + memcpy(bmp_posn, &info_header, sizeof(bitmap_info_header_t)); + bmp_posn += sizeof(bitmap_info_header_t); memcpy(bmp_posn, &bg_color_ref, sizeof(color_ref_t)); if (symbol->symbology == BARCODE_ULTRA) { @@ -167,7 +168,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) bmp_posn += sizeof(color_ref_t); memcpy(bmp_posn, &ultra_color_ref[i], sizeof(color_ref_t)); } - } else { + } else { bmp_posn += sizeof(color_ref_t); memcpy(bmp_posn, &fg_color_ref, sizeof(color_ref_t)); } @@ -176,7 +177,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) if ((symbol->output_options & BARCODE_STDOUT) != 0) { #ifdef _MSC_VER if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - strcpy(symbol->errtxt, "600: Can't open output file"); + sprintf(symbol->errtxt, "600: Can't open output file (%d: %.30s)", errno, strerror(errno)); free(bitmap_file_start); return ZINT_ERROR_FILE_ACCESS; } @@ -185,7 +186,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) } else { if (!(bmp_file = fopen(symbol->outfile, "wb"))) { free(bitmap_file_start); - strcpy(symbol->errtxt, "601: Can't open output file"); + sprintf(symbol->errtxt, "601: Can't open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } } diff --git a/backend/code1.c b/backend/code1.c index e08d7a57..9ae44bcb 100644 --- a/backend/code1.c +++ b/backend/code1.c @@ -39,10 +39,6 @@ #include #ifdef _MSC_VER #include -/* ceilf (C99) not before MSVC++2013 (C++ 12.0) */ -#if _MSC_VER < 1800 -#define ceilf (float) ceil -#endif #endif /* Add solid bar */ @@ -237,11 +233,11 @@ static int c1_look_ahead_test(const unsigned char source[], const int sourcelen, if (sp >= position + 3) { /* Step Q */ float cnt; - ascii_rnded = (int) ceilf(ascii_count); - c40_rnded = (int) ceilf(c40_count); - text_rnded = (int) ceilf(text_count); - edi_rnded = (int) ceilf(edi_count); - byte_rnded = (int) ceilf(byte_count); + ascii_rnded = (int) ceilf(stripf(ascii_count)); + c40_rnded = (int) ceilf(stripf(c40_count)); + text_rnded = (int) ceilf(stripf(text_count)); + edi_rnded = (int) ceilf(stripf(edi_count)); + byte_rnded = (int) ceilf(stripf(byte_count)); cnt = byte_count + 1.0f; if (cnt <= ascii_rnded && cnt <= c40_rnded && cnt <= text_rnded && cnt <= edi_rnded) { @@ -277,11 +273,11 @@ static int c1_look_ahead_test(const unsigned char source[], const int sourcelen, } /* Step K */ - ascii_rnded = (int) ceilf(ascii_count); - c40_rnded = (int) ceilf(c40_count); - text_rnded = (int) ceilf(text_count); - edi_rnded = (int) ceilf(edi_count); - byte_rnded = (int) ceilf(byte_count); + ascii_rnded = (int) ceilf(stripf(ascii_count)); + c40_rnded = (int) ceilf(stripf(c40_count)); + text_rnded = (int) ceilf(stripf(text_count)); + edi_rnded = (int) ceilf(stripf(edi_count)); + byte_rnded = (int) ceilf(stripf(byte_count)); if (byte_count <= ascii_rnded && byte_count <= c40_rnded && byte_count <= text_rnded && byte_count <= edi_rnded) { return C1_BYTE; /* Step K1 */ @@ -1121,7 +1117,7 @@ INTERNAL int code_one(struct zint_symbol *symbol, unsigned char source[], int le size = symbol->option_2; } - if ((symbol-> option_2 != 0) && (symbol->option_2 < size)) { + if ((symbol->option_2 != 0) && (symbol->option_2 < size)) { strcpy(symbol->errtxt, "518: Input too long for selected symbol size"); return ZINT_ERROR_TOO_LONG; } diff --git a/backend/code49.c b/backend/code49.c index 52a96f0f..e01b37d9 100644 --- a/backend/code49.c +++ b/backend/code49.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2009 - 2020 Robin Stuart + Copyright (C) 2009 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -74,7 +74,7 @@ INTERNAL int code_49(struct zint_symbol *symbol, unsigned char source[], int len codeword_count = 0; i = 0; - h = strlen(intermediate); + h = (int) strlen(intermediate); do { if ((intermediate[i] >= '0') && (intermediate[i] <= '9')) { /* Numeric data */ @@ -340,7 +340,7 @@ INTERNAL int code_49(struct zint_symbol *symbol, unsigned char source[], int len /* Expand into symbol */ symbol->row_height[i] = 10; - for (j = 0, len = strlen(pattern); j < len; j++) { + for (j = 0, len = (int) strlen(pattern); j < len; j++) { if (pattern[j] == '1') { set_module(symbol, i, j); } @@ -348,7 +348,7 @@ INTERNAL int code_49(struct zint_symbol *symbol, unsigned char source[], int len } symbol->rows = rows; - symbol->width = strlen(pattern); + symbol->width = (int) strlen(pattern); symbol->output_options |= BARCODE_BIND; diff --git a/backend/common.c b/backend/common.c index e0803014..eb623db5 100644 --- a/backend/common.c +++ b/backend/common.c @@ -462,7 +462,7 @@ void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *c int i, max = length, cnt_len = 0; if (length > 30) { /* 30*3 < errtxt 92 (100 - "Warning ") chars */ sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */ - cnt_len = strlen(symbol->errtxt); + cnt_len = (int) strlen(symbol->errtxt); max = 30 - (cnt_len + 2) / 3; } for (i = 0; i < max; i++) { diff --git a/backend/common.h b/backend/common.h index eccf574d..2ad037ef 100644 --- a/backend/common.h +++ b/backend/common.h @@ -31,7 +31,6 @@ */ /* vim: set ts=4 sw=4 et : */ -/* Used in some logic */ #ifndef __COMMON_H #define __COMMON_H @@ -57,23 +56,31 @@ #define ustrcat(target, source) strcat((char *) (target), (const char *) (source)) #define ustrncat(target, source, count) strncat((char *) (target), (const char *) (source), (count)) -#if defined(__GNUC__) && !defined(_WIN32) && !defined(ZINT_TEST) -# define INTERNAL __attribute__ ((visibility ("hidden"))) -#else /* despite the name, the test cases are referencing the INTERNAL functions, so they need to be exported */ -# if defined(ZINT_TEST) -# if defined(DLL_EXPORT) || defined(PIC) || defined(_USRDLL) -# define INTERNAL __declspec(dllexport) -# elif defined(ZINT_DLL) -# define INTERNAL __declspec(dllimport) -# endif +/* Removes excess precision from floats - see https://stackoverflow.com/q/503436/664741 */ +#define stripf(arg) (*((volatile float *) &(arg))) + +#ifdef _MSC_VER +# if _MSC_VER < 1800 /* ceilf, floorf, roundf (C99) not before MSVC 2013 (C++ 12.0) */ +# define ceilf (float) ceil +# define floorf (float) floor +# define roundf(arg) ((float) floor((arg) + 0.5f)) # endif -# if !defined(INTERNAL) -# define INTERNAL +# pragma warning(disable: 4244) /* conversion from int to float */ +# if _MSC_VER >= 1900 /* MSVC 2015 */ +# pragma warning(disable: 4996) /* function or variable may be unsafe */ # endif #endif -#if defined(ZINT_TEST) -#define STATIC_UNLESS_ZINT_TEST +#if (defined(__GNUC__) || defined(__clang__)) && !defined(ZINT_TEST) && !defined(__MINGW32__) +# define INTERNAL __attribute__ ((visibility ("hidden"))) +#elif defined(ZINT_TEST) +# define INTERNAL ZINT_EXTERN /* The test suite references INTERNAL functions, so they need to be exported */ +#else +# define INTERNAL +#endif + +#ifdef ZINT_TEST +#define STATIC_UNLESS_ZINT_TEST INTERNAL #else #define STATIC_UNLESS_ZINT_TEST static #endif @@ -82,16 +89,16 @@ #ifdef COMMON_INLINE /* Return true (1) if a module is dark/black, otherwise false (0) */ -#define module_is_set(s, y, x) (((s)->encoded_data[(y)][(x) >> 3] >> ((x) & 0x07)) & 1) +# define module_is_set(s, y, x) (((s)->encoded_data[(y)][(x) >> 3] >> ((x) & 0x07)) & 1) /* Set a module to dark/black */ -#define set_module(s, y, x) do { (s)->encoded_data[(y)][(x) >> 3] |= 1 << ((x) & 0x07); } while (0) +# define set_module(s, y, x) do { (s)->encoded_data[(y)][(x) >> 3] |= 1 << ((x) & 0x07); } while (0) /* Return true (1-8) if a module is colour, otherwise false (0) */ -#define module_colour_is_set(s, y, x) ((s)->encoded_data[(y)][(x)]) +# define module_colour_is_set(s, y, x) ((s)->encoded_data[(y)][(x)]) /* Set a module to a colour */ -#define set_module_colour(s, y, x, c) do { (s)->encoded_data[(y)][(x)] = (c); } while (0) +# define set_module_colour(s, y, x, c) do { (s)->encoded_data[(y)][(x)] = (c); } while (0) #endif #ifdef __cplusplus @@ -131,8 +138,8 @@ extern "C" { INTERNAL int colour_to_blue(const int colour); #ifdef ZINT_TEST - void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length); - void debug_test_codeword_dump_int(struct zint_symbol *symbol, const int *codewords, const int length); + INTERNAL void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length); + INTERNAL void debug_test_codeword_dump_int(struct zint_symbol *symbol, const int *codewords, const int length); #endif #ifdef __cplusplus diff --git a/backend/dmatrix.c b/backend/dmatrix.c index eae84fdb..7ec7d93b 100644 --- a/backend/dmatrix.c +++ b/backend/dmatrix.c @@ -44,10 +44,6 @@ #include #ifdef _MSC_VER #include -/* ceilf (C99) not before MSVC++2013 (C++ 12.0) */ -#if _MSC_VER < 1800 -#define ceilf (float) ceil -#endif #endif #include "common.h" #include "reedsol.h" @@ -419,12 +415,12 @@ static int look_ahead_test(const unsigned char inputData[], const int sourcelen, /* At the end of data ... step (k) */ /* step (k)(1) */ - ascii_rnded = (int) ceilf(ascii_count); - b256_rnded = (int) ceilf(b256_count); - edf_rnded = (int) ceilf(edf_count); - text_rnded = (int) ceilf(text_count); - x12_rnded = (int) ceilf(x12_count); - c40_rnded = (int) ceilf(c40_count); + ascii_rnded = (int) ceilf(stripf(ascii_count)); + b256_rnded = (int) ceilf(stripf(b256_count)); + edf_rnded = (int) ceilf(stripf(edf_count)); + text_rnded = (int) ceilf(stripf(text_count)); + x12_rnded = (int) ceilf(stripf(x12_count)); + c40_rnded = (int) ceilf(stripf(c40_count)); if (ascii_rnded <= b256_rnded && ascii_rnded <= edf_rnded && ascii_rnded <= text_rnded && ascii_rnded <= x12_rnded && ascii_rnded <= c40_rnded) { diff --git a/backend/emf.c b/backend/emf.c index 43847c66..d1b3b48b 100644 --- a/backend/emf.c +++ b/backend/emf.c @@ -1,7 +1,7 @@ /* emf.c - Support for Microsoft Enhanced Metafile Format libzint - the open source barcode library - Copyright (C) 2016 - 2020 Robin Stuart + Copyright (C) 2016 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -33,6 +33,7 @@ /* Developed according to [MS-EMF] - v20160714, Released July 14, 2016 * and [MS-WMF] - v20160714, Released July 14, 2016 */ +#include #include #include #include @@ -232,7 +233,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); - + if (strlen(symbol->bgcolour) > 6) { if ((ctoi(symbol->bgcolour[6]) == 0) && (ctoi(symbol->bgcolour[7]) == 0)) { draw_background = 0; @@ -253,12 +254,12 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { float text_fsizes[string_count ? string_count: 1]; int text_haligns[string_count ? string_count: 1]; #else - rectangle = (emr_rectangle_t*) _alloca(rectangle_count * sizeof (emr_rectangle_t)); - circle = (emr_ellipse_t*) _alloca(circle_count * sizeof (emr_ellipse_t)); - hexagon = (emr_polygon_t*) _alloca(hexagon_count * sizeof (emr_polygon_t)); - text = (emr_exttextoutw_t*) _alloca(string_count * sizeof (emr_exttextoutw_t)); - text_fsizes = (float *) _alloca(string_count * sizeof (float)); - text_haligns = (int *) _alloca(string_count * sizeof (int)); + rectangle = (emr_rectangle_t*) _alloca(rectangle_count * sizeof(emr_rectangle_t)); + circle = (emr_ellipse_t*) _alloca(circle_count * sizeof(emr_ellipse_t)); + hexagon = (emr_polygon_t*) _alloca(hexagon_count * sizeof(emr_polygon_t)); + text = (emr_exttextoutw_t*) _alloca(string_count * sizeof(emr_exttextoutw_t)); + text_fsizes = (float *) _alloca(string_count * sizeof(float)); + text_haligns = (int *) _alloca(string_count * sizeof(int)); #endif //Calculate how many coloured rectangles @@ -662,7 +663,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { recordcount++; if (symbol->symbology == BARCODE_MAXICODE) { - bytecount += 5 * sizeof (emr_selectobject_t); + bytecount += 5 * sizeof(emr_selectobject_t); recordcount += 5; } @@ -677,55 +678,55 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { emf_file = fopen(symbol->outfile, "wb"); } if (emf_file == NULL) { - strcpy(symbol->errtxt, "640: Could not open output file"); + sprintf(symbol->errtxt, "640: Could not open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } - fwrite(&emr_header, sizeof (emr_header_t), 1, emf_file); + fwrite(&emr_header, sizeof(emr_header_t), 1, emf_file); - fwrite(&emr_mapmode, sizeof (emr_mapmode_t), 1, emf_file); + fwrite(&emr_mapmode, sizeof(emr_mapmode_t), 1, emf_file); if (rotate_angle) { - fwrite(&emr_setworldtransform, sizeof (emr_setworldtransform_t), 1, emf_file); + fwrite(&emr_setworldtransform, sizeof(emr_setworldtransform_t), 1, emf_file); } - fwrite(&emr_createbrushindirect_bg, sizeof (emr_createbrushindirect_t), 1, emf_file); + fwrite(&emr_createbrushindirect_bg, sizeof(emr_createbrushindirect_t), 1, emf_file); if (symbol->symbology == BARCODE_ULTRA) { for (i = 0; i < 8; i++) { if (rectangle_count_bycolour[i + 1]) { - fwrite(&emr_createbrushindirect_colour[i], sizeof (emr_createbrushindirect_t), 1, emf_file); + fwrite(&emr_createbrushindirect_colour[i], sizeof(emr_createbrushindirect_t), 1, emf_file); } } } else { - fwrite(&emr_createbrushindirect_fg, sizeof (emr_createbrushindirect_t), 1, emf_file); + fwrite(&emr_createbrushindirect_fg, sizeof(emr_createbrushindirect_t), 1, emf_file); } - fwrite(&emr_createpen, sizeof (emr_createpen_t), 1, emf_file); + fwrite(&emr_createpen, sizeof(emr_createpen_t), 1, emf_file); if (symbol->vector->strings) { - fwrite(&emr_extcreatefontindirectw, sizeof (emr_extcreatefontindirectw_t), 1, emf_file); + fwrite(&emr_extcreatefontindirectw, sizeof(emr_extcreatefontindirectw_t), 1, emf_file); if (fsize2) { - fwrite(&emr_extcreatefontindirectw2, sizeof (emr_extcreatefontindirectw_t), 1, emf_file); + fwrite(&emr_extcreatefontindirectw2, sizeof(emr_extcreatefontindirectw_t), 1, emf_file); } } - fwrite(&emr_selectobject_bgbrush, sizeof (emr_selectobject_t), 1, emf_file); - fwrite(&emr_selectobject_pen, sizeof (emr_selectobject_t), 1, emf_file); + fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_selectobject_pen, sizeof(emr_selectobject_t), 1, emf_file); if (draw_background) { - fwrite(&background, sizeof (emr_rectangle_t), 1, emf_file); + fwrite(&background, sizeof(emr_rectangle_t), 1, emf_file); } if (symbol->symbology == BARCODE_ULTRA) { for(i = 0; i < 8; i++) { if (rectangle_count_bycolour[i + 1]) { - fwrite(&emr_selectobject_colour[i], sizeof (emr_selectobject_t), 1, emf_file); + fwrite(&emr_selectobject_colour[i], sizeof(emr_selectobject_t), 1, emf_file); rect = symbol->vector->rectangles; this_rectangle = 0; while (rect) { if (rect->colour == i + 1) { - fwrite(&rectangle[this_rectangle], sizeof (emr_rectangle_t), 1, emf_file); + fwrite(&rectangle[this_rectangle], sizeof(emr_rectangle_t), 1, emf_file); } this_rectangle++; rect = rect->next; @@ -733,42 +734,42 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { } } } else { - fwrite(&emr_selectobject_fgbrush, sizeof (emr_selectobject_t), 1, emf_file); + fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); // Rectangles for (i = 0; i < rectangle_count; i++) { - fwrite(&rectangle[i], sizeof (emr_rectangle_t), 1, emf_file); + fwrite(&rectangle[i], sizeof(emr_rectangle_t), 1, emf_file); } } // Hexagons for (i = 0; i < hexagon_count; i++) { - fwrite(&hexagon[i], sizeof (emr_polygon_t), 1, emf_file); + fwrite(&hexagon[i], sizeof(emr_polygon_t), 1, emf_file); } // Circles if (symbol->symbology == BARCODE_MAXICODE) { // Bullseye needed for (i = 0; i < circle_count; i++) { - fwrite(&circle[i], sizeof (emr_ellipse_t), 1, emf_file); + fwrite(&circle[i], sizeof(emr_ellipse_t), 1, emf_file); if (i < circle_count - 1) { if (i % 2) { - fwrite(&emr_selectobject_fgbrush, sizeof (emr_selectobject_t), 1, emf_file); + fwrite(&emr_selectobject_fgbrush, sizeof(emr_selectobject_t), 1, emf_file); } else { - fwrite(&emr_selectobject_bgbrush, sizeof (emr_selectobject_t), 1, emf_file); + fwrite(&emr_selectobject_bgbrush, sizeof(emr_selectobject_t), 1, emf_file); } } } } else { for (i = 0; i < circle_count; i++) { - fwrite(&circle[i], sizeof (emr_ellipse_t), 1, emf_file); + fwrite(&circle[i], sizeof(emr_ellipse_t), 1, emf_file); } } // Text if (string_count > 0) { - fwrite(&emr_selectobject_font, sizeof (emr_selectobject_t), 1, emf_file); - fwrite(&emr_settextcolor, sizeof (emr_settextcolor_t), 1, emf_file); + fwrite(&emr_selectobject_font, sizeof(emr_selectobject_t), 1, emf_file); + fwrite(&emr_settextcolor, sizeof(emr_settextcolor_t), 1, emf_file); } current_fsize = fsize; @@ -776,24 +777,24 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { for (i = 0; i < string_count; i++) { if (text_fsizes[i] != current_fsize) { current_fsize = text_fsizes[i]; - fwrite(&emr_selectobject_font2, sizeof (emr_selectobject_t), 1, emf_file); + fwrite(&emr_selectobject_font2, sizeof(emr_selectobject_t), 1, emf_file); } if (text_haligns[i] != current_halign) { current_halign = text_haligns[i]; if (current_halign == 0) { - fwrite(&emr_settextalign, sizeof (emr_settextalign_t), 1, emf_file); + fwrite(&emr_settextalign, sizeof(emr_settextalign_t), 1, emf_file); } else if (current_halign == 1) { - fwrite(&emr_settextalign1, sizeof (emr_settextalign_t), 1, emf_file); + fwrite(&emr_settextalign1, sizeof(emr_settextalign_t), 1, emf_file); } else { - fwrite(&emr_settextalign2, sizeof (emr_settextalign_t), 1, emf_file); + fwrite(&emr_settextalign2, sizeof(emr_settextalign_t), 1, emf_file); } } - fwrite(&text[i], sizeof (emr_exttextoutw_t), 1, emf_file); + fwrite(&text[i], sizeof(emr_exttextoutw_t), 1, emf_file); fwrite(this_string[i], bump_up(text[i].w_emr_text.chars) * 2, 1, emf_file); free(this_string[i]); } - fwrite(&emr_eof, sizeof (emr_eof_t), 1, emf_file); + fwrite(&emr_eof, sizeof(emr_eof_t), 1, emf_file); if (symbol->output_options & BARCODE_STDOUT) { fflush(emf_file); diff --git a/backend/gif.c b/backend/gif.c index 55077bb8..214e5ac0 100644 --- a/backend/gif.c +++ b/backend/gif.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2009 - 2020 Robin Stuart + Copyright (C) 2009 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -31,8 +31,8 @@ */ /* vim: set ts=4 sw=4 et : */ +#include #include -#include #include "common.h" #include #ifdef _MSC_VER @@ -398,7 +398,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) RGBCur[0] = 0; RGBCur[1] = 0; RGBCur[2] = 0; break; default: /* error case - return */ - strcpy(symbol->errtxt, "611: unknown pixel colour"); + strcpy(symbol->errtxt, "612: unknown pixel colour"); return ZINT_ERROR_INVALID_DATA; } /* Search, if RGB value is already present */ @@ -469,14 +469,14 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) if ((symbol->output_options & BARCODE_STDOUT) != 0) { #ifdef _MSC_VER if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - strcpy(symbol->errtxt, "610: Can't open output file"); + sprintf(symbol->errtxt, "610: Can't open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } #endif gif_file = stdout; } else { if (!(gif_file = fopen(symbol->outfile, "wb"))) { - strcpy(symbol->errtxt, "611: Can't open output file"); + sprintf(symbol->errtxt, "611: Can't open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } } diff --git a/backend/imail.c b/backend/imail.c index 9291c561..37c17fd1 100644 --- a/backend/imail.c +++ b/backend/imail.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2008 - 2020 Robin Stuart + Copyright (C) 2008 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -305,7 +305,7 @@ INTERNAL int imail(struct zint_symbol *symbol, unsigned char source[], int lengt return ZINT_ERROR_INVALID_DATA; } - zip_len = strlen(zip); + zip_len = (int) strlen(zip); if (zip_len != 0 && zip_len != 5 && zip_len != 9 && zip_len != 11) { strcpy(symbol->errtxt, "453: Invalid ZIP code"); return ZINT_ERROR_INVALID_DATA; @@ -342,7 +342,7 @@ INTERNAL int imail(struct zint_symbol *symbol, unsigned char source[], int lengt /* and then the rest */ - for (read = 2, len = strlen(tracker); read < len; read++) { + for (read = 2, len = (int) strlen(tracker); read < len; read++) { large_mul_u64(&accum, 10); large_add_u64(&accum, ctoi(tracker[read])); @@ -421,7 +421,7 @@ INTERNAL int imail(struct zint_symbol *symbol, unsigned char source[], int lengt /* Translate 4-state data pattern to symbol */ read = 0; - for (i = 0, len = strlen(data_pattern); i < len; i++) { + for (i = 0, len = (int) strlen(data_pattern); i < len; i++) { if ((data_pattern[i] == '1') || (data_pattern[i] == '0')) { set_module(symbol, 0, read); } diff --git a/backend/library.c b/backend/library.c index 395e6c3c..cb8f62a7 100644 --- a/backend/library.c +++ b/backend/library.c @@ -1539,7 +1539,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { unsigned char *buffer; long fileLen; size_t n; - int nRead = 0; + size_t nRead = 0; int ret; if (!symbol) return ZINT_ERROR_INVALID_DATA; @@ -1555,7 +1555,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { } else { file = fopen(filename, "rb"); if (!file) { - sprintf(symbol->errtxt, "229: Unable to read input file (%.30s)", strerror(errno)); + sprintf(symbol->errtxt, "229: Unable to read input file (%d: %.30s)", errno, strerror(errno)); return error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); } file_opened = 1; @@ -1593,7 +1593,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { do { n = fread(buffer + nRead, 1, fileLen - nRead, file); if (ferror(file)) { - sprintf(symbol->errtxt, "241: Input file read error (%.30s)", strerror(errno)); + sprintf(symbol->errtxt, "241: Input file read error (%d: %.30s)", errno, strerror(errno)); if (file_opened) { fclose(file); } @@ -1601,7 +1601,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) { return error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA); } nRead += n; - } while (!feof(file) && (0 < n) && (nRead < fileLen)); + } while (!feof(file) && (0 < n) && ((long) nRead < fileLen)); if (file_opened) { fclose(file); diff --git a/backend/mailmark.c b/backend/mailmark.c index 1411cd02..7db032f7 100644 --- a/backend/mailmark.c +++ b/backend/mailmark.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2008 - 2020 Robin Stuart + Copyright (C) 2008 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -31,12 +31,12 @@ */ /* vim: set ts=4 sw=4 et : */ -/* +/* * Developed in accordance with "Royal Mail Mailmark barcode C encoding and deconding instructions" * (https://www.royalmail.com/sites/default/files/Mailmark-4-state-barcode-C-encoding-and-decoding-instructions-Sept-2015.pdf) * and "Royal Mail Mailmark barcode L encoding and decoding" * (https://www.royalmail.com/sites/default/files/Mailmark-4-state-barcode-L-encoding-and-decoding-instructions-Sept-2015.pdf) - * + * */ #include @@ -82,7 +82,7 @@ static const unsigned short extender_group_l[26] = { static int verify_character(char input, char type) { int val = 0; - + switch (type) { case 'F': val = posn(SET_F, input); @@ -97,7 +97,7 @@ static int verify_character(char input, char type) { val = posn(SET_S, input); break; } - + if (val == -1) { return 0; } else { @@ -108,7 +108,7 @@ static int verify_character(char input, char type) { static int verify_postcode(char* postcode, int type) { int i; char pattern[11]; - + strcpy(pattern, postcode_format[type - 1]); for (i = 0; i < 9; i++) { @@ -122,13 +122,13 @@ static int verify_postcode(char* postcode, int type) { /* Royal Mail Mailmark */ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int length) { - + char local_source[28]; int format; int version_id; int mail_class; int supply_chain_id; - long item_id; + unsigned int item_id; char postcode[10]; int postcode_type; char pattern[10]; @@ -138,39 +138,39 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le unsigned char data[26]; int data_top, data_step; unsigned char check[7]; - short int extender[27]; + unsigned int extender[27]; char bar[80]; int check_count; int i, j, len; rs_t rs; - + if (length > 26) { strcpy(symbol->errtxt, "580: Input too long"); return ZINT_ERROR_TOO_LONG; } - + strcpy(local_source, (char*) source); - + if (length < 22) { for (i = length; i <= 22; i++) { strcat(local_source, " "); } length = 22; } - + if ((length > 22) && (length < 26)) { for (i = length; i <= 26; i++) { strcat(local_source, " "); } length = 26; - } - + } + to_upper((unsigned char*) local_source); - + if (symbol->debug & ZINT_DEBUG_PRINT) { printf("Producing Mailmark %s\n", local_source); } - + if (is_sane(RUBIDIUM, (unsigned char *) local_source, length) != 0) { strcpy(symbol->errtxt, "581: Invalid characters in input data"); return ZINT_ERROR_INVALID_DATA; @@ -182,21 +182,21 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le strcpy(symbol->errtxt, "582: Invalid format"); return ZINT_ERROR_INVALID_DATA; } - + // Version ID is in the range 1-4 version_id = ctoi(local_source[1]) - 1; if ((version_id < 0) || (version_id > 3)) { strcpy(symbol->errtxt, "583: Invalid Version ID"); return ZINT_ERROR_INVALID_DATA; } - + // Class is in the range 0-9,A-E mail_class = ctoi(local_source[2]); if ((mail_class < 0) || (mail_class > 14)) { strcpy(symbol->errtxt, "584: Invalid Class"); return ZINT_ERROR_INVALID_DATA; } - + // Supply Chain ID is 2 digits for barcode C and 6 digits for barcode L supply_chain_id = 0; for (i = 3; i < (length - 17); i++) { @@ -208,28 +208,28 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le return ZINT_ERROR_INVALID_DATA; } } - + // Item ID is 8 digits item_id = 0; for (i = length - 17; i < (length - 9); i++) { if ((local_source[i] >= '0') && (local_source[i] <= '9')) { item_id *= 10; - item_id += (long) ctoi(local_source[i]); + item_id += ctoi(local_source[i]); } else { strcpy(symbol->errtxt, "586: Invalid Item ID"); return ZINT_ERROR_INVALID_DATA; } } - + // Separate Destination Post Code plus DPS field for (i = 0; i < 9; i++) { postcode[i] = local_source[(length - 9) + i]; } postcode[9] = '\0'; - + // Detect postcode type - /* postcode_type is used to select which format of postcode - * + /* postcode_type is used to select which format of postcode + * * 1 = FNFNLLNLS * 2 = FFNNLLNLS * 3 = FFNNNLLNL @@ -238,7 +238,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le * 6 = FNNNLLNLS * 7 = International designation */ - + if (strcmp(postcode, "XY11 ") == 0) { postcode_type = 7; } else { @@ -266,7 +266,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le } } } - + // Verify postcode type if (postcode_type != 7) { if (verify_postcode(postcode, postcode_type) != 0) { @@ -274,7 +274,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le return ZINT_ERROR_INVALID_DATA; } } - + // Convert postcode to internal user field large_load_u64(&destination_postcode, 0); @@ -330,7 +330,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le large_add(&destination_postcode, &b); } } - + // Conversion from Internal User Fields to Consolidated Data Value // Set CDV to 0 large_load_u64(&cdv, 0); @@ -344,7 +344,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le // Add Item ID large_add_u64(&cdv, item_id); - if (length == 22) { + if (length == 22) { // Barcode C - Multiply by 100 large_mul_u64(&cdv, 100); } else { @@ -378,8 +378,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le printf("CDV: "); large_print(&cdv); } - - + if (length == 22) { data_top = 15; data_step = 8; @@ -389,27 +388,27 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le data_step = 10; check_count = 7; } - + // Conversion from Consolidated Data Value to Data Numbers for (j = data_top; j >= (data_step + 1); j--) { data[j] = (unsigned char) large_div_u64(&cdv, 32); } - + for (j = data_step; j >= 0; j--) { data[j] = (unsigned char) large_div_u64(&cdv, 30); } - + // Generation of Reed-Solomon Check Numbers rs_init_gf(&rs, 0x25); rs_init_code(&rs, check_count, 1); rs_encode(&rs, (data_top + 1), data, check); - + // Append check digits to data for (i = 1; i <= check_count; i++) { data[data_top + i] = check[check_count - i]; } - + if (symbol->debug & ZINT_DEBUG_PRINT) { printf("Codewords: "); for (i = 0; i <= data_top + check_count; i++) { @@ -417,7 +416,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le } printf("\n"); } - + // Conversion from Data Numbers and Check Numbers to Data Symbols and Check Symbols for (i = 0; i <= data_step; i++) { data[i] = data_symbol_even[data[i]]; @@ -425,7 +424,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le for (i = data_step + 1; i <= (data_top + check_count); i++) { data[i] = data_symbol_odd[data[i]]; } - + // Conversion from Data Symbols and Check Symbols to Extender Groups for (i = 0; i < length; i++) { if (length == 22) { @@ -434,13 +433,13 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le extender[extender_group_l[i]] = data[i]; } } - + // Conversion from Extender Groups to Bar Identifiers strcpy(bar, ""); - + for (i = 0; i < length; i++) { for (j = 0; j < 3; j++) { - switch(extender[i] & 0x24) { + switch (extender[i] & 0x24) { case 0x24: strcat(bar, "F"); break; @@ -465,13 +464,13 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le extender[i] = extender[i] << 1; } } - + bar[(length * 3)] = '\0'; - + if (symbol->debug & ZINT_DEBUG_PRINT) { printf("Bar pattern: %s\n", bar); } - + /* Translate 4-state data pattern to symbol */ j = 0; for (i = 0, len = (int) strlen(bar); i < len; i++) { @@ -491,6 +490,6 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le symbol->rows = 3; symbol->width = j - 1; - + return 0; } diff --git a/backend/output.c b/backend/output.c index a8534b3f..c29b6c7f 100644 --- a/backend/output.c +++ b/backend/output.c @@ -51,13 +51,13 @@ INTERNAL int output_check_colour_options(struct zint_symbol *symbol) { to_upper((unsigned char *) symbol->fgcolour); to_upper((unsigned char *) symbol->bgcolour); - error_number = is_sane(SSET, (unsigned char *) symbol->fgcolour, strlen(symbol->fgcolour)); + error_number = is_sane(SSET, (unsigned char *) symbol->fgcolour, (int) strlen(symbol->fgcolour)); if (error_number == ZINT_ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "653: Malformed foreground colour target"); return ZINT_ERROR_INVALID_OPTION; } - error_number = is_sane(SSET, (unsigned char *) symbol->bgcolour, strlen(symbol->bgcolour)); + error_number = is_sane(SSET, (unsigned char *) symbol->bgcolour, (int) strlen(symbol->bgcolour)); if (error_number == ZINT_ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "654: Malformed background colour target"); return ZINT_ERROR_INVALID_OPTION; @@ -432,7 +432,7 @@ INTERNAL int output_process_upcean(struct zint_symbol *symbol, int *p_main_width int comp_offset; /* Whitespace offset (if any) of main linear symbol due to having composite */ int upceanflag; /* UPC/EAN type flag */ int i, j, latch; - int text_length = ustrlen(symbol->text); + int text_length = (int) ustrlen(symbol->text); latch = 0; j = 0; diff --git a/backend/pcx.c b/backend/pcx.c index a99343ee..e0ba07b6 100644 --- a/backend/pcx.c +++ b/backend/pcx.c @@ -3,7 +3,7 @@ /* libzint - the open source barcode library - Copyright (C) 2009 - 2020 Robin Stuart + Copyright (C) 2009 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -32,8 +32,8 @@ */ /* vim: set ts=4 sw=4 et : */ +#include #include -#include #include "common.h" #include "pcx.h" /* PCX header structure */ #include @@ -52,7 +52,7 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) int bytes_per_line = symbol->bitmap_width + (symbol->bitmap_width & 1); // Must be even unsigned char previous; #ifdef _MSC_VER - unsigned char* rle_row; + unsigned char *rle_row; #endif #ifndef _MSC_VER @@ -70,7 +70,6 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); - header.manufacturer = 10; // ZSoft header.version = 5; // Version 3.0 header.encoding = 1; // Run length encoding @@ -103,26 +102,26 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) if (symbol->output_options & BARCODE_STDOUT) { #ifdef _MSC_VER if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - strcpy(symbol->errtxt, "620: Can't open output file"); + sprintf(symbol->errtxt, "620: Can't open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } #endif pcx_file = stdout; } else { if (!(pcx_file = fopen(symbol->outfile, "wb"))) { - strcpy(symbol->errtxt, "621: Can't open output file"); + sprintf(symbol->errtxt, "621: Can't open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } } - fwrite(&header, sizeof (pcx_header_t), 1, pcx_file); + fwrite(&header, sizeof(pcx_header_t), 1, pcx_file); for (row = 0; row < symbol->bitmap_height; row++) { for (colour = 0; colour < 3; colour++) { for (column = 0; column < symbol->bitmap_width; column++) { switch (colour) { case 0: - switch(pixelbuf[(row * symbol->bitmap_width) + column]) { + switch (pixelbuf[(row * symbol->bitmap_width) + column]) { case 'W': // White case 'M': // Magenta case 'R': // Red @@ -144,7 +143,7 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) } break; case 1: - switch(pixelbuf[(row * symbol->bitmap_width) + column]) { + switch (pixelbuf[(row * symbol->bitmap_width) + column]) { case 'W': // White case 'C': // Cyan case 'Y': // Yellow @@ -166,7 +165,7 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) } break; case 2: - switch(pixelbuf[(row * symbol->bitmap_width) + column]) { + switch (pixelbuf[(row * symbol->bitmap_width) + column]) { case 'W': // White case 'C': // Cyan case 'B': // Blue diff --git a/backend/plessey.c b/backend/plessey.c index caeecd45..24ff6185 100644 --- a/backend/plessey.c +++ b/backend/plessey.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2008 - 2020 Robin Stuart + Copyright (C) 2008 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -44,8 +44,8 @@ static const char *PlessTable[16] = { }; static const char *MSITable[10] = { - "12121212", "12121221", "12122112", "12122121", "12211212", "12211221", - "12212112", "12212121", "21121212", "21121221" + "12121212", "12121221", "12122112", "12122121", "12211212", + "12211221", "12212112", "12212121", "21121212", "21121221" }; /* Not MSI/Plessey but the older Plessey standard */ @@ -54,7 +54,7 @@ INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], int len int i; unsigned char *checkptr; static const char grid[9] = {1, 1, 1, 1, 0, 1, 0, 0, 1}; - char dest[1024]; /* 8 + 65 * 8 + 8 * 2 + 9 + 1 ~ 1024 */ + char dest[554]; /* 8 + 65 * 8 + 8 * 2 + 9 + 1 = 554 */ int error_number; if (length > 65) { @@ -105,56 +105,71 @@ INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], int len strcat(dest, "331311313"); expand(symbol, dest); - ustrcpy(symbol->text, source); + + symbol->text[0] = '\0'; + ustrncat(symbol->text, source, length); + free(checkptr); return error_number; } +/* Modulo 10 check digit - Luhn algorithm + See https://en.wikipedia.org/wiki/Luhn_algorithm */ +static char msi_check_digit_mod10(const unsigned char source[], const int length) { + static const int vals[2][10] = { + { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 }, /* Doubled and digits summed */ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, /* Single */ + }; + int i, x = 0, undoubled = 0; + + for (i = length - 1; i >= 0; i--) { + x += vals[undoubled][ctoi(source[i])]; + if (x > 32767 - 20) { + x %= 10; /* Prevent overflow */ + } + undoubled = !undoubled; + } + + return itoc((10 - x % 10) % 10); +} + +/* Modulo 11 check digit - IBM weight system wrap = 7, NCR system wrap = 9 + See https://en.wikipedia.org/wiki/MSI_Barcode */ +static char msi_check_digit_mod11(const unsigned char source[], const int length, const int wrap) { + int i, x = 0, weight = 2; + + for (i = length - 1; i >= 0; i--) { + x += weight * ctoi(source[i]); + if (x > 32767 - 200) { + x %= 11; /* Prevent overflow */ + } + weight++; + if (weight > wrap) { + weight = 2; + } + } + + return itoc((11 - x % 11) % 11); /* Will return 'A' for 10 */ +} + /* Plain MSI Plessey - does not calculate any check character */ -static int msi_plessey(struct zint_symbol *symbol, unsigned char source[], const int length) { +static void msi_plessey(struct zint_symbol *symbol, const unsigned char source[], const int length, char dest[]) { int i; - char dest[512]; /* 2 + 55 * 8 + 3 + 1 ~ 512 */ - - if (length > 55) { - strcpy(symbol->errtxt, "372: Input too long"); - return ZINT_ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); for (i = 0; i < length; i++) { lookup(NEON, MSITable, source[i], dest); } - /* Stop character */ - strcat(dest, "121"); - - expand(symbol, dest); - ustrcpy(symbol->text, source); - return 0; + symbol->text[0] = '\0'; + ustrncat(symbol->text, source, length); } -/* MSI Plessey with Modulo 10 check digit - algorithm from Barcode Island - * http://www.barcodeisland.com/ */ -static int msi_plessey_mod10(struct zint_symbol *symbol, unsigned char source[], int length) { - - int i, wright, pump, n; - unsigned long dau, pedwar; - char un[32], tri[32]; - int error_number, h; - char dest[1000]; - - error_number = 0; - - if (length > 18) { - strcpy(symbol->errtxt, "373: Input too long"); - return ZINT_ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); +/* MSI Plessey with Modulo 10 check digit */ +static void msi_plessey_mod10(struct zint_symbol *symbol, const unsigned char source[], const int length, + const int no_checktext, char dest[]) { + int i; + char check_digit; /* draw data section */ for (i = 0; i < length; i++) { @@ -162,310 +177,122 @@ static int msi_plessey_mod10(struct zint_symbol *symbol, unsigned char source[], } /* calculate check digit */ - wright = 0; - n = !(length & 1); - for (i = n; i < length; i += 2) { - un[wright++] = source[i]; - } - un[wright] = '\0'; - - dau = strtoul(un, NULL, 10); - dau *= 2; - - sprintf(tri, "%lu", dau); - - pedwar = 0; - h = (int) strlen(tri); - for (i = 0; i < h; i++) { - pedwar += ctoi(tri[i]); - } - - n = length & 1; - for (i = n; i < length; i += 2) { - pedwar += ctoi(source[i]); - } - - pump = (10 - pedwar % 10); - if (pump == 10) { - pump = 0; - } + check_digit = msi_check_digit_mod10(source, length); /* draw check digit */ - lookup(NEON, MSITable, itoc(pump), dest); + lookup(NEON, MSITable, check_digit, dest); - /* Stop character */ - strcat(dest, "121"); - expand(symbol, dest); - - ustrcpy(symbol->text, source); - symbol->text[length] = itoc(pump); - symbol->text[length + 1] = '\0'; - return error_number; + symbol->text[0] = '\0'; + ustrncat(symbol->text, source, length); + if (!no_checktext) { + symbol->text[length] = check_digit; + symbol->text[length + 1] = '\0'; + } } -/* MSI Plessey with two Modulo 10 check digits - algorithm from - * Barcode Island http://www.barcodeisland.com/ */ -static int msi_plessey_mod1010(struct zint_symbol *symbol, unsigned char source[], const int src_len) { +/* MSI Plessey with two Modulo 10 check digits */ +static void msi_plessey_mod1010(struct zint_symbol *symbol, const unsigned char source[], const int length, + const int no_checktext, char dest[]) { - int i, n, wright, pump; - unsigned long dau, pedwar, chwech; - char un[32], tri[32]; - int error_number, h; - char dest[1000]; + int i; + unsigned char temp[65 + 2 + 1]; - error_number = 0; - - if (src_len > 18) { - /* No Entry Stack Smashers! limit because of str->number conversion*/ - strcpy(symbol->errtxt, "374: Input too long"); - return ZINT_ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); + /* Append check digits */ + temp[0] = '\0'; + ustrncat(temp, source, length); + temp[length] = msi_check_digit_mod10(source, length); + temp[length + 1] = msi_check_digit_mod10(temp, length + 1); + temp[length + 2] = '\0'; /* draw data section */ - for (i = 0; i < src_len; i++) { + for (i = 0; i < length + 2; i++) { + lookup(NEON, MSITable, temp[i], dest); + } + + if (no_checktext) { + symbol->text[0] = '\0'; + ustrncat(symbol->text, source, length); + } else { + ustrcpy(symbol->text, temp); + } +} + +/* MSI Plessey with Modulo 11 check digit */ +static void msi_plessey_mod11(struct zint_symbol *symbol, const unsigned char source[], const int length, + const int no_checktext, const int wrap, char dest[]) { + /* Uses the IBM weight system if wrap = 7, and the NCR system if wrap = 9 */ + int i; + char check_digit; + + /* draw data section */ + for (i = 0; i < length; i++) { lookup(NEON, MSITable, source[i], dest); } - /* calculate first check digit */ - wright = 0; - - n = !(src_len & 1); - for (i = n; i < src_len; i += 2) { - un[wright++] = source[i]; - } - un[wright] = '\0'; - - dau = strtoul(un, NULL, 10); - dau *= 2; - - sprintf(tri, "%lu", dau); - - pedwar = 0; - h = (int) strlen(tri); - for (i = 0; i < h; i++) { - pedwar += ctoi(tri[i]); - } - - n = src_len & 1; - for (i = n; i < src_len; i += 2) { - pedwar += ctoi(source[i]); - } - - pump = 10 - pedwar % 10; - if (pump == 10) { - pump = 0; - } - - /* calculate second check digit */ - wright = 0; - n = src_len & 1; - for (i = n; i < src_len; i += 2) { - un[wright++] = source[i]; - } - un[wright++] = itoc(pump); - un[wright] = '\0'; - - dau = strtoul(un, NULL, 10); - dau *= 2; - - sprintf(tri, "%lu", dau); - - pedwar = 0; - h = (int) strlen(tri); - for (i = 0; i < h; i++) { - pedwar += ctoi(tri[i]); - } - - - i = !(src_len & 1); - for (; i < src_len; i += 2) { - pedwar += ctoi(source[i]); - } - - chwech = 10 - pedwar % 10; - if (chwech == 10) { - chwech = 0; - } - - /* Draw check digits */ - lookup(NEON, MSITable, itoc(pump), dest); - lookup(NEON, MSITable, itoc(chwech), dest); - - /* Stop character */ - strcat(dest, "121"); - - expand(symbol, dest); - - ustrcpy(symbol->text, source); - symbol->text[src_len] = itoc(pump); - symbol->text[src_len + 1] = itoc(chwech); - symbol->text[src_len + 2] = '\0'; - - return error_number; -} - -/* Calculate a Modulo 11 check digit using the system discussed on Wikipedia - - see http://en.wikipedia.org/wiki/Talk:MSI_Barcode */ -static int msi_plessey_mod11(struct zint_symbol *symbol, unsigned char source[], const int src_len) { - /* uses the IBM weight system */ - int i, weight, check; - unsigned long x; - int error_number; - char dest[1000]; - - error_number = 0; - - if (src_len > 55) { - strcpy(symbol->errtxt, "375: Input too long"); - return ZINT_ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); - - /* draw data section */ - for (i = 0; i < src_len; i++) { - lookup(NEON, MSITable, source[i], dest); - } - - /* calculate check digit */ - x = 0; - weight = 2; - for (i = src_len - 1; i >= 0; i--) { - x += (long) (weight * ctoi(source[i])); - weight++; - if (weight > 7) { - weight = 2; - } - } - - check = (11 - (x % 11)) % 11; - if (check == 10) { + /* Append check digit */ + check_digit = msi_check_digit_mod11(source, length, wrap); + if (check_digit == 'A') { lookup(NEON, MSITable, '1', dest); lookup(NEON, MSITable, '0', dest); } else { - lookup(NEON, MSITable, itoc(check), dest); + lookup(NEON, MSITable, check_digit, dest); } - /* stop character */ - strcat(dest, "121"); - - expand(symbol, dest); - - ustrcpy(symbol->text, source); - if (check == 10) { - strcat((char*) symbol->text, "10"); - } else { - symbol->text[src_len] = itoc(check); - symbol->text[src_len + 1] = '\0'; - } - - return error_number; -} - -/* Combining the Barcode Island and Wikipedia code - * Verified against http://www.bokai.com/BarcodeJSP/applet/BarcodeSampleApplet.htm */ -static int msi_plessey_mod1110(struct zint_symbol *symbol, unsigned char source[], const int src_len) { - /* Weighted using the IBM system */ - int i, weight, check, wright, pump; - unsigned long x, dau, pedwar; - int h; - int si; - char un[32], tri[32]; - int error_number; - char dest[1000]; - unsigned char temp[32]; - int temp_len; - - error_number = 0; - - if (src_len > 18) { - strcpy(symbol->errtxt, "376: Input too long"); - return ZINT_ERROR_TOO_LONG; - } - - /* start character */ - strcpy(dest, "21"); - - /* draw data section */ - for (i = 0; i < src_len; i++) { - lookup(NEON, MSITable, source[i], dest); - } - - /* calculate first (mod 11) digit */ - x = 0; - weight = 2; - for (si = src_len - 1; si >= 0; si--) { - x += (long) (weight * ctoi(source[si])); - weight++; - if (weight > 7) { - weight = 2; + symbol->text[0] = '\0'; + ustrncat(symbol->text, source, length); + if (!no_checktext) { + if (check_digit == 'A') { + ustrcat(symbol->text, "10"); + } else { + symbol->text[length] = check_digit; + symbol->text[length + 1] = '\0'; } } +} - check = (11 - (x % 11)) % 11; - ustrcpy(temp, source); - temp_len = src_len; - if (check == 10) { - lookup(NEON, MSITable, '1', dest); - lookup(NEON, MSITable, '0', dest); - strcat((char*) temp, "10"); - temp_len += 2; +/* MSI Plessey with Modulo 11 check digit and Modulo 10 check digit */ +static void msi_plessey_mod1110(struct zint_symbol *symbol, const unsigned char source[], const int length, + const int no_checktext, const int wrap, char dest[]) { + /* Uses the IBM weight system if wrap = 7, and the NCR system if wrap = 9 */ + int i; + char check_digit; + unsigned char temp[65 + 3 + 1]; + int temp_len = length; + + temp[0] = '\0'; + ustrncat(temp, source, length); + + /* Append first (mod 11) digit */ + check_digit = msi_check_digit_mod11(source, length, wrap); + if (check_digit == 'A') { + temp[temp_len++] = '1'; + temp[temp_len++] = '0'; } else { - lookup(NEON, MSITable, itoc(check), dest); - temp[temp_len++] = itoc(check); - temp[temp_len] = '\0'; + temp[temp_len++] = check_digit; } - /* calculate second (mod 10) check digit */ - wright = 0; - i = !(temp_len & 1); - for (; i < temp_len; i += 2) { - un[wright++] = temp[i]; - } - un[wright] = '\0'; + /* Append second (mod 10) check digit */ + temp[temp_len] = msi_check_digit_mod10(temp, temp_len); + temp[++temp_len] = '\0'; - dau = strtoul(un, NULL, 10); - dau *= 2; - - sprintf(tri, "%lu", dau); - - pedwar = 0; - h = (int) strlen(tri); - for (i = 0; i < h; i++) { - pedwar += ctoi(tri[i]); + /* draw data section */ + for (i = 0; i < temp_len; i++) { + lookup(NEON, MSITable, temp[i], dest); } - i = temp_len & 1; - for (; i < temp_len; i += 2) { - pedwar += ctoi(temp[i]); + if (no_checktext) { + symbol->text[0] = '\0'; + ustrncat(symbol->text, source, length); + } else { + ustrcpy(symbol->text, temp); } - - pump = 10 - pedwar % 10; - if (pump == 10) { - pump = 0; - } - - /* draw check digit */ - lookup(NEON, MSITable, itoc(pump), dest); - - /* stop character */ - strcat(dest, "121"); - expand(symbol, dest); - - temp[temp_len++] = itoc(pump); - temp[temp_len] = '\0'; - - - ustrcpy(symbol->text, temp); - return error_number; } INTERNAL int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length) { int error_number; + char dest[550]; /* 2 + 65 * 8 + 3 * 8 + 3 + 1 = 550 */ + int check_option = symbol->option_2; + int no_checktext = 0; error_number = is_sane(NEON, source, length); if (error_number != 0) { @@ -473,23 +300,43 @@ INTERNAL int msi_handle(struct zint_symbol *symbol, unsigned char source[], int return ZINT_ERROR_INVALID_DATA; } - - if ((symbol->option_2 < 0) || (symbol->option_2 > 4)) { - symbol->option_2 = 0; + if (length > 65) { + strcpy(symbol->errtxt, "372: Input too long"); + return ZINT_ERROR_TOO_LONG; } - switch (symbol->option_2) { - case 0: error_number = msi_plessey(symbol, source, length); + if (check_option >= 11 && check_option <= 16) { /* +10 means don't print check digits in HRT */ + check_option -= 10; + no_checktext = 1; + } + if ((check_option < 0) || (check_option > 6)) { + check_option = 0; + } + + /* Start character */ + strcpy(dest, "21"); + + switch (check_option) { + case 0: msi_plessey(symbol, source, length, dest); break; - case 1: error_number = msi_plessey_mod10(symbol, source, length); + case 1: msi_plessey_mod10(symbol, source, length, no_checktext, dest); break; - case 2: error_number = msi_plessey_mod1010(symbol, source, length); + case 2: msi_plessey_mod1010(symbol, source, length, no_checktext, dest); break; - case 3: error_number = msi_plessey_mod11(symbol, source, length); + case 3: msi_plessey_mod11(symbol, source, length, no_checktext, 7 /*IBM wrap*/, dest); break; - case 4: error_number = msi_plessey_mod1110(symbol, source, length); + case 4: msi_plessey_mod1110(symbol, source, length, no_checktext, 7 /*IBM wrap*/, dest); + break; + case 5: msi_plessey_mod11(symbol, source, length, no_checktext, 9 /*NCR wrap*/, dest); + break; + case 6: msi_plessey_mod1110(symbol, source, length, no_checktext, 9 /*NCR wrap*/, dest); break; } + /* Stop character */ + strcat(dest, "121"); + + expand(symbol, dest); + return error_number; } diff --git a/backend/png.c b/backend/png.c index 520ab2de..578e8f6d 100644 --- a/backend/png.c +++ b/backend/png.c @@ -31,6 +31,9 @@ */ /* vim: set ts=4 sw=4 et : */ +#ifndef NO_PNG + +#include #include #ifdef _MSC_VER #include @@ -39,7 +42,6 @@ #endif #include "common.h" -#ifndef NO_PNG #include #include #include @@ -233,14 +235,14 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) if (symbol->output_options & BARCODE_STDOUT) { #ifdef _MSC_VER if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - strcpy(symbol->errtxt, "631: Can't open output file"); + sprintf(symbol->errtxt, "631: Can't open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } #endif graphic->outfile = stdout; } else { if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) { - strcpy(symbol->errtxt, "632: Can't open output file"); + sprintf(symbol->errtxt, "632: Can't open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } } @@ -343,4 +345,7 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) return 0; } +#else +/* https://stackoverflow.com/a/26541331/664741 Suppresses gcc warning ISO C forbids an empty translation unit */ +typedef int make_iso_compilers_happy; #endif /* NO_PNG */ diff --git a/backend/postal.c b/backend/postal.c index fec8f374..41280ba9 100644 --- a/backend/postal.c +++ b/backend/postal.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2008 - 2020 Robin Stuart + Copyright (C) 2008 - 2021 Robin Stuart Including bug fixes by Bryan Hatton Redistribution and use in source and binary forms, with or without @@ -129,7 +129,7 @@ INTERNAL int post_plot(struct zint_symbol *symbol, unsigned char source[], int l } writer = 0; - h = strlen(height_pattern); + h = (int) strlen(height_pattern); for (loopey = 0; loopey < h; loopey++) { if (height_pattern[loopey] == 'L') { set_module(symbol, 0, writer); @@ -191,7 +191,7 @@ INTERNAL int planet_plot(struct zint_symbol *symbol, unsigned char source[], int } writer = 0; - h = strlen(height_pattern); + h = (int) strlen(height_pattern); for (loopey = 0; loopey < h; loopey++) { if (height_pattern[loopey] == 'L') { set_module(symbol, 0, writer); @@ -342,7 +342,7 @@ INTERNAL int royal_plot(struct zint_symbol *symbol, unsigned char source[], int /*check = */rm4scc(source, height_pattern, length); writer = 0; - h = strlen(height_pattern); + h = (int) strlen(height_pattern); for (loopey = 0; loopey < h; loopey++) { if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { set_module(symbol, 0, writer); @@ -392,7 +392,7 @@ INTERNAL int kix_code(struct zint_symbol *symbol, unsigned char source[], int le } writer = 0; - h = strlen(height_pattern); + h = (int) strlen(height_pattern); for (loopey = 0; loopey < h; loopey++) { if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { set_module(symbol, 0, writer); @@ -448,7 +448,7 @@ INTERNAL int daft_code(struct zint_symbol *symbol, unsigned char source[], int l } writer = 0; - h = strlen(height_pattern); + h = (int) strlen(height_pattern); for (loopey = 0; loopey < h; loopey++) { if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { set_module(symbol, 0, writer); @@ -577,7 +577,7 @@ INTERNAL int japan_post(struct zint_symbol *symbol, unsigned char source[], int /* Resolve pattern to 4-state symbols */ writer = 0; - h = strlen(pattern); + h = (int) strlen(pattern); for (loopey = 0; loopey < h; loopey++) { if ((pattern[loopey] == '2') || (pattern[loopey] == '1')) { set_module(symbol, 0, writer); diff --git a/backend/ps.c b/backend/ps.c index aa1a4b56..c2a9ab9c 100644 --- a/backend/ps.c +++ b/backend/ps.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2009-2020 Robin Stuart + Copyright (C) 2009-2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -31,6 +31,7 @@ */ /* vim: set ts=4 sw=4 et : */ +#include #include #include #include @@ -43,7 +44,7 @@ static void colour_to_pscolor(int option, int colour, char* output) { strcpy(output, ""); if ((option & CMYK_COLOUR) == 0) { // Use RGB colour space - switch(colour) { + switch (colour) { case 1: // Cyan strcat(output, "0.00 1.00 1.00"); break; @@ -72,7 +73,7 @@ static void colour_to_pscolor(int option, int colour, char* output) { strcat(output, " setrgbcolor"); } else { // Use CMYK colour space - switch(colour) { + switch (colour) { case 1: // Cyan strcat(output, "1.00 0.00 0.00 0.00"); break; @@ -169,7 +170,7 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { feps = fopen(symbol->outfile, "w"); } if (feps == NULL) { - strcpy(symbol->errtxt, "645: Could not open output file"); + sprintf(symbol->errtxt, "645: Could not open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } @@ -260,13 +261,15 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { /* Start writing the header */ fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n"); if (ZINT_VERSION_BUILD) { - fprintf(feps, "%%%%Creator: Zint %d.%d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE, ZINT_VERSION_BUILD); + fprintf(feps, "%%%%Creator: Zint %d.%d.%d.%d\n", + ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE, ZINT_VERSION_BUILD); } else { fprintf(feps, "%%%%Creator: Zint %d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE); } fprintf(feps, "%%%%Title: Zint Generated Symbol\n"); fprintf(feps, "%%%%Pages: 0\n"); - fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", (int) ceil(symbol->vector->width), (int) ceil(symbol->vector->height)); + fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", + (int) ceil(symbol->vector->width), (int) ceil(symbol->vector->height)); fprintf(feps, "%%%%EndComments\n"); /* Definitions */ @@ -314,7 +317,8 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { fprintf(feps, "%s\n", ps_color); } colour_rect_counter++; - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", rect->height, (symbol->vector->height - rect->y) - rect->height, rect->x, rect->width); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", + rect->height, (symbol->vector->height - rect->y) - rect->height, rect->x, rect->width); fprintf(feps, "TE\n"); } rect = rect->next; @@ -323,7 +327,8 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { } else { rect = symbol->vector->rectangles; while (rect) { - fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", rect->height, (symbol->vector->height - rect->y) - rect->height, rect->x, rect->width); + fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", + rect->height, (symbol->vector->height - rect->y) - rect->height, rect->x, rect->width); fprintf(feps, "TE\n"); rect = rect->next; } @@ -366,7 +371,8 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { ex = hex->x + half_radius; fx = hex->x - half_radius; } - fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy); + fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", + ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy); hex = hex->next; } @@ -383,7 +389,8 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { if ((symbol->output_options & CMYK_COLOUR) == 0) { fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper); } else { - fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_paper, magenta_paper, yellow_paper, black_paper); + fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", + cyan_paper, magenta_paper, yellow_paper, black_paper); } fprintf(feps, "%.2f %.2f %.2f TD\n", circle->x, (symbol->vector->height - circle->y), radius); if (circle->next) { @@ -405,12 +412,14 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { string = symbol->vector->strings; if (string) { - if ((symbol->output_options & BOLD_TEXT) && (!is_extendable(symbol->symbology) || (symbol->output_options & SMALL_TEXT))) { + if ((symbol->output_options & BOLD_TEXT) + && (!is_extendable(symbol->symbology) || (symbol->output_options & SMALL_TEXT))) { font = "Helvetica-Bold"; } else { font = "Helvetica"; } - if (iso_latin1) { /* Change encoding to ISO 8859-1, see Postscript Language Reference Manual 2nd Edition Example 5.6 */ + if (iso_latin1) { + /* Change encoding to ISO 8859-1, see Postscript Language Reference Manual 2nd Edition Example 5.6 */ fprintf(feps, "/%s findfont\n", font); fprintf(feps, "dup length dict begin\n"); fprintf(feps, "{1 index /FID ne {def} {pop pop} ifelse} forall\n"); @@ -425,7 +434,8 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) { fprintf(feps, "matrix currentmatrix\n"); fprintf(feps, "/%s findfont\n", font); fprintf(feps, "%.2f scalefont setfont\n", string->fsize); - fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", string->x, (symbol->vector->height - string->y)); + fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", + string->x, (symbol->vector->height - string->y)); if (string->halign == 0 || string->halign == 2) { /* Need width for middle or right align */ fprintf(feps, " (%s) stringwidth\n", ps_string); } diff --git a/backend/qr.c b/backend/qr.c index f36ebc8b..0c24cf7e 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -2175,7 +2175,7 @@ static void micro_populate_grid(unsigned char *grid, const int size, const char int n, i; int y; - n = strlen(full_stream); + n = (int) strlen(full_stream); y = size - 1; i = 0; do { diff --git a/backend/raster.c b/backend/raster.c index 5f9d1d38..a36085b8 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -39,16 +39,6 @@ #include #include #include -/* ceilf, floorf, roundf not before MSVC++2013 (C++ 12.0) */ -#if _MSC_VER < 1800 -#define ceilf (float) ceil -#define floorf (float) floor -#define roundf(arg) (float) floor((arg) + 0.5f) -#endif -/* For Visual C++ 6 suppress conversion from int to float warning */ -#if _MSC_VER == 1200 -#pragma warning(disable: 4244) -#endif #endif /* _MSC_VER */ #include "common.h" @@ -438,7 +428,7 @@ static void draw_string(unsigned char *pixbuf, const unsigned char input_string[ } letter_width += letter_gap; - string_length = ustrlen(input_string); + string_length = (int) ustrlen(input_string); string_left_hand = xposn - ((letter_width * string_length - letter_gap) * half_si) / 2; if (odd_si) { @@ -872,7 +862,7 @@ static int plot_raster_dotty(struct zint_symbol *symbol, const int rotate_angle, static void to_iso8859_1(const unsigned char source[], unsigned char preprocessed[]) { int j, i, input_length; - input_length = ustrlen(source); + input_length = (int) ustrlen(source); j = 0; i = 0; diff --git a/backend/svg.c b/backend/svg.c index 45c3b27f..78894a90 100644 --- a/backend/svg.c +++ b/backend/svg.c @@ -2,7 +2,7 @@ /* libzint - the open source barcode library - Copyright (C) 2009 - 2020 Robin Stuart + Copyright (C) 2009 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -31,8 +31,8 @@ */ /* vim: set ts=4 sw=4 et : */ +#include #include -#include #include #include #ifdef _MSC_VER @@ -42,7 +42,7 @@ #include "common.h" static void pick_colour(int colour, char colour_code[]) { - switch(colour) { + switch (colour) { case 1: // Cyan strcpy(colour_code, "00ffff"); break; @@ -70,16 +70,17 @@ static void pick_colour(int colour, char colour_code[]) { } } -static void make_html_friendly(unsigned char * string, char * html_version) { +static void make_html_friendly(unsigned char *string, char *html_version) { /* Converts text to use HTML entity codes */ - int i, html_pos; + int i, len, html_pos; html_pos = 0; html_version[html_pos] = '\0'; + len = (int) ustrlen(string); - for (i = 0; i < (int) ustrlen(string); i++) { - switch(string[i]) { + for (i = 0; i < len; i++) { + switch (string[i]) { case '>': strcat(html_version, ">"); html_pos += 4; @@ -136,10 +137,10 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { struct zint_vector_string *string; char colour_code[7]; - int html_len; + int len, html_len; #ifdef _MSC_VER - char* html_string; + char *html_string; #endif for (i = 0; i < 6; i++) { @@ -148,7 +149,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { } fgcolour_string[6] = '\0'; bgcolour_string[6] = '\0'; - + if (strlen(symbol->fgcolour) > 6) { fg_alpha = (16 * ctoi(symbol->fgcolour[6])) + ctoi(symbol->fgcolour[7]); if (fg_alpha != 0xff) { @@ -161,11 +162,12 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { bg_alpha_opacity = (float) (bg_alpha / 255.0); } } - - html_len = strlen((char *)symbol->text) + 1; - for (i = 0; i < (int) strlen((char *)symbol->text); i++) { - switch(symbol->text[i]) { + len = (int) ustrlen(symbol->text); + html_len = len + 1; + + for (i = 0; i < len; i++) { + switch (symbol->text[i]) { case '>': case '<': case '"': @@ -179,7 +181,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { #ifndef _MSC_VER char html_string[html_len]; #else - html_string = (char*) _alloca(html_len); + html_string = (char *) _alloca(html_len); #endif /* Check for no created vector set */ @@ -193,7 +195,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { fsvg = fopen(symbol->outfile, "w"); } if (fsvg == NULL) { - strcpy(symbol->errtxt, "680: Could not open output file"); + sprintf(symbol->errtxt, "680: Could not open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } @@ -203,14 +205,16 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { fprintf(fsvg, "\n"); fprintf(fsvg, "\n"); - fprintf(fsvg, "vector->width), (int) ceil(symbol->vector->height)); + fprintf(fsvg, "vector->width), (int) ceil(symbol->vector->height)); fprintf(fsvg, " xmlns=\"http://www.w3.org/2000/svg\">\n"); fprintf(fsvg, " Zint Generated Symbol\n"); fprintf(fsvg, " \n"); fprintf(fsvg, "\n \n", fgcolour_string); if (bg_alpha != 0) { - fprintf(fsvg, " vector->width), (int) ceil(symbol->vector->height), bgcolour_string); + fprintf(fsvg, " vector->width), (int) ceil(symbol->vector->height), bgcolour_string); if (bg_alpha != 0xff) { fprintf(fsvg, " opacity=\"%.3f\"", bg_alpha_opacity); } @@ -219,7 +223,8 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { rect = symbol->vector->rectangles; while (rect) { - fprintf(fsvg, " x, rect->y, rect->width, rect->height); + fprintf(fsvg, " x, rect->y, rect->width, rect->height); if (rect->colour != -1) { pick_colour(rect->colour, colour_code); fprintf(fsvg, " fill=\"#%s\"", colour_code); @@ -267,7 +272,8 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { ex = hex->x + half_radius; fx = hex->x - half_radius; } - fprintf(fsvg, " x, circle->y, radius); - + if (circle->colour) { fprintf(fsvg, " fill=\"#%s\"", bgcolour_string); if (bg_alpha != 0xff) { @@ -299,7 +305,8 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) { circle = circle->next; } - bold = (symbol->output_options & BOLD_TEXT) && (!is_extendable(symbol->symbology) || (symbol->output_options & SMALL_TEXT)); + bold = (symbol->output_options & BOLD_TEXT) + && (!is_extendable(symbol->symbology) || (symbol->output_options & SMALL_TEXT)); string = symbol->vector->strings; while (string) { const char *halign = string->halign == 2 ? "end" : string->halign == 1 ? "start" : "middle"; diff --git a/backend/tests/CMakeLists.txt b/backend/tests/CMakeLists.txt index 88eeea81..eb25ebb1 100644 --- a/backend/tests/CMakeLists.txt +++ b/backend/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2019 - 2021 Robin Stuart +# Copyright (C) 2009-2021 Robin Stuart # Adapted from qrencode/tests/CMakeLists.txt # Copyright (C) 2006-2017 Kentaro Fukuchi # vim: set ts=4 sw=4 et : @@ -22,6 +22,7 @@ if(NOT EXISTS ${BWIPP_PS}) execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${BWIPP_TAR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tools) endif() +configure_file(${BWIPP_PS} ${CMAKE_CURRENT_BINARY_DIR}/tools/bwipp_dump.ps COPYONLY) set(testcommon_SRCS testcommon.c testcommon.h) diff --git a/backend/tests/README b/backend/tests/README index e536bf7f..48f4f7a5 100644 --- a/backend/tests/README +++ b/backend/tests/README @@ -1,7 +1,7 @@ Zint backend test suite ----------------------- -In order to build the zint testsuite, zint has to be compiled with the +In order to build the zint test suite, zint has to be compiled with the ZINT_TEST option enabled: cd @@ -12,50 +12,53 @@ ZINT_TEST option enabled: ------------------------------------------------------------------------------ -In order to run the testsuite, the path of the zint library needs to be -communicated to the runtime linker. On UNIX like systems, this is done -by exporting LD_LIBRARY_PATH to the path containing the zint library, -which is /backend: +In order to run the test suite, the path of the zint library may need to be +communicated to the runtime linker. On UNIX-like systems, this is done by +exporting LD_LIBRARY_PATH to the path containing the zint library, which is +/backend: cd cd build export LD_LIBRARY_PATH=$(pwd)/backend - + Setting LD_LIBRARY_PATH is not required if the zint library to be tested is installed into a system library path ( /usr/lib for example ) prior to running the tests. - -To run all tests (within /backend/tests): + +To run all tests (within ): ctest -To run individual tests, eg: +For various useful options, e.g. matching (-R) and excluding (-E) tests, see +https://cmake.org/cmake/help/latest/manual/ctest.1.html#options - ./test_common - ./test_vector +Tests can also be run individually, eg: + + backend/tests/test_common + backend/tests/test_vector To run a single test function within an individual test, use '-f ': - ./test_common -f utf8_to_unicode - ./test_dotcode -f input + backend/tests/test_common -f utf8_to_unicode + backend/tests/test_dotcode -f input To run a single dataset item in a single test function, use '-i ': - ./test_dotcode -f input -i 2 + backend/tests/test_dotcode -f input -i 2 To show debug info (if any), use '-d ': - ./test_dotcode -f input -i 2 -d 1 + backend/tests/test_dotcode -f input -i 2 -d 1 (for other flags see /backend/tests/testcommon.h) To generate test data, use '-g': - ./test_dotcode -f encode -g + backend/tests/test_dotcode -f encode -g To run a test against BWIPP (if any), use '-d 128': - ./test_composite -d 128 + backend/tests/test_composite -d 128 (see also /backend/tests/tools/run_bwipp_tests.sh) @@ -64,13 +67,13 @@ To run a test against BWIPP (if any), use '-d 128': If the zint library was built with static linkage support, i.e. ZINT_STATIC is ON, an additional test executable, which uses the zint-static library, will be built. The static variant of each test shares the test name, but has a -"-static" suffix. For example, +"-static" suffix. For example, - ./test_dotcode + backend/tests/test_dotcode would run the dotcode test that uses the shared zint library, while - ./test_dotcode-static + backend/tests/test_dotcode-static runs the same test built against the zint-static library. diff --git a/backend/tests/test_big5.c b/backend/tests/test_big5.c index c1a053e7..92ad0a2d 100644 --- a/backend/tests/test_big5.c +++ b/backend/tests/test_big5.c @@ -116,7 +116,7 @@ static void test_big5_utf8(int index) { // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { /* 0*/ { "_", -1, 0, 1, { 0xA1C4 }, "" }, - /* 1*/ { "╴", -1, ZINT_ERROR_INVALID_DATA, -1, {}, "" }, + /* 1*/ { "╴", -1, ZINT_ERROR_INVALID_DATA, -1, {0}, "" }, }; int data_size = sizeof(data) / sizeof(struct item); @@ -135,7 +135,7 @@ static void test_big5_utf8(int index) { assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol.errtxt); if (ret == 0) { assert_equal(ret_length, data[i].ret_length, "i:%d ret_length %d != %d\n", i, ret_length, data[i].ret_length); - for (int j = 0; j < (int) ret_length; j++) { + for (int j = 0; j < ret_length; j++) { assert_equal(b5data[j], data[i].expected_b5data[j], "i:%d b5data[%d] %04X != %04X\n", i, j, b5data[j], data[i].expected_b5data[j]); } } diff --git a/backend/tests/test_bmp.c b/backend/tests/test_bmp.c index dacd13c2..73256ea6 100644 --- a/backend/tests/test_bmp.c +++ b/backend/tests/test_bmp.c @@ -142,8 +142,8 @@ static void test_print(int index, int generate, int debug) { if (generate) { if (!testUtilExists(data_dir)) { - ret = mkdir(data_dir, 0755); - assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); + ret = testutil_mkdir(data_dir, 0755); + assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno)); } } diff --git a/backend/tests/test_eci.c b/backend/tests/test_eci.c index 8f3f41f0..ed3f2b05 100644 --- a/backend/tests/test_eci.c +++ b/backend/tests/test_eci.c @@ -780,8 +780,9 @@ static void test_utf8_to_eci_ucs2be(void) { int length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data); int out_length = length; int eci_length = get_eci_length(data[i].eci, (const unsigned char *) data[i].data, length); - char *dest = alloca(eci_length + 1); + char dest[1024]; + assert_nonzero(eci_length + 1 <= 1024, "i:%d eci_length %d + 1 > 1024\n", i, eci_length); ret = utf8_to_eci(data[i].eci, (const unsigned char *) data[i].data, (unsigned char *) dest, &out_length); assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret); if (ret == 0) { diff --git a/backend/tests/test_emf.c b/backend/tests/test_emf.c index 75aa11a2..f5bce776 100644 --- a/backend/tests/test_emf.c +++ b/backend/tests/test_emf.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020 Robin Stuart + Copyright (C) 2020 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -80,8 +80,8 @@ static void test_print(int index, int generate, int debug) { if (generate) { if (!testUtilExists(data_dir)) { - ret = mkdir(data_dir, 0755); - assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); + ret = testutil_mkdir(data_dir, 0755); + assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno)); } } diff --git a/backend/tests/test_large.c b/backend/tests/test_large.c index eb7934b7..172fb5c5 100644 --- a/backend/tests/test_large.c +++ b/backend/tests/test_large.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020 Robin Stuart + Copyright (C) 2020 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -32,6 +32,19 @@ #include "testcommon.h" #include "../large.h" +#if defined(__MINGW32__) +# define LX_FMT "I64" +# if defined(__clang__) +# pragma GCC diagnostic ignored "-Wformat-non-iso" +# elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wformat" /* Unfortunately doesn't seem to be way to only avoid non-ISO warnings */ +# endif +#elif defined(_MSC_VER) +# define LX_FMT "ll" +#else +# define LX_FMT "l" +#endif + #define LI(l, h) { l, h } int clz_u64(uint64_t x); @@ -181,7 +194,7 @@ static void test_clz_u64(int index) { if (index != -1 && i != index) continue; ret = clz_u64(data[i].s); - assert_equal(ret, data[i].ret, "i:%d 0x%lX ret %d != %d\n", i, data[i].s, ret, data[i].ret); + assert_equal(ret, data[i].ret, "i:%d 0x%" LX_FMT "X ret %d != %d\n", i, data[i].s, ret, data[i].ret); } testFinish(); @@ -214,9 +227,9 @@ static void test_load(int index) { large_load(&data[i].t, &data[i].s); - assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%lX (%s) != expected lo 0x%lX (%s)\n", + assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%" LX_FMT "X (%s) != expected lo 0x%" LX_FMT "X (%s)\n", i, data[i].t.lo, large_dump(&data[i].t, t_dump), data[i].expected.lo, large_dump(&data[i].expected, expected_dump)); - assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%lX (%s) != expected hi 0x%lX (%s)\n", + assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%" LX_FMT "X (%s) != expected hi 0x%" LX_FMT "X (%s)\n", i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump)); } @@ -254,9 +267,9 @@ static void test_load_str_u64(int index) { large_load_str_u64(&data[i].t, (unsigned char *) data[i].s, data[i].length == -1 ? (int) strlen(data[i].s) : data[i].length); - assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%lX (%s) != expected lo 0x%lX (%s)\n", + assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%" LX_FMT "X (%s) != expected lo 0x%" LX_FMT "X (%s)\n", i, data[i].t.lo, large_dump(&data[i].t, t_dump), data[i].expected.lo, large_dump(&data[i].expected, expected_dump)); - assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%lX (%s) != expected hi 0x%lX (%s)\n", + assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%" LX_FMT "X (%s) != expected hi 0x%" LX_FMT "X (%s)\n", i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump)); } @@ -297,9 +310,9 @@ static void test_add_u64(int index) { large_add_u64(&data[i].t, data[i].s); - assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%lX (%s) != expected lo 0x%lX (%s)\n", + assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%" LX_FMT "X (%s) != expected lo 0x%" LX_FMT "X (%s)\n", i, data[i].t.lo, large_dump(&data[i].t, t_dump), data[i].expected.lo, large_dump(&data[i].expected, expected_dump)); - assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%lX (%s) != expected hi 0x%lX (%s)\n", + assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%" LX_FMT "X (%s) != expected hi 0x%" LX_FMT "X (%s)\n", i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump)); } @@ -340,9 +353,9 @@ static void test_sub_u64(int index) { large_sub_u64(&data[i].t, data[i].s); - assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%lX (%s) != expected lo 0x%lX (%s)\n", + assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%" LX_FMT "X (%s) != expected lo 0x%" LX_FMT "X (%s)\n", i, data[i].t.lo, large_dump(&data[i].t, t_dump), data[i].expected.lo, large_dump(&data[i].expected, expected_dump)); - assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%lX (%s) != expected hi 0x%lX (%s)\n", + assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%" LX_FMT "X (%s) != expected hi 0x%" LX_FMT "X (%s)\n", i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump)); } @@ -396,9 +409,9 @@ static void test_mul_u64(int index) { large_mul_u64(&data[i].t, data[i].s); - assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%lX (%s) != expected lo 0x%lX (%s)\n", + assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%" LX_FMT "X (%s) != expected lo 0x%" LX_FMT "X (%s)\n", i, data[i].t.lo, large_dump(&data[i].t, t_dump), data[i].expected.lo, large_dump(&data[i].expected, expected_dump)); - assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%lX (%s) != expected hi 0x%lX (%s)\n", + assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%" LX_FMT "X (%s) != expected hi 0x%" LX_FMT "X (%s)\n", i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump)); } @@ -520,10 +533,11 @@ static void test_div_u64(int index) { r = large_div_u64(&data[i].t, data[i].s); - assert_equal(r, data[i].expected_r, "i:%d r %lu (0x%lX) != expected_r %lu (0x%lX)\n", i, r, r, data[i].expected_r, data[i].expected_r); - assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%lX (%s) != expected lo 0x%lX (%s)\n", + assert_equal(r, data[i].expected_r, "i:%d r %" LX_FMT "u (0x%" LX_FMT "X) != expected_r %" LX_FMT "u (0x%" LX_FMT "X)\n", + i, r, r, data[i].expected_r, data[i].expected_r); + assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%" LX_FMT "X (%s) != expected lo 0x%" LX_FMT "X (%s)\n", i, data[i].t.lo, large_dump(&data[i].t, t_dump), data[i].expected.lo, large_dump(&data[i].expected, expected_dump)); - assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%lX (%s) != expected hi 0x%lX (%s)\n", + assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%" LX_FMT "X (%s) != expected hi 0x%" LX_FMT "X (%s)\n", i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump)); } @@ -684,9 +698,9 @@ static void test_unset_bit(int index) { large_unset_bit(&data[i].t, data[i].s); - assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%lX (%s) != expected lo 0x%lX (%s)\n", + assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%" LX_FMT "X (%s) != expected lo 0x%" LX_FMT "X (%s)\n", i, data[i].t.lo, large_dump(&data[i].t, t_dump), data[i].expected.lo, large_dump(&data[i].expected, expected_dump)); - assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%lX (%s) != expected hi 0x%lX (%s)\n", + assert_equal(data[i].t.hi, data[i].expected.hi, "i:%d hi 0x%" LX_FMT "X (%s) != expected hi 0x%" LX_FMT "X (%s)\n", i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump)); } @@ -848,8 +862,8 @@ static void test_dump(int index) { large_dump(&data[i].t, dump); - assert_zero(strcmp(dump, data[i].expected), "i:%d { %lX, %lX } strcmp(%s, %s) != 0\n", - i, (unsigned long) data[i].t.lo, (unsigned long) data[i].t.hi, dump, data[i].expected); + assert_zero(strcmp(dump, data[i].expected), "i:%d { %" LX_FMT "X, %" LX_FMT "X } strcmp(%s, %s) != 0\n", + i, data[i].t.lo, data[i].t.hi, dump, data[i].expected); } testFinish(); diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c index 98d4e8af..ac6f86ec 100644 --- a/backend/tests/test_library.c +++ b/backend/tests/test_library.c @@ -32,7 +32,6 @@ #include "testcommon.h" #include #include -#include static void test_checks(int index, int debug) { @@ -265,7 +264,7 @@ static void test_escape_char_process(int index, int generate, int debug) { FILE *fp; fp = fopen(input_filename, "wb"); assert_nonnull(fp, "i:%d fopen(%s) failed\n", i, input_filename); - assert_nonzero(fputs(data[i].data, fp), "i%d fputs(%s) failed\n", i, data[i].data); + assert_notequal(fputs(data[i].data, fp), EOF, "i%d fputs(%s) failed == EOF (%d)\n", i, data[i].data, ferror(fp)); assert_zero(fclose(fp), "i%d fclose() failed\n", i); struct zint_symbol *symbol2 = ZBarcode_Create(); @@ -282,7 +281,7 @@ static void test_escape_char_process(int index, int generate, int debug) { ret = testUtilSymbolCmp(symbol2, symbol); assert_zero(ret, "i:%d testUtilSymbolCmp symbol2 ret %d != 0\n", i, ret); - assert_zero(remove(input_filename), "i:%d remove(%s) != 0 (%d)\n", i, input_filename, errno); + assert_zero(remove(input_filename), "i:%d remove(%s) != 0 (%d: %s)\n", i, input_filename, errno, strerror(errno)); ZBarcode_Delete(symbol2); } @@ -334,6 +333,10 @@ static void test_encode_file_length(void) { testStart(""); +#ifdef _WIN32 + testSkip("Test not compatible with Windows"); + return; +#else int ret; char filename[] = "in.bin"; char buf[ZINT_MAX_DATA_LEN + 1] = {0}; @@ -346,41 +349,42 @@ static void test_encode_file_length(void) { // Empty file fd = creat(filename, S_IRUSR); - assert_nonzero(fd, "Empty input file not created\n"); - assert_zero(close(fd), "Empty close(%s) != 0\n", filename); + assert_notequal(fd, -1, "Empty input file (%s) not created == -1 (%d: %s)\n", filename, errno, strerror(errno)); + assert_zero(close(fd), "Empty close(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno)); ret = ZBarcode_Encode_File(symbol, filename); assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File empty ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt); - assert_zero(remove(filename), "remove(%s) != 0\n", filename); + assert_zero(remove(filename), "remove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno)); // Too large file fd = creat(filename, S_IRUSR | S_IWUSR); - assert_nonzero(fd, "Too large input file not created\n"); + assert_notequal(fd, -1, "Too large input file (%s) not created == -1 (%d: %s)\n", filename, errno, strerror(errno)); ret = write(fd, buf, sizeof(buf)); assert_equal(ret, sizeof(buf), "Too large write ret %d != %d\n", ret, (int) sizeof(buf)); - assert_zero(close(fd), "Too large close(%s) != 0\n", filename); + assert_zero(close(fd), "Too large close(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno)); ret = ZBarcode_Encode_File(symbol, filename); assert_equal(ret, ZINT_ERROR_TOO_LONG, "ZBarcode_Encode_File too large ret %d != ZINT_ERROR_TOO_LONG (%s)\n", ret, symbol->errtxt); - assert_zero(remove(filename), "remove(%s) != 0\n", filename); + assert_zero(remove(filename), "remove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno)); // Unreadable file fd = creat(filename, S_IWUSR); - assert_nonzero(fd, "Unreadable input file not created\n"); + assert_notequal(fd, -1, "Unreadable input file (%s) not created == -1 (%d: %s)\n", filename, errno, strerror(errno)); ret = write(fd, buf, 1); assert_equal(ret, 1, "Unreadable write ret %d != 1\n", ret); - assert_zero(close(fd), "Unreadable close(%s) != 0\n", filename); + assert_zero(close(fd), "Unreadable close(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno)); ret = ZBarcode_Encode_File(symbol, filename); assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ZBarcode_Encode_File unreadable ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt); - assert_zero(remove(filename), "remove(%s) != 0\n", filename); + assert_zero(remove(filename), "remove(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno)); ZBarcode_Delete(symbol); testFinish(); +#endif /* _WIN32 */ } // #181 Nico Gunkel OSS-Fuzz (buffer not freed on fread() error) Note: unable to reproduce fread() error using this method @@ -394,13 +398,13 @@ static void test_encode_file_directory(void) { struct zint_symbol *symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - (void)rmdir(dirname); // In case junk hanging around - assert_zero(mkdir(dirname, 0700), "mkdir(%s, 0700) != 0\n", dirname); + (void)testutil_rmdir(dirname); // In case junk hanging around + assert_zero(testutil_mkdir(dirname, 0700), "testutil_mkdir(%s, 0700) != 0 (%d: %s)\n", dirname, errno, strerror(errno)); ret = ZBarcode_Encode_File(symbol, dirname); assert_equal(ret, ZINT_ERROR_INVALID_DATA, "ret %d != ZINT_ERROR_INVALID_DATA (%s)\n", ret, symbol->errtxt); - assert_zero(rmdir(dirname), "rmdir(%s) != 0\n", dirname); + assert_zero(testutil_rmdir(dirname), "testutil_rmdir(%s) != 0 (%d: %s)\n", dirname, errno, strerror(errno)); ZBarcode_Delete(symbol); diff --git a/backend/tests/test_plessey.c b/backend/tests/test_plessey.c index 2bfdf9eb..e188e96b 100644 --- a/backend/tests/test_plessey.c +++ b/backend/tests/test_plessey.c @@ -47,18 +47,26 @@ static void test_large(int index, int debug) { }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_MSI_PLESSEY, -1, "9", 55, 0, 1, 667 }, - /* 1*/ { BARCODE_MSI_PLESSEY, -1, "9", 56, ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 2*/ { BARCODE_MSI_PLESSEY, 1, "9", 18, 0, 1, 235 }, // 1 mod-10 check digit - /* 3*/ { BARCODE_MSI_PLESSEY, 1, "9", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 4*/ { BARCODE_MSI_PLESSEY, 2, "9", 18, 0, 1, 247 }, // 2 mod-10 check digits - /* 5*/ { BARCODE_MSI_PLESSEY, 2, "9", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 6*/ { BARCODE_MSI_PLESSEY, 3, "9", 55, 0, 1, 679 }, // 1 mod-11 check digit - /* 7*/ { BARCODE_MSI_PLESSEY, 3, "9", 56, ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 8*/ { BARCODE_MSI_PLESSEY, 4, "9", 18, 0, 1, 247 }, // 1 mod-11 and 1 mod-10 check digit - /* 9*/ { BARCODE_MSI_PLESSEY, 4, "9", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 10*/ { BARCODE_PLESSEY, -1, "A", 65, 0, 1, 1107 }, - /* 11*/ { BARCODE_PLESSEY, -1, "A", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 0*/ { BARCODE_MSI_PLESSEY, -1, "9", 65, 0, 1, 787 }, + /* 1*/ { BARCODE_MSI_PLESSEY, -1, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 2*/ { BARCODE_MSI_PLESSEY, 1, "9", 65, 0, 1, 799 }, // 1 mod-10 check digit + /* 3*/ { BARCODE_MSI_PLESSEY, 1, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 4*/ { BARCODE_MSI_PLESSEY, 2, "9", 65, 0, 1, 811 }, // 2 mod-10 check digits + /* 5*/ { BARCODE_MSI_PLESSEY, 2, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 6*/ { BARCODE_MSI_PLESSEY, 3, "9", 65, 0, 1, 799 }, // 1 mod-11 check digit + /* 7*/ { BARCODE_MSI_PLESSEY, 3, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 8*/ { BARCODE_MSI_PLESSEY, 3, "3", 65, 0, 1, 811 }, // 1 mod-11 double check digit "10" + /* 9*/ { BARCODE_MSI_PLESSEY, 3, "3", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 10*/ { BARCODE_MSI_PLESSEY, 4, "9", 65, 0, 1, 811 }, // 1 mod-11 and 1 mod-10 check digit + /* 11*/ { BARCODE_MSI_PLESSEY, 4, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 12*/ { BARCODE_MSI_PLESSEY, 4, "3", 65, 0, 1, 823 }, // 1 mod-11 double check digit "10" and 1 mod-10 check digit + /* 13*/ { BARCODE_MSI_PLESSEY, 4, "3", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 14*/ { BARCODE_MSI_PLESSEY, 5, "9", 65, 0, 1, 799 }, // 1 NCR mod-11 check digit + /* 15*/ { BARCODE_MSI_PLESSEY, 5, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 16*/ { BARCODE_MSI_PLESSEY, 6, "9", 65, 0, 1, 811 }, // 1 NCR mod-11 and 1 mod-10 check digit + /* 17*/ { BARCODE_MSI_PLESSEY, 6, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 18*/ { BARCODE_PLESSEY, -1, "A", 65, 0, 1, 1107 }, + /* 19*/ { BARCODE_PLESSEY, -1, "A", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, }; int data_size = ARRAY_SIZE(data); @@ -107,16 +115,32 @@ static void test_hrt(int index, int debug) { /* 0*/ { BARCODE_MSI_PLESSEY, -1, "1234567", "1234567" }, /* 1*/ { BARCODE_MSI_PLESSEY, 0, "1234567", "1234567" }, /* 2*/ { BARCODE_MSI_PLESSEY, 1, "1234567", "12345674" }, - /* 3*/ { BARCODE_MSI_PLESSEY, 2, "1234567", "123456741" }, - /* 4*/ { BARCODE_MSI_PLESSEY, 3, "1234567", "12345674" }, - /* 5*/ { BARCODE_MSI_PLESSEY, 4, "1234567", "123456741" }, - /* 6*/ { BARCODE_MSI_PLESSEY, 1, "123456", "1234566" }, - /* 7*/ { BARCODE_MSI_PLESSEY, 2, "123456", "12345666" }, - /* 8*/ { BARCODE_MSI_PLESSEY, 3, "123456", "1234560" }, - /* 9*/ { BARCODE_MSI_PLESSEY, 4, "123456", "12345609" }, - /* 10*/ { BARCODE_MSI_PLESSEY, 3, "2211", "221110" }, // Mod-11 check digit '10' - /* 11*/ { BARCODE_MSI_PLESSEY, 4, "2211", "2211100" }, - /* 12*/ { BARCODE_PLESSEY, -1, "0123456789ABCDEF", "0123456789ABCDEF" }, + /* 3*/ { BARCODE_MSI_PLESSEY, 1 + 10, "1234567", "1234567" }, + /* 4*/ { BARCODE_MSI_PLESSEY, 1, "9999999999", "99999999990" }, + /* 5*/ { BARCODE_MSI_PLESSEY, 2, "1234567", "123456741" }, + /* 6*/ { BARCODE_MSI_PLESSEY, 2 + 10, "1234567", "1234567" }, + /* 7*/ { BARCODE_MSI_PLESSEY, 2, "9999999999", "999999999900" }, + /* 8*/ { BARCODE_MSI_PLESSEY, 3, "1234567", "12345674" }, + /* 9*/ { BARCODE_MSI_PLESSEY, 3 + 10, "1234567", "1234567" }, + /* 10*/ { BARCODE_MSI_PLESSEY, 3, "9999999999", "99999999995" }, + /* 11*/ { BARCODE_MSI_PLESSEY, 4, "1234567", "123456741" }, + /* 12*/ { BARCODE_MSI_PLESSEY, 4 + 10, "1234567", "1234567" }, + /* 13*/ { BARCODE_MSI_PLESSEY, 4, "9999999999", "999999999959" }, + /* 14*/ { BARCODE_MSI_PLESSEY, 5, "1234567", "12345679" }, + /* 15*/ { BARCODE_MSI_PLESSEY, 5 + 10, "1234567", "1234567" }, + /* 16*/ { BARCODE_MSI_PLESSEY, 5, "9999999999", "999999999910" }, + /* 17*/ { BARCODE_MSI_PLESSEY, 6, "1234567", "123456790" }, + /* 18*/ { BARCODE_MSI_PLESSEY, 6 + 10, "1234567", "1234567" }, + /* 19*/ { BARCODE_MSI_PLESSEY, 6, "9999999999", "9999999999109" }, + /* 20*/ { BARCODE_MSI_PLESSEY, 1, "123456", "1234566" }, + /* 21*/ { BARCODE_MSI_PLESSEY, 2, "123456", "12345666" }, + /* 22*/ { BARCODE_MSI_PLESSEY, 3, "123456", "1234560" }, + /* 23*/ { BARCODE_MSI_PLESSEY, 4, "123456", "12345609" }, + /* 24*/ { BARCODE_MSI_PLESSEY, 3, "2211", "221110" }, // Mod-11 check digit '10' + /* 25*/ { BARCODE_MSI_PLESSEY, 3 + 10, "2211", "2211" }, // Mod-11 check digit '10' + /* 26*/ { BARCODE_MSI_PLESSEY, 4, "2211", "2211100" }, + /* 27*/ { BARCODE_MSI_PLESSEY, 4 + 10, "2211", "2211" }, + /* 28*/ { BARCODE_PLESSEY, -1, "0123456789ABCDEF", "0123456789ABCDEF" }, }; int data_size = ARRAY_SIZE(data); @@ -219,16 +243,22 @@ static void test_encode(int index, int generate, int debug) { /* 4*/ { BARCODE_MSI_PLESSEY, 4, "1234567890", 0, 1, 151, "", "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001101101001001001101001" }, - /* 5*/ { BARCODE_MSI_PLESSEY, 3, "2211", 0, 1, 79, "Produces mod-11 '10' check digit; BWIPP (badmod11)", + /* 5*/ { BARCODE_MSI_PLESSEY, 5, "1234567890", 0, 1, 139, "", + "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001001001001" + }, + /* 6*/ { BARCODE_MSI_PLESSEY, 6, "1234567890", 0, 1, 151, "", + "1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001001001001101101101001" + }, + /* 7*/ { BARCODE_MSI_PLESSEY, 3, "2211", 0, 1, 79, "Produces mod-11 '10' check digit; BWIPP (badmod11)", "1101001001101001001001101001001001001101001001001101001001001101001001001001001" }, - /* 6*/ { BARCODE_MSI_PLESSEY, 4, "2211", 0, 1, 91, "BWIPP (badmod11)", + /* 8*/ { BARCODE_MSI_PLESSEY, 4, "2211", 0, 1, 91, "BWIPP (badmod11)", "1101001001101001001001101001001001001101001001001101001001001101001001001001001001001001001" }, - /* 7*/ { BARCODE_PLESSEY, -1, "0123456789ABCDEF", 0, 1, 323, "", + /* 9*/ { BARCODE_PLESSEY, -1, "0123456789ABCDEF", 0, 1, 323, "", "11101110100011101000100010001000111010001000100010001110100010001110111010001000100010001110100011101000111010001000111011101000111011101110100010001000100011101110100010001110100011101000111011101110100011101000100011101110111010001110111010001110111011101110111011101110111010001000111010001000100010001110001000101110111" }, - /* 8*/ { BARCODE_MSI_PLESSEY, 4, "999999999999999999", 0, 1, 247, "Max value; #209 check buffer not overrun", + /* 10*/ { BARCODE_MSI_PLESSEY, 4, "999999999999999999", 0, 1, 247, "Max value (previously); #209 check buffer not overrun", "1101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001001001001001101001" }, }; diff --git a/backend/tests/test_png.c b/backend/tests/test_png.c index 4af2f6f5..677e5443 100644 --- a/backend/tests/test_png.c +++ b/backend/tests/test_png.c @@ -196,8 +196,8 @@ static void test_print(int index, int generate, int debug) { if (generate) { if (!testUtilExists(data_dir)) { - ret = mkdir(data_dir, 0755); - assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); + ret = testutil_mkdir(data_dir, 0755); + assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno)); } } diff --git a/backend/tests/test_print.c b/backend/tests/test_print.c index 3a6a1b08..e1e60578 100644 --- a/backend/tests/test_print.c +++ b/backend/tests/test_print.c @@ -81,13 +81,13 @@ static void test_print(int index, int generate, int debug) { if (generate) { strcpy(data_dir, "data"); if (!testUtilExists(data_dir)) { - ret = mkdir(data_dir, 0755); - assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); + ret = testutil_mkdir(data_dir, 0755); + assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno)); } strcat(data_dir, "/print"); if (!testUtilExists(data_dir)) { - ret = mkdir(data_dir, 0755); - assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); + ret = testutil_mkdir(data_dir, 0755); + assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno)); } } @@ -100,8 +100,8 @@ static void test_print(int index, int generate, int debug) { if (generate) { if (!testUtilExists(data_dir)) { - ret = mkdir(data_dir, 0755); - assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); + ret = testutil_mkdir(data_dir, 0755); + assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno)); } } diff --git a/backend/tests/test_ps.c b/backend/tests/test_ps.c index 2cda98c1..3dd9952d 100644 --- a/backend/tests/test_ps.c +++ b/backend/tests/test_ps.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020 Robin Stuart + Copyright (C) 2020 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -71,8 +71,8 @@ static void test_print(int index, int generate, int debug) { if (generate) { if (!testUtilExists(data_dir)) { - ret = mkdir(data_dir, 0755); - assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); + ret = testutil_mkdir(data_dir, 0755); + assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno)); } } diff --git a/backend/tests/test_svg.c b/backend/tests/test_svg.c index 00d06845..8bb821c5 100644 --- a/backend/tests/test_svg.c +++ b/backend/tests/test_svg.c @@ -111,8 +111,8 @@ static void test_print(int index, int generate, int debug) { if (generate) { if (!testUtilExists(data_dir)) { - ret = mkdir(data_dir, 0755); - assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); + ret = testutil_mkdir(data_dir, 0755); + assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno)); } } diff --git a/backend/tests/test_tif.c b/backend/tests/test_tif.c index e250d6e4..538be63c 100644 --- a/backend/tests/test_tif.c +++ b/backend/tests/test_tif.c @@ -190,8 +190,8 @@ static void test_print(int index, int generate, int debug) { if (generate) { if (!testUtilExists(data_dir)) { - ret = mkdir(data_dir, 0755); - assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); + ret = testutil_mkdir(data_dir, 0755); + assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno)); } } diff --git a/backend/tests/test_vector.c b/backend/tests/test_vector.c index cec91485..f1a1309a 100644 --- a/backend/tests/test_vector.c +++ b/backend/tests/test_vector.c @@ -529,9 +529,9 @@ static void test_stacking(int index, int debug) { }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_CODE128, -1, -1, -1, "A", "B", 50, 2, 46, 92, 116.1, -1, -1, -1 }, - /* 1*/ { BARCODE_CODE128, BARCODE_BIND, -1, -1, "A", "B", 50, 2, 46, 92, 116.1, 49, 0, 2 }, - /* 2*/ { BARCODE_CODE128, BARCODE_BIND, -1, 2, "A", "B", 50, 2, 46, 92, 116.1, 48, 0, 4 }, + /* 0*/ { BARCODE_CODE128, -1, -1, -1, "A", "B", 50, 2, 46, 92, 116, -1, -1, -1 }, + /* 1*/ { BARCODE_CODE128, BARCODE_BIND, -1, -1, "A", "B", 50, 2, 46, 92, 116, 49, 0, 2 }, + /* 2*/ { BARCODE_CODE128, BARCODE_BIND, -1, 2, "A", "B", 50, 2, 46, 92, 116, 48, 0, 4 }, }; int data_size = ARRAY_SIZE(data); diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index 6a0b3173..5e269f08 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -34,6 +34,14 @@ */ #include "testcommon.h" + +#ifdef _MSC_VER +#include +#define testutil_alloca(nmemb) _alloca(nmemb) +#else +#define testutil_alloca(nmemb) alloca(nmemb) +#endif + #include "../eci.h" #ifndef NO_PNG #include @@ -1178,7 +1186,7 @@ void testUtilBitmapPrint(const struct zint_symbol *symbol, const char *prefix, c int testUtilBitmapCmp(const struct zint_symbol *symbol, const char *expected, int *row, int *column) { static char colour[] = { '0', 'C', 'M', 'B', 'Y', 'G', 'R', '1' }; - int r, c, i, j; + int r, c = -1, i, j; const char *e = expected; const char *ep = expected + strlen(expected); char buf[7]; @@ -2017,7 +2025,7 @@ static char *testUtilBwippEscape(char *bwipp_data, int bwipp_data_size, const ch /* Escape single quote also to avoid having to do proper shell escaping TODO: proper shell escaping */ if (*d < 0x20 || *d >= 0x7F || *d == '^' || *d == '"' || *d == '\'') { if (b + 4 >= be) { - fprintf(stderr, "testUtilBwippEscape: bwipp_data buffer full\n"); + fprintf(stderr, "testUtilBwippEscape: double quote bwipp_data buffer full (%d)\n", bwipp_data_size); return NULL; } sprintf(b, "^%03u", *d++); @@ -2044,7 +2052,7 @@ static char *testUtilBwippEscape(char *bwipp_data, int bwipp_data_size, const ch default: fprintf(stderr, "testUtilBwippEscape: unknown escape %c\n", *d); return NULL; break; } if (b + 4 >= be) { - fprintf(stderr, "testUtilBwippEscape: bwipp_data buffer full\n"); + fprintf(stderr, "testUtilBwippEscape: loop bwipp_data buffer full (%d)\n", bwipp_data_size); return NULL; } sprintf(b, "^%03d", val); @@ -2057,7 +2065,7 @@ static char *testUtilBwippEscape(char *bwipp_data, int bwipp_data_size, const ch } if (b == be && d < de) { - fprintf(stderr, "testUtilBwippEscape: bwipp_data buffer full\n"); + fprintf(stderr, "testUtilBwippEscape: end bwipp_data buffer full (%d)\n", bwipp_data_size); return NULL; } *b = '\0'; @@ -2086,10 +2094,10 @@ static void testUtilISBNHyphenate(char *bwipp_data, int addon_posn) { #define GS_INITIAL_LEN 35 /* Length of cmd up to -q */ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3, const char *data, int length, const char *primary, char *buffer, int buffer_size) { - const char *cmd_fmt = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%s' ../tools/bwipp_dump.ps"; - const char *cmd_opts_fmt = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%s' -so='%s' ../tools/bwipp_dump.ps"; - const char *cmd_fmt2 = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%.2043s' -sd2='%s' ../tools/bwipp_dump.ps"; // If data > 2K - const char *cmd_opts_fmt2 = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%.2043s' -sd2='%s' -so='%s' ../tools/bwipp_dump.ps"; + const char *cmd_fmt = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%s' backend/tests/tools/bwipp_dump.ps"; + const char *cmd_opts_fmt = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%s' -so='%s' backend/tests/tools/bwipp_dump.ps"; + const char *cmd_fmt2 = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%.2043s' -sd2='%s' backend/tests/tools/bwipp_dump.ps"; // If data > 2K + const char *cmd_opts_fmt2 = "gs -dNOPAUSE -dBATCH -dNODISPLAY -q -sb=%s -sd='%.2043s' -sd2='%s' -so='%s' backend/tests/tools/bwipp_dump.ps"; int symbology = symbol->symbology; int data_len = length == -1 ? (int) strlen(data) : length; @@ -2097,13 +2105,14 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int int max_data_len = 4 + primary_len + 1 + 1 + data_len * 4 + 64; /* 4 AI prefix + primary + '|' + leading zero + escaped data + fudge */ int eci_length = get_eci_length(symbol->eci, (const unsigned char *) data, data_len); - char *converted = alloca(eci_length + 1); - char *cmd = alloca(max_data_len + 1024); + char *converted = (char *) testutil_alloca(eci_length + 1); + char *cmd = (char *) testutil_alloca(max_data_len + 1024); const char *bwipp_barcode = NULL; char *bwipp_opts = NULL; - char *bwipp_data = alloca(max_data_len + 1); + int bwipp_data_size = max_data_len + 1; + char *bwipp_data = (char *) testutil_alloca(bwipp_data_size); char bwipp_opts_buf[512]; - int *bwipp_row_height = alloca(sizeof(int) * symbol->rows); + int *bwipp_row_height = (int *) testutil_alloca(sizeof(int) * symbol->rows); int linear_row_height; int gs1_cvt; int user_mask; @@ -2227,7 +2236,7 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int } } } else { - if (testUtilBwippEscape(bwipp_data, sizeof(bwipp_data), data, data_len, symbol->input_mode & ESCAPE_MODE, eci, &parse, &parsefnc) == NULL) { + if (testUtilBwippEscape(bwipp_data, bwipp_data_size, data, data_len, symbol->input_mode & ESCAPE_MODE, eci, &parse, &parsefnc) == NULL) { return -1; } if (parse) { @@ -2285,12 +2294,19 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int sprintf(bwipp_opts_buf + (int) strlen(bwipp_opts_buf), "%sincludecheck", strlen(bwipp_opts_buf) ? " " : ""); const char *checktype = NULL; + if (option_2 >= 11 && option_2 <= 16) { + option_2 -= 10; /* Remove no-check indicator */ + } if (option_2 == 2) { checktype = "mod1010"; } else if (option_2 == 3) { checktype = "mod11 badmod11"; } else if (option_2 == 4) { checktype = "mod1110 badmod11"; + } else if (option_2 == 5) { + checktype = "ncrmod11 badmod11"; + } else if (option_2 == 6) { + checktype = "ncrmod1110 badmod11"; } if (checktype) { sprintf(bwipp_opts_buf + (int) strlen(bwipp_opts_buf), "%schecktype=%s", strlen(bwipp_opts_buf) ? " " : "", checktype); @@ -2480,7 +2496,7 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int } } if (option_2 > 0) { - char scm_vv_buf[16]; + char scm_vv_buf[32]; sprintf(scm_vv_buf, "[)>^03001^029%02d", option_2); /* [)>\R01\Gvv */ memmove(bwipp_data + 15, bwipp_data, strlen(bwipp_data) + 1); memcpy(bwipp_data, scm_vv_buf, 15); @@ -2621,7 +2637,7 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int printf("i:%d testUtilBwipp: cmd %s\n", index, cmd); } - fp = popen(cmd, "r"); + fp = testutil_popen(cmd, "r"); if (!fp) { fprintf(stderr, "i:%d testUtilBwipp: failed to run '%s'\n", index, cmd); return -1; @@ -2630,13 +2646,13 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int for (r = 0; r < symbol->rows; r++) { if (b + symbol->width > be) { fprintf(stderr, "i:%d testUtilBwipp: row %d, width %d, row width iteration overrun (%s)\n", index, r, symbol->width, cmd); - pclose(fp); + testutil_pclose(fp); return -1; } cnt = fread(b, 1, symbol->width, fp); if (cnt != symbol->width) { fprintf(stderr, "i:%d testUtilBwipp: failed to read symbol->width %d bytes, cnt %d (%s)\n", index, symbol->width, cnt, cmd); - pclose(fp); + testutil_pclose(fp); return -1; } b += cnt; @@ -2645,7 +2661,7 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int if (cnt != symbol->width) { fprintf(stderr, "i:%d testUtilBwipp: failed to read/ignore symbol->width %d bytes, cnt %d, h %d, bwipp_row_height[%d] %d, symbol->row_height[%d] %d (%s)\n", index, symbol->width, cnt, h, r, bwipp_row_height[r], r, symbol->row_height[r], cmd); - pclose(fp); + testutil_pclose(fp); return -1; } } @@ -2654,11 +2670,11 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int if (fgetc(fp) != EOF) { fprintf(stderr, "i:%d testUtilBwipp: failed to read full stream (%s)\n", index, cmd); - pclose(fp); + testutil_pclose(fp); return -1; } - pclose(fp); + testutil_pclose(fp); return 0; } diff --git a/backend/tests/testcommon.h b/backend/tests/testcommon.h index 2c4f2398..eccaee0d 100644 --- a/backend/tests/testcommon.h +++ b/backend/tests/testcommon.h @@ -42,17 +42,38 @@ #define ZINT_DEBUG_TEST_BWIPP 128 #define ZINT_DEBUG_TEST_PERFORMANCE 256 -#ifdef _WIN32 -#include -#define alloca(nmemb) _malloca(nmemb) -#define popen(command, mode) _popen(command, mode) -#define pclose(stream) _pclose(stream) +#ifdef _MSC_VER +#define testutil_popen(command, mode) _popen(command, mode) +#define testutil_pclose(stream) _pclose(stream) #else #include +#define testutil_popen(command, mode) popen(command, mode) +#define testutil_pclose(stream) pclose(stream) #endif + +#ifdef _WIN32 +#include +#define testutil_mkdir(path, mode) _mkdir(path) +#define testutil_rmdir(path) _rmdir(path) +#else +#define testutil_mkdir(path, mode) mkdir(path, mode) +#define testutil_rmdir(path) rmdir(path) +#endif + #include +#include #include "../common.h" +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wpedantic" +# pragma clang diagnostic ignored "-Woverlength-strings" +#elif defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wpedantic" +# pragma GCC diagnostic ignored "-Woverlength-strings" +#elif defined(_MSC_VER) +# pragma warning(disable: 4305) /* truncation from 'double' to 'float' */ +#endif + #ifdef __cplusplus extern "C" { #endif @@ -72,7 +93,9 @@ void testFinish(void); void testSkip(const char *msg); void testReport(); -typedef struct s_testFunction { const char *name; void *func; int has_index; int has_generate; int has_debug; } testFunction; +typedef struct s_testFunction { + const char *name; void *func; int has_index; int has_generate; int has_debug; +} testFunction; void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size); #define assert_exp(__exp__, ...) \ @@ -89,7 +112,8 @@ void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size); INTERNAL void vector_free(struct zint_symbol *symbol); /* Free vector structures */ -int testUtilSetSymbol(struct zint_symbol *symbol, int symbology, int input_mode, int eci, int option_1, int option_2, int option_3, int output_options, char *data, int length, int debug); +int testUtilSetSymbol(struct zint_symbol *symbol, int symbology, int input_mode, int eci, + int option_1, int option_2, int option_3, int output_options, char *data, int length, int debug); const char *testUtilBarcodeName(int symbology); const char *testUtilErrorName(int error_number); const char *testUtilInputModeName(int input_mode); @@ -129,10 +153,13 @@ int testUtilHaveVnu(); int testUtilVerifyVnu(char *filename, int debug); int testUtilHaveTiffInfo(); int testUtilVerifyTiffInfo(char *filename, int debug); -int testUtilCanBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3, int debug); -int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3, const char *data, int length, const char *primary, char *buffer, int buffer_size); +int testUtilCanBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3, + int debug); +int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3, + const char *data, int length, const char *primary, char *buffer, int buffer_size); int testUtilBwippCmp(const struct zint_symbol *symbol, char *msg, const char *bwipp_buf, const char *expected); -int testUtilBwippCmpRow(const struct zint_symbol *symbol, int row, char *msg, const char *bwipp_buf, const char *expected); +int testUtilBwippCmpRow(const struct zint_symbol *symbol, int row, char *msg, const char *bwipp_buf, + const char *expected); #ifdef __cplusplus } diff --git a/backend/tests/tools/run_bwipp_tests.sh b/backend/tests/tools/run_bwipp_tests.sh index ca495fcc..3e6cf762 100755 --- a/backend/tests/tools/run_bwipp_tests.sh +++ b/backend/tests/tools/run_bwipp_tests.sh @@ -6,10 +6,10 @@ set -e function run_bwipp_test() { if [ -z "$2" ]; then echo -e "\n$1" - ./$1 -d $(expr 128 + 16 + 32) || exit 1 + backend/tests/$1 -d $(expr 128 + 16 + 32) || exit 1 else echo -e "\n$1 -f $2" - ./$1 -f "$2" -d $(expr 128 + 16 + 32) || exit 1 + backend/tests/$1 -f "$2" -d $(expr 128 + 16 + 32) || exit 1 fi } diff --git a/backend/tif.c b/backend/tif.c index a950e122..899383c8 100644 --- a/backend/tif.c +++ b/backend/tif.c @@ -32,6 +32,7 @@ */ /* vim: set ts=4 sw=4 et : */ +#include #include #include #include @@ -333,14 +334,14 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf) if (symbol->output_options & BARCODE_STDOUT) { #ifdef _MSC_VER if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { - strcpy(symbol->errtxt, "671: Can't open output file"); + sprintf(symbol->errtxt, "671: Can't open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } #endif tif_file = stdout; } else { if (!(tif_file = fopen(symbol->outfile, "wb+"))) { - strcpy(symbol->errtxt, "672: Can't open output file"); + sprintf(symbol->errtxt, "672: Can't open output file (%d: %.30s)", errno, strerror(errno)); return ZINT_ERROR_FILE_ACCESS; } compression = TIF_LZW; diff --git a/backend/ultra.c b/backend/ultra.c index eaf0fa3d..2f19b953 100644 --- a/backend/ultra.c +++ b/backend/ultra.c @@ -1,7 +1,7 @@ /* ultra.c - Ultracode libzint - the open source barcode library - Copyright (C) 2020 Robin Stuart + Copyright (C) 2020 - 2021 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -58,7 +58,8 @@ static const char ultra_digit[] = "0123456789,/"; static const char ultra_colour[] = "0CBMRYGKW"; //static const int ultra_maxsize[] = {34, 78, 158, 282}; // According to Table 1 -static const int ultra_maxsize[] = {34, 81, 158, 282}; // Adjusted to allow 79-81 codeword range in 3-row symbols (only 1 secondary vertical clock track, not 2, so 3 extra) +// Adjusted to allow 79-81 codeword range in 3-row symbols (only 1 secondary vertical clock track, not 2, so 3 extra) +static const int ultra_maxsize[] = {34, 81, 158, 282}; static const int ultra_mincols[] = {5, 13, 23, 30}; // # Total Tile Columns from Table 1 @@ -208,7 +209,7 @@ static int ultra_find_fragment(const unsigned char source[], int source_length, for (j = 0; j < 27; j++) { latch = 0; - fraglen = strlen(fragment[j]); + fraglen = (int) strlen(fragment[j]); if ((position + fraglen) <= source_length) { latch = 1; for (k = 0; k < fraglen; k++) { @@ -228,8 +229,8 @@ static int ultra_find_fragment(const unsigned char source[], int source_length, } /* Encode characters in 8-bit mode */ -static float look_ahead_eightbit(unsigned char source[], int in_length, int in_locn, char current_mode, int end_char, int cw[], int* cw_len, int gs1) -{ +static float look_ahead_eightbit(unsigned char source[], int in_length, int in_locn, char current_mode, int end_char, + int cw[], int* cw_len, int gs1) { int codeword_count = 0; int i; int letters_encoded = 0; @@ -262,7 +263,8 @@ static float look_ahead_eightbit(unsigned char source[], int in_length, int in_l } /* Encode character in the ASCII mode/submode (including numeric compression) */ -static float look_ahead_ascii(unsigned char source[], int in_length, int in_locn, char current_mode, int symbol_mode, int end_char, int cw[], int* cw_len, int* encoded, int gs1) { +static float look_ahead_ascii(unsigned char source[], int in_length, int in_locn, char current_mode, int symbol_mode, + int end_char, int cw[], int* cw_len, int* encoded, int gs1) { int codeword_count = 0; int i; int first_digit, second_digit, done; @@ -370,7 +372,7 @@ static int c43_should_latch_other(const unsigned char data[], const int length, fragno = ultra_find_fragment(data, length, i); if (fragno != -1 && fragno != 26) { - fraglen = strlen(fragment[fragno]); + fraglen = (int) strlen(fragment[fragno]); predict_window += fraglen; if (predict_window > length) { predict_window = length; @@ -420,7 +422,8 @@ static int get_subset(unsigned char source[], int in_length, int in_locn, int cu } /* Encode characters in the C43 compaction submode */ -static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, char current_mode, int end_char, int subset, int cw[], int* cw_len, int* encoded, int gs1, int debug) { +static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, char current_mode, int end_char, + int subset, int cw[], int* cw_len, int* encoded, int gs1, int debug) { int codeword_count = 0; int subcodeword_count = 0; int i; @@ -435,7 +438,7 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, #ifndef _MSC_VER int subcw[(in_length + 3) * 2]; #else - int * subcw = (int *) _alloca((in_length + 3) * 2 * sizeof (int)); + int * subcw = (int *) _alloca((in_length + 3) * 2 * sizeof(int)); #endif /* _MSC_VER */ if (current_mode == EIGHTBIT_MODE) { @@ -451,32 +454,32 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, switch(fragno) { case 17: // mailto: cw[codeword_count] = 276; - sublocn += strlen(fragment[fragno]); + sublocn += (int) strlen(fragment[fragno]); codeword_count++; break; case 18: // tel: cw[codeword_count] = 277; - sublocn += strlen(fragment[fragno]); + sublocn += (int) strlen(fragment[fragno]); codeword_count++; break; case 26: // file: cw[codeword_count] = 278; - sublocn += strlen(fragment[fragno]); + sublocn += (int) strlen(fragment[fragno]); codeword_count++; break; case 0: // http:// cw[codeword_count] = 279; - sublocn += strlen(fragment[fragno]); + sublocn += (int) strlen(fragment[fragno]); codeword_count++; break; case 1: // https:// cw[codeword_count] = 280; - sublocn += strlen(fragment[fragno]); + sublocn += (int) strlen(fragment[fragno]); codeword_count++; break; case 4: // ftp:// cw[codeword_count] = 281; - sublocn += strlen(fragment[fragno]); + sublocn += (int) strlen(fragment[fragno]); codeword_count++; break; default: @@ -558,12 +561,12 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, if ((fragno >= 0) && (fragno <= 18)) { subcw[subcodeword_count] = fragno; // C43 Set 3 codewords 0 to 18 subcodeword_count++; - sublocn += strlen(fragment[fragno]); + sublocn += (int) strlen(fragment[fragno]); } if ((fragno >= 19) && (fragno <= 25)) { subcw[subcodeword_count] = fragno + 17; // C43 Set 3 codewords 36 to 42 subcodeword_count++; - sublocn += strlen(fragment[fragno]); + sublocn += (int) strlen(fragment[fragno]); } if (fragno == -1) { subcw[subcodeword_count] = posn(ultra_c43_set3, source[sublocn]) + 19; // C43 Set 3 codewords 19 to 35 @@ -637,9 +640,9 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c char mode[in_length + 1]; int cw_fragment[in_length * 2 + 1]; #else - unsigned char * crop_source = (unsigned char *) _alloca((in_length + 1) * sizeof (unsigned char)); - char * mode = (char *) _alloca((in_length + 1) * sizeof (char)); - int * cw_fragment = (int *) _alloca((in_length * 2 + 1) * sizeof (int)); + unsigned char * crop_source = (unsigned char *) _alloca(in_length + 1); + char * mode = (char *) _alloca(in_length + 1); + int * cw_fragment = (int *) _alloca((in_length * 2 + 1) * sizeof(int)); #endif /* _MSC_VER */ if ((symbol->input_mode & 0x07) == GS1_MODE) { @@ -769,10 +772,13 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c input_locn = 0; do { end_char = input_locn + PREDICT_WINDOW; - eightbit_score = look_ahead_eightbit(crop_source, crop_length, input_locn, current_mode, end_char, cw_fragment, &fragment_length, gs1); - ascii_score = look_ahead_ascii(crop_source, crop_length, input_locn, current_mode, symbol_mode, end_char, cw_fragment, &fragment_length, &ascii_encoded, gs1); + eightbit_score = look_ahead_eightbit(crop_source, crop_length, input_locn, current_mode, end_char, + cw_fragment, &fragment_length, gs1); + ascii_score = look_ahead_ascii(crop_source, crop_length, input_locn, current_mode, symbol_mode, + end_char, cw_fragment, &fragment_length, &ascii_encoded, gs1); subset = c43_should_latch_other(crop_source, crop_length, input_locn, 1 /*subset*/, gs1) ? 2 : 1; - c43_score = look_ahead_c43(crop_source, crop_length, input_locn, current_mode, end_char, subset, cw_fragment, &fragment_length, &c43_encoded, gs1, 0 /*debug*/); + c43_score = look_ahead_c43(crop_source, crop_length, input_locn, current_mode, end_char, + subset, cw_fragment, &fragment_length, &c43_encoded, gs1, 0 /*debug*/); mode[input_locn] = 'a'; current_mode = ASCII_MODE; @@ -824,21 +830,26 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c switch(mode[input_locn]) { case 'a': - look_ahead_ascii(crop_source, crop_length, input_locn, current_mode, symbol_mode, input_locn + block_length, cw_fragment, &fragment_length, NULL, gs1); + look_ahead_ascii(crop_source, crop_length, input_locn, current_mode, symbol_mode, + input_locn + block_length, cw_fragment, &fragment_length, NULL, gs1); current_mode = ASCII_MODE; break; case 'c': subset = c43_should_latch_other(crop_source, crop_length, input_locn, 1 /*subset*/, gs1) ? 2 : 1; - look_ahead_c43(crop_source, crop_length, input_locn, current_mode, input_locn + block_length, subset, cw_fragment, &fragment_length, NULL, gs1, symbol->debug); + look_ahead_c43(crop_source, crop_length, input_locn, current_mode, input_locn + block_length, subset, + cw_fragment, &fragment_length, NULL, gs1, symbol->debug); /* Substitute temporary latch if possible */ - if ((current_mode == EIGHTBIT_MODE) && (cw_fragment[0] == 260) && (fragment_length >= 5) && (fragment_length <= 11)) { + if ((current_mode == EIGHTBIT_MODE) && (cw_fragment[0] == 260) + && (fragment_length >= 5) && (fragment_length <= 11)) { /* Temporary latch to submode 1 from Table 11 */ cw_fragment[0] = 256 + ((fragment_length - 5) / 2); - } else if ((current_mode == EIGHTBIT_MODE) && (cw_fragment[0] == 266) && (fragment_length >= 5) && (fragment_length <= 11)) { + } else if ((current_mode == EIGHTBIT_MODE) && (cw_fragment[0] == 266) + && (fragment_length >= 5) && (fragment_length <= 11)) { /* Temporary latch to submode 2 from Table 11 */ cw_fragment[0] = 262 + ((fragment_length - 5) / 2); - } else if ((current_mode == ASCII_MODE) && (cw_fragment[0] == 278) && (fragment_length >= 5) && (fragment_length <= 11)) { + } else if ((current_mode == ASCII_MODE) && (cw_fragment[0] == 278) + && (fragment_length >= 5) && (fragment_length <= 11)) { /* Temporary latch to submode 1 from Table 9 */ cw_fragment[0] = 274 + ((fragment_length - 5) / 2); } else { @@ -846,7 +857,8 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c } break; case '8': - look_ahead_eightbit(crop_source, crop_length, input_locn, current_mode, input_locn + block_length, cw_fragment, &fragment_length, gs1); + look_ahead_eightbit(crop_source, crop_length, input_locn, current_mode, input_locn + block_length, + cw_fragment, &fragment_length, gs1); current_mode = EIGHTBIT_MODE; break; } @@ -870,7 +882,8 @@ INTERNAL int ultracode(struct zint_symbol *symbol, unsigned char source[], int l int total_cws; int pads; int cw_memalloc; - int codeword[282 + 3]; // Allow for 3 pads in final 57th (60th incl. clock tracks) column of 5-row symbol (57 * 5 == 285) + // Allow for 3 pads in final 57th (60th incl. clock tracks) column of 5-row symbol (57 * 5 == 285) + int codeword[282 + 3]; int i, j, locn; int total_height, total_width; char tilepat[6]; @@ -894,7 +907,7 @@ INTERNAL int ultracode(struct zint_symbol *symbol, unsigned char source[], int l #ifndef _MSC_VER int data_codewords[cw_memalloc]; #else - data_codewords = (int *) _alloca(cw_memalloc * sizeof (int)); + data_codewords = (int *) _alloca(cw_memalloc * sizeof(int)); #endif /* _MSC_VER */ data_cw_count = ultra_generate_codewords(symbol, source, length, data_codewords); @@ -943,7 +956,8 @@ INTERNAL int ultracode(struct zint_symbol *symbol, unsigned char source[], int l rows = 5; for (i = 2; i >= 0; i--) { - if (total_cws - 6 <= ultra_maxsize[i]) { // Total codewords less 6 overhead (Start + MCC + ACC + 3 TCC/RSEC/QCC patterns) + // Total codewords less 6 overhead (Start + MCC + ACC + 3 TCC/RSEC/QCC patterns) + if (total_cws - 6 <= ultra_maxsize[i]) { rows--; } } @@ -1005,7 +1019,7 @@ INTERNAL int ultracode(struct zint_symbol *symbol, unsigned char source[], int l #ifndef _MSC_VER char pattern[total_height * total_width]; #else - pattern = (char *) _alloca(total_height * total_width * sizeof (char)); + pattern = (char *) _alloca(total_height * total_width); #endif /* _MSC_VER */ for (i = 0; i < (total_height * total_width); i++) { diff --git a/backend/vector.c b/backend/vector.c index 208bb27c..f86685fb 100644 --- a/backend/vector.c +++ b/backend/vector.c @@ -52,7 +52,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle); static struct zint_vector_rect *vector_plot_create_rect(float x, float y, float width, float height) { struct zint_vector_rect *rect; - rect = (struct zint_vector_rect*) malloc(sizeof (struct zint_vector_rect)); + rect = (struct zint_vector_rect *) malloc(sizeof(struct zint_vector_rect)); if (!rect) return NULL; rect->next = NULL; @@ -79,7 +79,7 @@ static int vector_plot_add_rect(struct zint_symbol *symbol, struct zint_vector_r static struct zint_vector_hexagon *vector_plot_create_hexagon(float x, float y, float diameter) { struct zint_vector_hexagon *hexagon; - hexagon = (struct zint_vector_hexagon*) malloc(sizeof (struct zint_vector_hexagon)); + hexagon = (struct zint_vector_hexagon *) malloc(sizeof(struct zint_vector_hexagon)); if (!hexagon) return NULL; hexagon->next = NULL; hexagon->x = x; @@ -104,7 +104,7 @@ static int vector_plot_add_hexagon(struct zint_symbol *symbol, struct zint_vecto static struct zint_vector_circle *vector_plot_create_circle(float x, float y, float diameter, int colour) { struct zint_vector_circle *circle; - circle = (struct zint_vector_circle *) malloc(sizeof (struct zint_vector_circle)); + circle = (struct zint_vector_circle *) malloc(sizeof(struct zint_vector_circle)); if (!circle) return NULL; circle->next = NULL; circle->x = x; @@ -131,17 +131,17 @@ static int vector_plot_add_string(struct zint_symbol *symbol, struct zint_vector_string **last_string) { struct zint_vector_string *string; - string = (struct zint_vector_string*) malloc(sizeof (struct zint_vector_string)); + string = (struct zint_vector_string *) malloc(sizeof(struct zint_vector_string)); if (!string) return 0; string->next = NULL; string->x = x; string->y = y; string->width = width; string->fsize = fsize; - string->length = ustrlen(text); + string->length = (int) ustrlen(text); string->rotation = 0; string->halign = halign; - string->text = (unsigned char*) malloc(sizeof (unsigned char) * (ustrlen(text) + 1)); + string->text = (unsigned char *) malloc(ustrlen(text) + 1); if (!string->text) { free(string); return 0; } ustrcpy(string->text, text); @@ -433,7 +433,7 @@ INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_ } // Allocate memory - vector = symbol->vector = (struct zint_vector *) malloc(sizeof (struct zint_vector)); + vector = symbol->vector = (struct zint_vector *) malloc(sizeof(struct zint_vector)); if (!vector) return ZINT_ERROR_MEMORY; vector->rectangles = NULL; vector->hexagons = NULL; diff --git a/backend/zint.h b/backend/zint.h index d2ad7d67..f9c4d9d5 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -305,16 +305,16 @@ extern "C" { #define ZINT_DEBUG_PRINT 1 #define ZINT_DEBUG_TEST 2 -#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(_MSC_VER) -#if defined (DLL_EXPORT) || defined(PIC) || defined(_USRDLL) -#define ZINT_EXTERN __declspec(dllexport) -#elif defined(ZINT_DLL) -#define ZINT_EXTERN __declspec(dllimport) +#ifdef _WIN32 +# if defined(DLL_EXPORT) || defined(PIC) || defined(_USRDLL) +# define ZINT_EXTERN __declspec(dllexport) +# elif defined(ZINT_DLL) +# define ZINT_EXTERN __declspec(dllimport) +# else +# define ZINT_EXTERN extern +# endif #else -#define ZINT_EXTERN extern -#endif -#else -#define ZINT_EXTERN extern +# define ZINT_EXTERN extern #endif ZINT_EXTERN struct zint_symbol *ZBarcode_Create(void); diff --git a/cmake/zint_add_test.cmake b/cmake/zint_add_test.cmake index 29c88f61..86ae0f68 100644 --- a/cmake/zint_add_test.cmake +++ b/cmake/zint_add_test.cmake @@ -1,4 +1,4 @@ -# Copyright (C) 2020 Robin Stuart +# Copyright (C) 2021 Robin Stuart # Adapted from qrencode/tests/CMakeLists.txt # Copyright (C) 2006-2017 Kentaro Fukuchi # vim: set ts=4 sw=4 et : @@ -13,4 +13,4 @@ macro(zint_add_test test_name test_command) target_link_libraries(${test_command}-static testcommon-static ${ADDITIONAL_LIBS}) add_test(${test_name}-static ${test_command}-static) endif() -endmacro() +endmacro() diff --git a/docs/manual.txt b/docs/manual.txt index e6f60ce7..72b6450d 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -1470,8 +1470,8 @@ check digit is added by default. To add a check digit, set option_2 = 1 or --vers=1. To add a check digit but not show it in the human readable text, set option_2 = 2 or --vers=2. -6.1.2.4 Interleaved Code 2 of 5 -------------------------------- +6.1.2.4 Interleaved Code 2 of 5 (ISO 16390) +------------------------------------------- This self-checking symbology encodes pairs of numbers, and so can only encode an even number of digits (0-9). If an odd number of digits is entered a leading zero is added by Zint. No check digit is added by default. To add a check digit, @@ -1622,12 +1622,17 @@ encoded. The table below shows the options available: Value of option_2 | Check Digits ------------------------------------------- 0 | None -1 | Modulo-10 +1 | Modulo-10 (Luhn) 2 | Modulo-10 & Modulo-10 -3 | Modulo-11 -4 | Modulo-11 & Modulo-10 +3 | Modulo-11 (IBM) +4 | Modulo-11 (IBM) & Modulo-10 +5 | Modulo-11 (NCR) +6 | Modulo-11 (NCR) & Modulo-10 ------------------------------------------- +To not show the check digit or digits in the human readable text, add 10 to the +option_2 value. + 6.1.7 Telepen ------------- 6.1.7.1 Telepen Alpha @@ -3196,6 +3201,8 @@ international standards: > ISO/IEC JTC1/SC31N000 (Draft 2018-6-8) Information technology - Automatic identification and data capture techniques - Rectangular Micro QR Code (rMQR) bar code symbology specification +> ISO/IEC 16390:2007 Information technology - Automatic identification and data + capture techniques - Interleaved 2 of 5 bar code symbology specification > Uniform Symbology Specification Code One (AIM Inc., 1994) > ANSI/AIM BC12-1998 - Uniform Symbology Specification Channel Code > ANSI/AIM BC6-2000 - Uniform Symbology Specification Code 49 diff --git a/frontend/CMakeLists.txt b/frontend/CMakeLists.txt index f873b43a..ce1a4368 100644 --- a/frontend/CMakeLists.txt +++ b/frontend/CMakeLists.txt @@ -1,4 +1,5 @@ -# (c) 2008 by BogDan Vatra < bogdan@licentia.eu > +# Copyright (C) 2008 by BogDan Vatra < bogdan@licentia.eu > +# Copyright (C) 2009-2021 Robin Stuart project(zint_frontend) @@ -8,15 +9,15 @@ include_directories(BEFORE "${CMAKE_SOURCE_DIR}/backend") add_executable(zint_frontend ${zint_frontend_SRCS}) -set_target_properties(zint_frontend PROPERTIES OUTPUT_NAME "zint") +set_target_properties(zint_frontend PROPERTIES OUTPUT_NAME "zint") target_link_libraries(zint_frontend zint) if(NOT HAVE_GETOPT) target_link_libraries(zint_frontend zint_bundled_getopt) -endif(NOT HAVE_GETOPT) +endif() install(TARGETS zint_frontend DESTINATION "${BIN_INSTALL_DIR}" RUNTIME) if(ZINT_TEST) add_subdirectory(tests) -endif(ZINT_TEST) +endif() diff --git a/frontend/main.c b/frontend/main.c index 0261a2ab..c92fff96 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -29,9 +29,12 @@ #include #else #include -#include "getopt.h" +#include "../getopt/getopt.h" #include "zint.h" +#if _MSC_VER >= 1900 /* MSVC 2015 */ +#pragma warning(disable: 4996) /* function or variable may be unsafe */ #endif +#endif /* _MSC_VER */ /* It's assumed that int is at least 32 bits, the following will compile-time fail if not * https://stackoverflow.com/a/1980056/664741 */ @@ -330,6 +333,7 @@ static int get_barcode_name(const char *barcode_name) { { BARCODE_MAXICODE, "maxicode" }, { BARCODE_MICROPDF417, "micropdf417" }, { BARCODE_MICROQR, "microqr" }, + { BARCODE_MSI_PLESSEY, "msi" }, /* Synonym */ { BARCODE_MSI_PLESSEY, "msiplessey" }, { BARCODE_NVE18, "nve18" }, { BARCODE_PDF417, "pdf417" }, diff --git a/frontend/tests/README b/frontend/tests/README index 8954211a..01d0608f 100644 --- a/frontend/tests/README +++ b/frontend/tests/README @@ -2,8 +2,8 @@ Zint frontend test suite ------------------------ See /backend/tests/README to see how to build the test suite. -In Addition to the setup for the backend tests, the environment needs to be -able to find the `zint` application using that name. In UNIX like systems +In addition to the setup for the backend tests, the environment needs to be +able to find the `zint` application using that name. In UNIX-like systems this can be configured by prepending the PATH variable with the frontend's directory inside the build directory: diff --git a/frontend/tests/test_args.c b/frontend/tests/test_args.c index 36b5132c..0865ead6 100644 --- a/frontend/tests/test_args.c +++ b/frontend/tests/test_args.c @@ -29,18 +29,80 @@ */ /* vim: set ts=4 sw=4 et : */ -#include #include "testcommon.h" +#ifdef _WIN32 +/* Hacks to stop popen() mangling input on Windows */ +static int utf8_to_wchar(const char *str, wchar_t *out) { + unsigned int codepoint, state = 0; + + while (*str) { + do { + decode_utf8(&state, &codepoint, *str++); + } while (*str && state != 0 && state != 12); + if (state != 0) { + fprintf(stderr, "utf8_to_wchar: warning: invalid UTF-8\n"); + return 0; + } + *out++ = codepoint; + } + *out = L'\0'; + + return 1; +} + +static int escape_cmd(const char *str, char *buf) { + int ret = 0; + char *out = buf; + const unsigned char *ustr; + + for (ustr = (const unsigned char *) str; *ustr; ustr++) { + if (*ustr >= 0x80 || *ustr < 0x20 || *ustr == '\\') { + sprintf(out, "\\x%02X", *ustr); + out += 4; + ret = 1; + } else { + *out++ = *ustr; + } + } + *out = '\0'; + if (ret) { + if (out - buf > 5 && strcmp(out - 5, " 2>&1") == 0) { + strcpy(out - 5, " --esc 2>&1"); + } else { + strcpy(out, " --esc"); + } + } + + return ret; +} +#endif + static char *exec(const char *cmd, char *buf, int buf_size, int debug, int index) { FILE *fp; int cnt; +#ifdef _WIN32 + wchar_t wchar_cmd[8192]; + char esc_cmd[16384]; + int is_binary = strstr(cmd, " --binary") != NULL; + int is_escaped = strstr(cmd, " --esc") != NULL; +#endif if (debug & ZINT_DEBUG_TEST_PRINT) printf("%d: %s\n", index, cmd); *buf = '\0'; - fp = popen(cmd, "r"); +#ifdef _WIN32 + if (!is_binary && utf8_to_wchar(cmd, wchar_cmd)) { + fp = _wpopen(wchar_cmd, L"r"); + } else if (!is_escaped && is_binary && escape_cmd(cmd, esc_cmd)) { + fp = testutil_popen(esc_cmd, "r"); + } else { + fp = testutil_popen(cmd, "r"); + } +#else + fp = testutil_popen(cmd, "r"); +#endif if (!fp) { fprintf(stderr, "exec: failed to run '%s'\n", cmd); return NULL; @@ -48,10 +110,10 @@ static char *exec(const char *cmd, char *buf, int buf_size, int debug, int index cnt = fread(buf, 1, buf_size, fp); if (fgetc(fp) != EOF) { fprintf(stderr, "exec: failed to read full stream (%s)\n", cmd); - pclose(fp); + testutil_pclose(fp); return NULL; } - pclose(fp); + testutil_pclose(fp); if (cnt) { if (buf[cnt - 1] == '\r' || buf[cnt - 1] == '\n') { @@ -85,7 +147,7 @@ static void arg_double(char *cmd, const char *opt, double val) { static void arg_data(char *cmd, const char *opt, const char *data) { if (data != NULL) { - sprintf(cmd + (int) strlen(cmd), "%s%s'%s'", strlen(cmd) ? " " : "", opt, data); + sprintf(cmd + (int) strlen(cmd), "%s%s\"%s\"", strlen(cmd) ? " " : "", opt, data); } } @@ -107,7 +169,7 @@ static int arg_input(char *cmd, const char *filename, const char *input) { } fclose(fp); } - sprintf(cmd + (int) strlen(cmd), "%s-i '%s'", strlen(cmd) ? " " : "", filename); + sprintf(cmd + (int) strlen(cmd), "%s-i \"%s\"", strlen(cmd) ? " " : "", filename); return 1; } return 0; @@ -277,10 +339,10 @@ static void test_dump_args(int index, int debug) { assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd); if (have_input1) { - assert_zero(remove(input1_filename), "i:%d remove(%s) != 0 (%d)\n", i, input1_filename, errno); + assert_zero(remove(input1_filename), "i:%d remove(%s) != 0 (%d: %s)\n", i, input1_filename, errno, strerror(errno)); } if (have_input2) { - assert_zero(remove(input2_filename), "i:%d remove(%s) != 0\n", i, input2_filename); + assert_zero(remove(input2_filename), "i:%d remove(%s) != 0 (%d: %s)\n", i, input2_filename, errno, strerror(errno)); } } @@ -291,6 +353,12 @@ static void test_input(int index, int debug) { testStart(""); +#ifdef _WIN32 +#define TEST_INPUT_LONG "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234" +#else +#define TEST_INPUT_LONG "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" +#endif + struct item { int b; int batch; @@ -305,19 +373,19 @@ static void test_input(int index, int debug) { }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n456\n", "test_batch~.png", 2, "test_batch1.png\000test_batch2.png" }, - /* 1*/ { BARCODE_CODE128, 1, -1, 1, NULL, "123\n456\n7890123456789\n", NULL, 3, "123.png\000456.png\0007890123456789.png" }, + /* 0*/ { BARCODE_CODE128, 1, -1, 0, "gif", "123\n456\n", "test_batch~.gif", 2, "test_batch1.gif\000test_batch2.gif" }, + /* 1*/ { BARCODE_CODE128, 1, -1, 1, "gif", "123\n456\n7890123456789\n", NULL, 3, "123.gif\000456.gif\0007890123456789.gif" }, /* 2*/ { BARCODE_CODE128, 1, -1, 1, "svg", "123\n456\n7890123456789\n", NULL, 3, "123.svg\000456.svg\0007890123456789.svg" }, - /* 3*/ { BARCODE_CODE128, 1, -1, 1, NULL, "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_xA0B.png" }, - /* 4*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, NULL, "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_B.png" }, - /* 5*/ { BARCODE_CODE128, 1, -1, 1, NULL, "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_u00A0B.png" }, - /* 6*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, NULL, "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_B.png" }, - /* 7*/ { BARCODE_CODE128, 1, -1, 0, NULL, "\n", "test_batch.png", 0, NULL }, - /* 8*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n456\n", "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890~.png", 2, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png\000test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678902.png" }, - /* 9*/ { BARCODE_CODE128, 0, -1, 0, "svg", "123", "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png", 1, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.svg" }, - /* 10*/ { BARCODE_CODE128, 1, -1, 0, "svg", "123\n", "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png", 1, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.svg" }, - /* 11*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n", "test_batch.jpeg", 1, "test_batch.jpeg.png" }, - /* 12*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n", "test_batch.jpg", 1, "test_batch.png" }, + /* 3*/ { BARCODE_CODE128, 1, -1, 1, "gif", "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A_xA0B.gif" }, + /* 4*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, "gif", "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A_B.gif" }, + /* 5*/ { BARCODE_CODE128, 1, -1, 1, "gif", "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A_u00A0B.gif" }, + /* 6*/ { BARCODE_CODE128, 1, ESCAPE_MODE, 1, "gif", "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.gif\000456.gif\0007890123456789.gif\000A_B.gif" }, + /* 7*/ { BARCODE_CODE128, 1, -1, 0, "gif", "\n", "test_batch.gif", 0, NULL }, + /* 8*/ { BARCODE_CODE128, 1, -1, 0, "gif", "123\n456\n", TEST_INPUT_LONG "~.gif", 2, TEST_INPUT_LONG "1.gif\000" TEST_INPUT_LONG "2.gif" }, + /* 9*/ { BARCODE_CODE128, 0, -1, 0, "svg", "123", TEST_INPUT_LONG "1.gif", 1, TEST_INPUT_LONG "1.svg" }, + /* 10*/ { BARCODE_CODE128, 1, -1, 0, "svg", "123\n", TEST_INPUT_LONG "1.gif", 1, TEST_INPUT_LONG "1.svg" }, + /* 11*/ { BARCODE_CODE128, 1, -1, 0, "gif", "123\n", "test_batch.jpeg", 1, "test_batch.jpeg.gif" }, + /* 12*/ { BARCODE_CODE128, 1, -1, 0, "gif", "123\n", "test_batch.jpg", 1, "test_batch.gif" }, /* 13*/ { BARCODE_CODE128, 1, -1, 0, "emf", "123\n", "test_batch.jpeg", 1, "test_batch.jpeg.emf" }, /* 14*/ { BARCODE_CODE128, 1, -1, 0, "emf", "123\n", "test_batch.jpg", 1, "test_batch.emf" }, /* 15*/ { BARCODE_CODE128, 1, -1, 0, "eps", "123\n", "test_batch.ps", 1, "test_batch.eps" }, @@ -353,11 +421,11 @@ static void test_input(int index, int debug) { outfile = data[i].expected; for (int j = 0; j < data[i].num_expected; j++) { assert_nonzero(testUtilExists(outfile), "i:%d j:%d testUtilExists(%s) != 1\n", i, j, outfile); - assert_zero(remove(outfile), "i:%d j:%d remove(%s) != 0 (%d)\n", i, j, outfile, errno); + assert_zero(remove(outfile), "i:%d j:%d remove(%s) != 0 (%d: %s)\n", i, j, outfile, errno, strerror(errno)); outfile += strlen(outfile) + 1; } - assert_zero(remove(input_filename), "i:%d remove(%s) != 0 (%d)\n", i, input_filename, errno); + assert_zero(remove(input_filename), "i:%d remove(%s) != 0 (%d: %s)\n", i, input_filename, errno, strerror(errno)); } testFinish(); @@ -375,7 +443,7 @@ static void test_stdin_input(int index, int debug) { }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_CODE128, "123", "-", "test_stdin_input.png" }, + /* 0*/ { BARCODE_CODE128, "123", "-", "test_stdin_input.gif" }, }; int data_size = ARRAY_SIZE(data); @@ -400,7 +468,7 @@ static void test_stdin_input(int index, int debug) { assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i), "i:%d exec(%s) NULL\n", i, cmd); assert_nonzero(testUtilExists(data[i].outfile), "i:%d testUtilExists(%s) != 1\n", i, data[i].outfile); - assert_zero(remove(data[i].outfile), "i:%d remove(%s) != 0 (%d)\n", i, data[i].outfile, errno); + assert_zero(remove(data[i].outfile), "i:%d remove(%s) != 0 (%d: %s)\n", i, data[i].outfile, errno, strerror(errno)); } testFinish(); @@ -455,10 +523,10 @@ static void test_batch_input(int index, int debug) { assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s)\n", i, buf, data[i].expected); if (have_input1) { - assert_zero(remove(input1_filename), "i:%d remove(%s) != 0 (%d)\n", i, input1_filename, errno); + assert_zero(remove(input1_filename), "i:%d remove(%s) != 0 (%d: %s)\n", i, input1_filename, errno, strerror(errno)); } if (have_input2) { - assert_zero(remove(input2_filename), "i:%d remove(%s) != 0\n", i, input2_filename); + assert_zero(remove(input2_filename), "i:%d remove(%s) != 0 (%d: %s)\n", i, input2_filename, errno, strerror(errno)); } } @@ -469,6 +537,11 @@ static void test_batch_large(int index, int debug) { testStart(""); +#ifdef _WIN32 + testSkip("Test not compatible with Windows"); + return; +#endif + struct item { int b; int mirror; @@ -479,8 +552,8 @@ static void test_batch_large(int index, int debug) { }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_HANXIN, 0, "1", 7827, "out.png" }, - /* 1*/ { BARCODE_HANXIN, 1, "1", 7827, "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.png" }, + /* 0*/ { BARCODE_HANXIN, 0, "1", 7827, "out.gif" }, + /* 1*/ { BARCODE_HANXIN, 1, "1", 7827, "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.gif" }, /* 2*/ { BARCODE_HANXIN, 0, "1", 7828, NULL }, }; int data_size = ARRAY_SIZE(data); @@ -497,7 +570,7 @@ static void test_batch_large(int index, int debug) { if (index != -1 && i != index) continue; if ((debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) printf("i:%d\n", i); - strcpy(cmd, "zint --batch"); + strcpy(cmd, "zint --batch --filetype=gif"); if (debug & ZINT_DEBUG_PRINT) { strcat(cmd, " --verbose"); } @@ -511,13 +584,13 @@ static void test_batch_large(int index, int debug) { assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i), "i:%d exec(%s) NULL\n", i, cmd); if (data[i].expected) { - assert_zero(remove(data[i].expected), "i:%d remove(%s) != 0 (%d)\n", i, data[i].expected, errno); + assert_zero(remove(data[i].expected), "i:%d remove(%s) != 0 (%d: %s)\n", i, data[i].expected, errno, strerror(errno)); } else { - assert_zero(testUtilExists("out.png"), "i:%d testUtilExists(out.png) != 0 (%d)\n", i, errno); + assert_zero(testUtilExists("out.gif"), "i:%d testUtilExists(out.gif) != 0 (%d: %s) (%s)\n", i, errno, strerror(errno), cmd); } if (have_input) { - assert_zero(remove(input_filename), "i:%d remove(%s) != 0 (%d)\n", i, input_filename, errno); + assert_zero(remove(input_filename), "i:%d remove(%s) != 0 (%d: %s)\n", i, input_filename, errno, strerror(errno)); } } @@ -573,7 +646,7 @@ static void test_checks(int index, int debug) { /* 18*/ { -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, "Error 132: Invalid rows value" }, /* 19*/ { -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, 45, -1, -1, -1, -1, -1, -1, -1, "Warning 112: Number of rows out of range" }, /* 20*/ { -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, -1, "Warning 105: Invalid scale value" }, - /* 21*/ { -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, 0.49, -1, -1, -1, -1, -1, -1, "Warning 146: Scaling less than 0.5 will be set to 0.5 for 'png' output" }, + /* 21*/ { -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, 0.49, -1, -1, -1, -1, -1, -1, "Warning 146: Scaling less than 0.5 will be set to 0.5 for 'gif' output" }, /* 22*/ { -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, "Error 149: Invalid Structured Carrier Message version value" }, /* 23*/ { -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, "Warning 150: Invalid version (vv) for Structured Carrier Message, ignoring" }, /* 24*/ { -1, -1, -1, -1, -1, NULL, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, "Error 134: Invalid ECC value" }, @@ -591,13 +664,13 @@ static void test_checks(int index, int debug) { char cmd[4096]; char buf[4096]; - char *outfilename = "out.png"; + char *outfilename = "out.gif"; for (int i = 0; i < data_size; i++) { if (index != -1 && i != index) continue; - strcpy(cmd, "zint -d '1'"); + strcpy(cmd, "zint -d 1 --filetype=gif"); if (debug & ZINT_DEBUG_PRINT) { strcat(cmd, " --verbose"); } @@ -627,7 +700,7 @@ static void test_checks(int index, int debug) { assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s)\n", i, buf, data[i].expected); if (strncmp(data[i].expected, "Warning", 7) == 0) { - assert_zero(remove(outfilename), "i:%d remove(%s) != 0 (%d)\n", i, outfilename, errno); + assert_zero(remove(outfilename), "i:%d remove(%s) != 0 (%d: %s)\n", i, outfilename, errno, strerror(errno)); } } @@ -684,101 +757,102 @@ static void test_barcode_symbology(int index, int debug) { /* 34*/ { "upce", "1", NULL, 0, "symbology: 37," }, /* 35*/ { "upce chk", "12345670", NULL, 0, "symbology: 38," }, /* 36*/ { "POSTNET ", "12345678901", NULL, 0, "symbology: 40," }, - /* 37*/ { "MSI Plessey ", "1", NULL, 0, "symbology: 47," }, - /* 38*/ { "fim ", "A", NULL, 0, "symbology: 49," }, - /* 39*/ { "LOGMARS", "123456", NULL, 0, "symbology: 50," }, - /* 40*/ { " pharma", "123456", NULL, 0, "symbology: 51," }, - /* 41*/ { " pzn ", "1", NULL, 0, "symbology: 52," }, - /* 42*/ { "pharma two", "4", NULL, 0, "symbology: 53," }, - /* 43*/ { "BARCODE_PDF417", "1", NULL, 0, "symbology: 55," }, - /* 44*/ { "barcodepdf417comp", "1", NULL, 0, "symbology: 56," }, - /* 45*/ { "MaxiCode", "1", NULL, 0, "symbology: 57," }, - /* 46*/ { "QR CODE", "1", NULL, 0, "symbology: 58," }, - /* 47*/ { "qr", "1", NULL, 0, "symbology: 58," }, // Synonym - /* 48*/ { "Code 128 B", "1", NULL, 0, "symbology: 60," }, - /* 49*/ { "AUS POST", "12345678901234567890123", NULL, 0, "symbology: 63," }, - /* 50*/ { "AusReply", "12345678", NULL, 0, "symbology: 66," }, - /* 51*/ { "AUSROUTE", "12345678", NULL, 0, "symbology: 67," }, - /* 52*/ { "AUS REDIRECT", "12345678", NULL, 0, "symbology: 68," }, - /* 53*/ { "isbnx", "123456789", NULL, 0, "symbology: 69," }, - /* 54*/ { "rm4scc", "1", NULL, 0, "symbology: 70," }, - /* 55*/ { "DataMatrix", "1", NULL, 0, "symbology: 71," }, - /* 56*/ { "EAN14", "1", NULL, 0, "symbology: 72," }, - /* 57*/ { "vin", "12345678701234567", NULL, 0, "symbology: 73," }, - /* 58*/ { "CodaBlock-F", "1", NULL, 0, "symbology: 74," }, - /* 59*/ { "NVE18", "1", NULL, 0, "symbology: 75," }, - /* 60*/ { "Japan Post", "1", NULL, 0, "symbology: 76," }, - /* 61*/ { "Korea Post", "1", NULL, 0, "symbology: 77," }, - /* 62*/ { "DBar Stk", "1", NULL, 0, "symbology: 79," }, - /* 63*/ { "DBar Omn Stk", "1", NULL, 0, "symbology: 80," }, - /* 64*/ { "DBar Exp Stk", "[20]01", NULL, 0, "symbology: 81," }, - /* 65*/ { "planet", "12345678901", NULL, 0, "symbology: 82," }, - /* 66*/ { "MicroPDF417", "1", NULL, 0, "symbology: 84," }, - /* 67*/ { "USPS IMail", "12345678901234567890", NULL, 0, "symbology: 85," }, - /* 68*/ { "plessey", "1", NULL, 0, "symbology: 86," }, - /* 69*/ { "telepen num", "1", NULL, 0, "symbology: 87," }, - /* 70*/ { "ITF14", "1", NULL, 0, "symbology: 89," }, - /* 71*/ { "KIX", "1", NULL, 0, "symbology: 90," }, - /* 72*/ { "Aztec", "1", NULL, 0, "symbology: 92," }, - /* 73*/ { "daft", "D", NULL, 0, "symbology: 93," }, - /* 74*/ { "DPD", "0123456789012345678901234567", NULL, 0, "symbology: 96," }, - /* 75*/ { "Micro QR", "1", NULL, 0, "symbology: 97," }, - /* 76*/ { "hibc128", "1", NULL, 0, "symbology: 98," }, - /* 77*/ { "hibccode128", "1", NULL, 0, "symbology: 98," }, // Synonym - /* 78*/ { "hibc39", "1", NULL, 0, "symbology: 99," }, - /* 79*/ { "hibccode39", "1", NULL, 0, "symbology: 99," }, // Synonym - /* 80*/ { "hibcdatamatrix", "1", NULL, 0, "symbology: 102," }, // Synonym - /* 81*/ { "hibcdm", "1", NULL, 0, "symbology: 102," }, - /* 82*/ { "HIBC qr", "1", NULL, 0, "symbology: 104," }, - /* 83*/ { "HIBC QR Code", "1", NULL, 0, "symbology: 104," }, // Synonym - /* 84*/ { "HIBCPDF", "1", NULL, 0, "symbology: 106," }, - /* 85*/ { "HIBCPDF417", "1", NULL, 0, "symbology: 106," }, // Synonym - /* 86*/ { "HIBCMICPDF", "1", NULL, 0, "symbology: 108," }, - /* 87*/ { "HIBC Micro PDF", "1", NULL, 0, "symbology: 108," }, // Synonym - /* 88*/ { "HIBC Micro PDF417", "1", NULL, 0, "symbology: 108," }, // Synonym - /* 89*/ { "HIBC BlockF", "1", NULL, 0, "symbology: 110," }, - /* 90*/ { "HIBC CodaBlock-F", "1", NULL, 0, "symbology: 110," }, // Synonym - /* 91*/ { "HIBC Aztec", "1", NULL, 0, "symbology: 112," }, - /* 92*/ { "DotCode", "1", NULL, 0, "symbology: 115," }, - /* 93*/ { "Han Xin", "1", NULL, 0, "symbology: 116," }, - /* 94*/ { "Mailmark", "01000000000000000AA00AA0A", NULL, 0, "symbology: 121," }, - /* 95*/ { "azrune", "1", NULL, 0, "symbology: 128," }, - /* 96*/ { "aztecrune", "1", NULL, 0, "symbology: 128," }, // Synonym - /* 97*/ { "aztecrunes", "1", NULL, 0, "symbology: 128," }, // Synonym - /* 98*/ { "code32", "1", NULL, 0, "symbology: 129," }, - /* 99*/ { "eanx cc", "[20]01", "1234567890128", 0, "symbology: 130," }, - /*100*/ { "eancc", "[20]01", "1234567890128", 0, "symbology: 130," }, - /*101*/ { "GS1 128 CC", "[01]12345678901231", "[20]01", 0, "symbology: 131," }, - /*102*/ { "dbaromncc", "[20]01", "1234567890123", 0, "symbology: 132," }, - /*103*/ { "dbarltdcc", "[20]01", "1234567890123", 0, "symbology: 133," }, - /*104*/ { "dbarexpcc", "[20]01", "[01]12345678901231", 0, "symbology: 134," }, - /*105*/ { "upcacc", "[20]01", "12345678901", 0, "symbology: 135," }, - /*106*/ { "upcecc", "[20]01", "1234567", 0, "symbology: 136," }, - /*107*/ { "dbar stk cc", "[20]01", "1234567890123", 0, "symbology: 137," }, - /*108*/ { "dbaromnstkcc", "[20]01", "1234567890123", 0, "symbology: 138," }, - /*109*/ { "dbarexpstkcc", "[20]01", "[01]12345678901231", 0, "symbology: 139," }, - /*110*/ { "Channel", "1", NULL, 0, "symbology: 140," }, - /*111*/ { "CodeOne", "1", NULL, 0, "symbology: 141," }, - /*112*/ { "Grid Matrix", "1", NULL, 0, "symbology: 142," }, - /*113*/ { "UPN QR", "1", NULL, 0, "symbology: 143," }, - /*114*/ { "UPN QR Code", "1", NULL, 0, "symbology: 143," }, // Synonym - /*115*/ { "ultra", "1", NULL, 0, "symbology: 144," }, - /*116*/ { "ultracode", "1", NULL, 0, "symbology: 144," }, // Synonym - /*117*/ { "rMQR", "1", NULL, 0, "symbology: 145," }, - /*118*/ { "x", "1", NULL, 1, "Error 119: Invalid barcode type 'x'" }, - /*119*/ { "\177", "1", NULL, 1, "Error 119: Invalid barcode type '\177'" }, + /* 37*/ { "msi", "1", NULL, 0, "symbology: 47," }, + /* 38*/ { "MSI Plessey ", "1", NULL, 0, "symbology: 47," }, + /* 39*/ { "fim ", "A", NULL, 0, "symbology: 49," }, + /* 40*/ { "LOGMARS", "123456", NULL, 0, "symbology: 50," }, + /* 41*/ { " pharma", "123456", NULL, 0, "symbology: 51," }, + /* 42*/ { " pzn ", "1", NULL, 0, "symbology: 52," }, + /* 43*/ { "pharma two", "4", NULL, 0, "symbology: 53," }, + /* 44*/ { "BARCODE_PDF417", "1", NULL, 0, "symbology: 55," }, + /* 45*/ { "barcodepdf417comp", "1", NULL, 0, "symbology: 56," }, + /* 46*/ { "MaxiCode", "1", NULL, 0, "symbology: 57," }, + /* 47*/ { "QR CODE", "1", NULL, 0, "symbology: 58," }, + /* 48*/ { "qr", "1", NULL, 0, "symbology: 58," }, // Synonym + /* 49*/ { "Code 128 B", "1", NULL, 0, "symbology: 60," }, + /* 50*/ { "AUS POST", "12345678901234567890123", NULL, 0, "symbology: 63," }, + /* 51*/ { "AusReply", "12345678", NULL, 0, "symbology: 66," }, + /* 52*/ { "AUSROUTE", "12345678", NULL, 0, "symbology: 67," }, + /* 53*/ { "AUS REDIRECT", "12345678", NULL, 0, "symbology: 68," }, + /* 54*/ { "isbnx", "123456789", NULL, 0, "symbology: 69," }, + /* 55*/ { "rm4scc", "1", NULL, 0, "symbology: 70," }, + /* 56*/ { "DataMatrix", "1", NULL, 0, "symbology: 71," }, + /* 57*/ { "EAN14", "1", NULL, 0, "symbology: 72," }, + /* 58*/ { "vin", "12345678701234567", NULL, 0, "symbology: 73," }, + /* 59*/ { "CodaBlock-F", "1", NULL, 0, "symbology: 74," }, + /* 60*/ { "NVE18", "1", NULL, 0, "symbology: 75," }, + /* 61*/ { "Japan Post", "1", NULL, 0, "symbology: 76," }, + /* 62*/ { "Korea Post", "1", NULL, 0, "symbology: 77," }, + /* 63*/ { "DBar Stk", "1", NULL, 0, "symbology: 79," }, + /* 64*/ { "DBar Omn Stk", "1", NULL, 0, "symbology: 80," }, + /* 65*/ { "DBar Exp Stk", "[20]01", NULL, 0, "symbology: 81," }, + /* 66*/ { "planet", "12345678901", NULL, 0, "symbology: 82," }, + /* 67*/ { "MicroPDF417", "1", NULL, 0, "symbology: 84," }, + /* 68*/ { "USPS IMail", "12345678901234567890", NULL, 0, "symbology: 85," }, + /* 69*/ { "plessey", "1", NULL, 0, "symbology: 86," }, + /* 70*/ { "telepen num", "1", NULL, 0, "symbology: 87," }, + /* 71*/ { "ITF14", "1", NULL, 0, "symbology: 89," }, + /* 72*/ { "KIX", "1", NULL, 0, "symbology: 90," }, + /* 73*/ { "Aztec", "1", NULL, 0, "symbology: 92," }, + /* 74*/ { "daft", "D", NULL, 0, "symbology: 93," }, + /* 75*/ { "DPD", "0123456789012345678901234567", NULL, 0, "symbology: 96," }, + /* 76*/ { "Micro QR", "1", NULL, 0, "symbology: 97," }, + /* 77*/ { "hibc128", "1", NULL, 0, "symbology: 98," }, + /* 78*/ { "hibccode128", "1", NULL, 0, "symbology: 98," }, // Synonym + /* 79*/ { "hibc39", "1", NULL, 0, "symbology: 99," }, + /* 80*/ { "hibccode39", "1", NULL, 0, "symbology: 99," }, // Synonym + /* 81*/ { "hibcdatamatrix", "1", NULL, 0, "symbology: 102," }, // Synonym + /* 82*/ { "hibcdm", "1", NULL, 0, "symbology: 102," }, + /* 83*/ { "HIBC qr", "1", NULL, 0, "symbology: 104," }, + /* 84*/ { "HIBC QR Code", "1", NULL, 0, "symbology: 104," }, // Synonym + /* 85*/ { "HIBCPDF", "1", NULL, 0, "symbology: 106," }, + /* 86*/ { "HIBCPDF417", "1", NULL, 0, "symbology: 106," }, // Synonym + /* 87*/ { "HIBCMICPDF", "1", NULL, 0, "symbology: 108," }, + /* 88*/ { "HIBC Micro PDF", "1", NULL, 0, "symbology: 108," }, // Synonym + /* 89*/ { "HIBC Micro PDF417", "1", NULL, 0, "symbology: 108," }, // Synonym + /* 90*/ { "HIBC BlockF", "1", NULL, 0, "symbology: 110," }, + /* 91*/ { "HIBC CodaBlock-F", "1", NULL, 0, "symbology: 110," }, // Synonym + /* 92*/ { "HIBC Aztec", "1", NULL, 0, "symbology: 112," }, + /* 93*/ { "DotCode", "1", NULL, 0, "symbology: 115," }, + /* 94*/ { "Han Xin", "1", NULL, 0, "symbology: 116," }, + /* 95*/ { "Mailmark", "01000000000000000AA00AA0A", NULL, 0, "symbology: 121," }, + /* 96*/ { "azrune", "1", NULL, 0, "symbology: 128," }, + /* 97*/ { "aztecrune", "1", NULL, 0, "symbology: 128," }, // Synonym + /* 98*/ { "aztecrunes", "1", NULL, 0, "symbology: 128," }, // Synonym + /* 99*/ { "code32", "1", NULL, 0, "symbology: 129," }, + /*100*/ { "eanx cc", "[20]01", "1234567890128", 0, "symbology: 130," }, + /*101*/ { "eancc", "[20]01", "1234567890128", 0, "symbology: 130," }, + /*102*/ { "GS1 128 CC", "[01]12345678901231", "[20]01", 0, "symbology: 131," }, + /*103*/ { "dbaromncc", "[20]01", "1234567890123", 0, "symbology: 132," }, + /*104*/ { "dbarltdcc", "[20]01", "1234567890123", 0, "symbology: 133," }, + /*105*/ { "dbarexpcc", "[20]01", "[01]12345678901231", 0, "symbology: 134," }, + /*106*/ { "upcacc", "[20]01", "12345678901", 0, "symbology: 135," }, + /*107*/ { "upcecc", "[20]01", "1234567", 0, "symbology: 136," }, + /*108*/ { "dbar stk cc", "[20]01", "1234567890123", 0, "symbology: 137," }, + /*109*/ { "dbaromnstkcc", "[20]01", "1234567890123", 0, "symbology: 138," }, + /*110*/ { "dbarexpstkcc", "[20]01", "[01]12345678901231", 0, "symbology: 139," }, + /*111*/ { "Channel", "1", NULL, 0, "symbology: 140," }, + /*112*/ { "CodeOne", "1", NULL, 0, "symbology: 141," }, + /*113*/ { "Grid Matrix", "1", NULL, 0, "symbology: 142," }, + /*114*/ { "UPN QR", "1", NULL, 0, "symbology: 143," }, + /*115*/ { "UPN QR Code", "1", NULL, 0, "symbology: 143," }, // Synonym + /*116*/ { "ultra", "1", NULL, 0, "symbology: 144," }, + /*117*/ { "ultracode", "1", NULL, 0, "symbology: 144," }, // Synonym + /*118*/ { "rMQR", "1", NULL, 0, "symbology: 145," }, + /*119*/ { "x", "1", NULL, 1, "Error 119: Invalid barcode type 'x'" }, + /*120*/ { "\177", "1", NULL, 1, "Error 119: Invalid barcode type '\177'" }, }; int data_size = ARRAY_SIZE(data); char cmd[4096]; char buf[8192]; - char *outfilename = "out.png"; + char *outfilename = "out.gif"; for (int i = 0; i < data_size; i++) { if (index != -1 && i != index) continue; - strcpy(cmd, "zint "); + strcpy(cmd, "zint --filetype=gif"); strcat(cmd, " --verbose"); arg_data(cmd, "-b ", data[i].bname); @@ -790,7 +864,7 @@ static void test_barcode_symbology(int index, int debug) { assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i), "i:%d exec(%s) NULL\n", i, cmd); assert_nonnull(strstr(buf, data[i].expected), "i:%d strstr(%s, %s) == NULL (%s)\n", i, buf, data[i].expected, cmd); if (!data[i].fail) { - assert_zero(remove(outfilename), "i:%d remove(%s) != 0 (%d) (%s)\n", i, outfilename, errno, cmd); + assert_zero(remove(outfilename), "i:%d remove(%s) != 0 (%d: %s) (%s)\n", i, outfilename, errno, strerror(errno), cmd); } } diff --git a/frontend_qt/grpMSICheck.ui b/frontend_qt/grpMSICheck.ui index 226338e8..0e9571ab 100644 --- a/frontend_qt/grpMSICheck.ui +++ b/frontend_qt/grpMSICheck.ui @@ -32,10 +32,20 @@ cmbMSICheck + + Mod-10 uses Luhn algorithm +Mod-11 (IBM) uses IBM weightings +Mod-11 (NCR) uses NCR weightings + + + Mod-10 uses Luhn algorithm +Mod-11 (IBM) uses IBM weightings +Mod-11 (NCR) uses NCR weightings + None @@ -53,18 +63,41 @@ - Mod-11 + Mod-11 (IBM) - Mod-11 & Mod-10 + Mod-11 (IBM) & Mod-10 + + + + + Mod-11 (NCR) + + + + + Mod-11 (NCR) & Mod-10 + + + + Do not show check digit(s) in &Text + + + Add check digit(s) but do not display in Human Readable Text + + + false + + + diff --git a/frontend_qt/mainWindow.ui b/frontend_qt/mainWindow.ui index e42a95cc..dfda32f2 100644 --- a/frontend_qt/mainWindow.ui +++ b/frontend_qt/mainWindow.ui @@ -594,8 +594,8 @@ p, li { white-space: pre-wrap; } - Use parentheses "()" instead of square brackets "[]" -to delimit GS1 application identifiers + Process parentheses "()" instead of square brackets "[]" +as GS1 application identifiers delimiters (ignored if disabled) diff --git a/frontend_qt/mainwindow.cpp b/frontend_qt/mainwindow.cpp index dc2a3cfd..033a6d21 100644 --- a/frontend_qt/mainwindow.cpp +++ b/frontend_qt/mainwindow.cpp @@ -62,11 +62,11 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags fl) "Codablock-F (and HIBC)", "Code 11", "Code 128 (ISO 15417) (and GS1-128 and HIBC)", - "Code 16k", + "Code 16k (ISO 12323)", "Code 2 of 5 Data Logic", "Code 2 of 5 IATA", "Code 2 of 5 Industrial", - "Code 2 of 5 Interleaved", + "Code 2 of 5 Interleaved (ISO 16390)", "Code 2 of 5 Standard (Matrix)", "Code 32 (Italian Pharmacode)", "Code 39 (ISO 16388) (and HIBC)", @@ -488,11 +488,11 @@ void MainWindow::on_encoded() void MainWindow::filter_symbologies() { QString filter = filter_bstyle->text().simplified(); /* `simplified()` trims and reduces inner whitespace to a single space - nice! */ - QListView *view = qobject_cast(bstyle->view()); + QListView *lview = qobject_cast(bstyle->view()); QStandardItemModel *model = qobject_cast(bstyle->model()); QStandardItem *item; - if (!view || !model) { + if (!lview || !model) { return; } @@ -510,7 +510,7 @@ void MainWindow::filter_symbologies() if (filter_cnt) { for (int i = 0; i < cnt; i++) { - bool hidden = view->isRowHidden(i); + bool hidden = lview->isRowHidden(i); bool hide = true; for (int j = 0; j < filter_cnt; j++) { if (bstyle->itemText(i).contains(filter_list[j], Qt::CaseInsensitive)) { @@ -522,15 +522,15 @@ void MainWindow::filter_symbologies() // https://stackoverflow.com/questions/25172220/how-to-hide-qcombobox-items-instead-of-clearing-them-out item = model->item(i); item->setFlags(hide ? item->flags() & ~Qt::ItemIsEnabled : item->flags() | Qt::ItemIsEnabled); - view->setRowHidden(i, hide); + lview->setRowHidden(i, hide); } } } else { for (int i = 0; i < cnt; i++) { - if (view->isRowHidden(i)) { + if (lview->isRowHidden(i)) { item = model->item(i); item->setFlags(item->flags() | Qt::ItemIsEnabled); - view->setRowHidden(i, false); + lview->setRowHidden(i, false); } } } @@ -566,9 +566,9 @@ void MainWindow::copy_to_clipboard_svg() return; } - QMimeData *data = new QMimeData; - data->setImageData(QImage(filename)); - clipboard->setMimeData(data, QClipboard::Clipboard); + QMimeData *mdata = new QMimeData; + mdata->setImageData(QImage(filename)); + clipboard->setMimeData(mdata, QClipboard::Clipboard); QFile::remove(filename); @@ -584,9 +584,9 @@ void MainWindow::copy_to_clipboard_bmp() return; } - QMimeData *data = new QMimeData; - data->setImageData(QImage(filename)); - clipboard->setMimeData(data, QClipboard::Clipboard); + QMimeData *mdata = new QMimeData; + mdata->setImageData(QImage(filename)); + clipboard->setMimeData(mdata, QClipboard::Clipboard); QFile::remove(filename); } @@ -689,6 +689,8 @@ void MainWindow::change_options() file.close(); tabMain->insertTab(1, m_optionWidget, tr("MSI Pless&ey")); connect(m_optionWidget->findChild("cmbMSICheck"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("cmbMSICheck"), SIGNAL(currentIndexChanged( int )), SLOT(msi_plessey_ui_set())); + connect(m_optionWidget->findChild("chkMSICheckText"), SIGNAL(clicked( bool )), SLOT(update_preview())); } else if (symbology == BARCODE_CODE11) { QFile file(":/grpC11.ui"); @@ -1064,6 +1066,16 @@ void MainWindow::maxi_primary() } } +void MainWindow::msi_plessey_ui_set() +{ + if (metaObject()->enumerator(0).value(bstyle->currentIndex()) != BARCODE_MSI_PLESSEY) + return; + QCheckBox *checkBox = m_optionWidget ? m_optionWidget->findChild("chkMSICheckText") : nullptr; + if (checkBox) { + checkBox->setEnabled(get_combobox_index("cmbMSICheck") > 0); + } +} + // Taken from https://stackoverflow.com/questions/38915001/disable-specific-items-in-qcombobox void MainWindow::combobox_item_enabled(QComboBox *comboBox, int index, bool enabled) { @@ -1280,7 +1292,11 @@ void MainWindow::update_preview() case BARCODE_MSI_PLESSEY: m_bc.bc.setSymbol(BARCODE_MSI_PLESSEY); - m_bc.bc.setOption2(m_optionWidget->findChild("cmbMSICheck")->currentIndex()); + item_val = get_combobox_index("cmbMSICheck"); + if (item_val && m_optionWidget->findChild("chkMSICheckText")->isChecked()) { + item_val += 10; + } + m_bc.bc.setOption2(item_val); break; case BARCODE_CODE11: @@ -1614,7 +1630,7 @@ const char *MainWindow::get_setting_name(int symbology) { int define; int val; }; - static const struct item data[] = { + static const struct item ndata[] = { { "", -1, 0 }, { "code11", BARCODE_CODE11, 1 }, { "c25standard", BARCODE_C25STANDARD, 2 }, @@ -1762,16 +1778,16 @@ const char *MainWindow::get_setting_name(int symbology) { { "ultra", BARCODE_ULTRA, 144 }, { "rmqr", BARCODE_RMQR, 145 }, }; - static const int data_size = sizeof(data) / sizeof(struct item); + static const int data_size = sizeof(ndata) / sizeof(struct item); if (symbology < 0 || symbology >= data_size) { return ""; } - if (data[symbology].val != symbology || (data[symbology].define != -1 && data[symbology].define != symbology)) { // Self-check - fprintf(stderr, "MainWindow::get_setting_name: data table out of sync (%d)\n", symbology); + if (ndata[symbology].val != symbology || (ndata[symbology].define != -1 && ndata[symbology].define != symbology)) { // Self-check + fprintf(stderr, "MainWindow::get_setting_name: ndata table out of sync (%d)\n", symbology); return ""; } - return data[symbology].name; + return ndata[symbology].name; } /* Helper to return index of selected radio button in group, checking for NULL */ @@ -1948,6 +1964,7 @@ void MainWindow::save_sub_settings(QSettings &settings, int symbology) { case BARCODE_MSI_PLESSEY: settings.setValue("studio/bc/msi_plessey/check_digit", get_combobox_index("cmbMSICheck")); + settings.setValue("studio/bc/msi_plessey/check_text", get_checkbox_val("chkMSICheckText")); break; case BARCODE_CODE11: @@ -2106,9 +2123,9 @@ void MainWindow::load_sub_settings(QSettings &settings, int symbology) { const char *name = get_setting_name(symbology); if (*name) { - const QString &data = settings.value(QString("studio/bc/%1/data").arg(name), "").toString(); - if (!data.isEmpty()) { - txtData->setText(data); + const QString &tdata = settings.value(QString("studio/bc/%1/data").arg(name), "").toString(); + if (!tdata.isEmpty()) { + txtData->setText(tdata); } if (!grpComposite->isHidden()) { const QString &composite_text = settings.value(QString("studio/bc/%1/composite_text").arg(name), "").toString(); @@ -2195,6 +2212,8 @@ void MainWindow::load_sub_settings(QSettings &settings, int symbology) { case BARCODE_MSI_PLESSEY: set_combobox_from_setting(settings, "studio/bc/msi_plessey/check_digit", "cmbMSICheck"); + set_checkbox_from_setting(settings, "studio/bc/msi_plessey/check_text", "chkMSICheckText"); + msi_plessey_ui_set(); break; case BARCODE_CODE11: diff --git a/frontend_qt/mainwindow.h b/frontend_qt/mainwindow.h index 92e880d2..02fbd0b5 100644 --- a/frontend_qt/mainwindow.h +++ b/frontend_qt/mainwindow.h @@ -122,6 +122,7 @@ public slots: void composite_ui_set(); void composite_ean_check(); void maxi_primary(); + void msi_plessey_ui_set(); void change_print_scale(); void change_cmyk(); void autoheight_ui_set(); diff --git a/frontend_qt/qzint.cpp b/frontend_qt/qzint.cpp index 31eaf4da..23cadfa7 100644 --- a/frontend_qt/qzint.cpp +++ b/frontend_qt/qzint.cpp @@ -16,6 +16,12 @@ ***************************************************************************/ /* vim: set ts=4 sw=4 et : */ +#ifdef _MSC_VER +#if _MSC_VER >= 1900 /* MSVC 2015 */ +#pragma warning(disable: 4996) /* function or variable may be unsafe */ +#endif +#endif + //#include #include "qzint.h" #include diff --git a/win32/README b/win32/README index c8617b11..96ea034f 100644 --- a/win32/README +++ b/win32/README @@ -31,6 +31,7 @@ First build zlib: cd zlib + nmake -f win32\Makefile.msc clean nmake -f win32\Makefile.msc LOC="-DASMV -DASMINF=" OBJA="inffas32.obj match686.obj" cd .. @@ -39,14 +40,9 @@ and then lpng: cd lpng - cmake -G"Visual Studio 15 2017"^ - -DCMAKE_BUILD_TYPE=Release^ - -DPNG_BUILD_ZLIB=ON^ - -DZLIB_INCLUDE_DIRS=..\zlib^ - -DPNG_STATIC=ON^ - -DPNG_SHARED=OFF^ - -H.^ - -Bbuild + cmake -G "Visual Studio 15 2017" -DCMAKE_BUILD_TYPE=Release^ + -DPNG_BUILD_ZLIB=ON -DZLIB_INCLUDE_DIRS=..\zlib^ + -DPNG_STATIC=ON -DPNG_SHARED=OFF -B build cmake --build build --config Release @@ -91,21 +87,104 @@ You should now be able to run Zint Studio: zint\frontend_qt\release\qtZint +Visual Studio 2019 +------------------ + +A solution for Visual Studio 2019 is in sub-directory vs2019. The steps are the +same as for Visual Studio 2017. To build lpng use + + cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_BUILD_TYPE=Release^ + -DPNG_BUILD_ZLIB=ON -DZLIB_INCLUDE_DIRS=..\zlib^ + -DPNG_STATIC=ON -DPNG_SHARED=OFF -B build + +(note the extra argument "-A Win32"). For Qt, the latest Qt5 version as of +writing to support Visual Studio 2019 is 15.5.2. Install this and the +"MSVC 2019 32-bit" component. Zint Studio can also be built using Qt6. + + Visual Studio 2015 ------------------ The solution and project files for Visual Studio 2015 have been moved to the -sub-directory vs2015 and are no longer maintained. However by copying the steps -above and adapting the settings from the Visual Studio 2017 project files (and -adding any sources missing), they should be pretty serviceable. +sub-directory vs2015. The steps are almost the same as for Visual Studio 2017, +except that "rc.exe" may not be available. If so, you need to install a Windows +Kit and then update your PATH, e.g. (adjust for version): + + set "PATH=C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86;%PATH%" + +To build lpng use + + cmake -G "Visual Studio 14 2015" -DCMAKE_BUILD_TYPE=Release^ + -DPNG_BUILD_ZLIB=ON -DZLIB_INCLUDE_DIRS=..\zlib^ + -DPNG_STATIC=ON -DPNG_SHARED=OFF -B build + +Recent versions of Qt no longer supply a specific component for Visual Studio +2015, but you can use "MSVC 2017 32-bit" instead as it's compatible. For information on building a standalone version of Zint Studio using Visual Studio 2015, see "frontend_qt/howto_build_qzint_using_msvs2015.txt" +CMake and Visual Studio +----------------------- + +Zint can also be built using CMake with Visual Studio 2019, 2017 or 2015. The +following example uses Visual Studio 2019 to build for x86/Win32: + +As above, set %PROJECT_DIR% and clone lpng, zlib and zint into it. Then + + cd zlib + ml /safeseh /coff /c contrib/masmx86/match686.asm + ml /safeseh /coff /c contrib/masmx86/inffas32.asm + nmake -f win32\Makefile.msc LOC="-DASMV -DASMINF=" OBJA="inffas32.obj match686.obj" + cd .. + +(compiling the zlib assembler with "SAFESEH" seems to be required when building +zint using CMake) + + cd lpng + cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_BUILD_TYPE=Release^ + -DPNG_BUILD_ZLIB=ON -DZLIB_INCLUDE_DIRS=..\zlib^ + -DPNG_STATIC=ON -DPNG_SHARED=OFF -B build + cmake --build build --config Release + cd .. + +CMake needs to be able to find zlib and lpng. One way to do this (requires +Administration privileges) is to create two sub-directories in +"C:\Program Files (x86)" called "include" and "lib", and then copy + + "zlib\zlib.h", "zlib\zconf.h", "lpng\png.h", "lpng\pngconf.h" and + "lpng\pnglibconf.h" into "include", and + + "zlib\zlib.lib" and "lpng\build\Release\libpng16_static.lib" into "lib". + +This example uses Qt 5.15.2 and component "MSVC 2017 32-bit" so install them and +add to path (your path may differ): + + set "PATH=C:\Qt\5.15.2\msvc2019\bin;%PATH%" + +Now build zint: + + cd zint + cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_BUILD_TYPE=Release -B build + cmake --build build --config Release + cd .. + +You should be able to run zint CLI and Zint Studio: + + set "PATH=%PROJECT_DIR%\zint\build\backend\Release;%PATH%" + zint\build\frontend\Release\zint.exe + zint\build\frontend_qt\Release\zint-qt.exe + +Note that the program name for Zint Studio when built using CMake is not +"qtZint.exe" but "zint-qt.exe". + + Visual C++ 6 ------------ +The zint library and command line tool can be built using VC6. + See "win32\zint_cmdline_vc6\readme.txt" @@ -127,8 +206,8 @@ Any reasonably modern version of Qt can be used. The following uses Qt 5.14.2. Using the Qt Maintenance Tool (see the Visual Studio 2017 instructions above) install the "MinGW 7.3.0 32-bit" component. -(Note the Qt MinGW version does not necessarily have to match the version of -MinGW installed, but the closer the better). +(Note the Qt MinGW versions actually refer to Mingw-w64, the 64-bit fork of +MinGW, but versions up to 8.1 seem to be compatible.) Open a MinGW/MSYS shell by clicking/running e.g. (your path may differ) @@ -143,8 +222,8 @@ differ): Go into the directory you want to use and clone zint and libpng: - PROJECT_DIR="" - cd ${PROJECT_DIR} + cd + PROJECT_DIR="$(pwd)" git clone https://git.code.sf.net/p/zint/code zint git clone https://git.code.sf.net/p/libpng/code lpng @@ -166,6 +245,8 @@ This will fail with a syntax error. To fix: sed -i 's/\r//' pnglibconf.h +(ignore "preserving permissions" warning if any) + And then do the make again: make diff --git a/win32/vs2008/zint.vcproj b/win32/vs2008/zint.vcproj index 48da4fdb..f971363b 100644 --- a/win32/vs2008/zint.vcproj +++ b/win32/vs2008/zint.vcproj @@ -243,11 +243,11 @@ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > $(SolutionDir)$(Configuration)\ $(Configuration)\ true + zintd true @@ -103,6 +104,7 @@ $(SolutionDir)$(Configuration)\ $(Configuration)\ false + zint false diff --git a/win32/vs2015/zint.vcxproj b/win32/vs2015/zint.vcxproj index c423272f..906fe277 100644 --- a/win32/vs2015/zint.vcxproj +++ b/win32/vs2015/zint.vcxproj @@ -224,13 +224,13 @@ - - + + - + diff --git a/win32/vs2019/zint.vcxproj b/win32/vs2019/zint.vcxproj index c4c5448f..61fe62cd 100644 --- a/win32/vs2019/zint.vcxproj +++ b/win32/vs2019/zint.vcxproj @@ -84,13 +84,13 @@ - - + + - + @@ -104,4 +104,4 @@ - \ No newline at end of file + diff --git a/win32/zint.vcxproj b/win32/zint.vcxproj index 2b6aae9e..8dfb68ed 100644 --- a/win32/zint.vcxproj +++ b/win32/zint.vcxproj @@ -84,13 +84,13 @@ - - + + - + diff --git a/win32/zint_cmdline_vc6/readme.txt b/win32/zint_cmdline_vc6/readme.txt index d9328f7b..760bf52c 100644 --- a/win32/zint_cmdline_vc6/readme.txt +++ b/win32/zint_cmdline_vc6/readme.txt @@ -1,5 +1,5 @@ Harald Oehlmann -2016-01-12 +2021-06-10 Why to use VC6 ? It avoids DLL Hell as the runtime is present on all Windows Versions since XP. @@ -7,18 +7,22 @@ I compile on Windows 10 64 bit. How to compile: -$ZR is the zint root folder (this file is in $ZR/win32/zint_cmdline_vc6) +$ZR is the zint root folder (this file is in $ZR\win32\zint_cmdline_vc6) -a) zlib (current version: 1.2.8) -* put zlib to $ZR\..\zlib * get vc6 shell +(if not available in the Start Menu, open a Command Prompt and run +"C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT") + +a) zlib (current version: 1.2.11) +* put zlib to $ZR\..\zlib cd $ZR\..\zlib nmake -f win32\Makefile.msc -> generates zlib.lib, zlib1.dll --> generates $ZR\..\lpng\libpng.lib -b) lpng (current version: 1.6.20) -* put libpng to $ZR/../lpng + +b) lpng (current version: 1.6.37) +* put libpng to $ZR\..\lpng cd $ZR\..\lpng nmake -f scripts\makefile.vcwin32 -> generates $ZR\..\lpng\libpng.lib -c) open the files in this folder with the msvc6 gui and compile \ No newline at end of file + +c) open zint_cmdline_vc6.dsp in this folder with the msvc6 gui and compile diff --git a/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp b/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp index e71b8f54..f8b37631 100644 --- a/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp +++ b/win32/zint_cmdline_vc6/zint_cmdline_vc6.dsp @@ -164,11 +164,11 @@ SOURCE=..\..\backend\general_field.c # End Source File # Begin Source File -SOURCE=..\..\frontend\getopt.c +SOURCE=..\..\getopt\getopt.c # End Source File # Begin Source File -SOURCE=..\..\frontend\getopt1.c +SOURCE=..\..\getopt\getopt1.c # End Source File # Begin Source File