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
This commit is contained in:
gitlost 2021-06-10 11:15:39 +01:00
parent f471bb6e50
commit 4a8cac2a5a
63 changed files with 1189 additions and 983 deletions

View File

@ -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 <rstuart114@gmail.com>
# vim: set ts=4 sw=4 et : # vim: set ts=4 sw=4 et :
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
@ -31,6 +32,7 @@ include(SetPaths.cmake)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(CheckFunctionExists) include(CheckFunctionExists)
if(NOT MSVC) # Use default warnings if MSVC otherwise inundated
check_cxx_compiler_flag("-Wall" CXX_COMPILER_FLAG_WALL) check_cxx_compiler_flag("-Wall" CXX_COMPILER_FLAG_WALL)
if(CXX_COMPILER_FLAG_WALL) if(CXX_COMPILER_FLAG_WALL)
add_compile_options("-Wall") add_compile_options("-Wall")
@ -45,6 +47,7 @@ check_cxx_compiler_flag("-Wpedantic" CXX_COMPILER_FLAG_WPEDANTIC)
if(CXX_COMPILER_FLAG_WPEDANTIC) if(CXX_COMPILER_FLAG_WPEDANTIC)
add_compile_options("-Wpedantic") add_compile_options("-Wpedantic")
endif() endif()
endif()
if(ZINT_DEBUG) if(ZINT_DEBUG)
check_cxx_compiler_flag("-g" CXX_COMPILER_FLAG_G) check_cxx_compiler_flag("-g" CXX_COMPILER_FLAG_G)
@ -61,39 +64,40 @@ if(ZINT_TEST)
enable_testing() enable_testing()
endif() 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) if(ZINT_SANITIZE)
add_compile_options(-fsanitize=undefined -fsanitize=address) add_compile_options(-fsanitize=undefined -fsanitize=address)
link_libraries(-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 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) add_compile_options(-fno-var-tracking-assignments)
endif() endif()
endif() endif()
endif()
IF(APPLE) if(APPLE)
IF (UNIVERSAL) # TODO: make universal binary if(UNIVERSAL) # TODO: make universal binary
IF(NOT ZINT_HAS_BEEN_RUN_BEFORE) if(NOT ZINT_HAS_BEEN_RUN_BEFORE)
IF(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) 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_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) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING
ELSE(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) "Flags used by the compiler during all build types." FORCE)
IF(EXISTS /Developer/SDKs/MacOSX10.4u.sdk OR EXISTS /SDKs/MacOSX10.4u.sdk) 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_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) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING
ENDIF(EXISTS /Developer/SDKs/MacOSX10.4u.sdk OR EXISTS /SDKs/MacOSX10.4u.sdk) "Flags used by the compiler during all build types." FORCE)
ENDIF(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) endif()
message("Build architectures for OSX:${CMAKE_OSX_ARCHITECTURES}") message("Build architectures for OSX:${CMAKE_OSX_ARCHITECTURES}")
ENDIF(NOT ZINT_HAS_BEEN_RUN_BEFORE) endif()
else()
ELSE (UNIVERSAL) set(CMAKE_OSX_SYSROOT "/")
SET(CMAKE_OSX_SYSROOT "/") endif()
ENDIF (UNIVERSAL) endif()
ENDIF(APPLE)
check_function_exists(getopt HAVE_GETOPT) check_function_exists(getopt HAVE_GETOPT)
if(NOT HAVE_GETOPT) if(NOT HAVE_GETOPT)
add_subdirectory(getopt) add_subdirectory(getopt)
endif(NOT HAVE_GETOPT) endif()
add_subdirectory(backend) add_subdirectory(backend)
add_subdirectory(frontend) add_subdirectory(frontend)

View File

@ -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 <rstuart114@gmail.com>
# vim: set ts=4 sw=4 et : # vim: set ts=4 sw=4 et :
project(zint) project(zint)
@ -63,4 +64,4 @@ install(FILES zint.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel)
if(ZINT_TEST) if(ZINT_TEST)
add_subdirectory(tests) add_subdirectory(tests)
endif(ZINT_TEST) endif()

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -31,6 +31,7 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include "common.h" #include "common.h"
#include "bmp.h" /* Bitmap header structure */ #include "bmp.h" /* Bitmap header structure */
@ -64,7 +65,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
row_size = 4 * ((bits_per_pixel * symbol->bitmap_width + 31) / 32); row_size = 4 * ((bits_per_pixel * symbol->bitmap_width + 31) / 32);
data_size = symbol->bitmap_height * row_size; data_size = symbol->bitmap_height * row_size;
data_offset = sizeof(bitmap_file_header_t) + sizeof(bitmap_info_header_t); data_offset = sizeof(bitmap_file_header_t) + sizeof(bitmap_info_header_t);
data_offset += (colour_count * (sizeof(color_ref_t))); data_offset += colour_count * sizeof(color_ref_t);
file_size = data_offset + data_size; file_size = data_offset + data_size;
bitmap_file_start = (unsigned char *) malloc(file_size); bitmap_file_start = (unsigned char *) malloc(file_size);
@ -176,7 +177,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
if ((symbol->output_options & BARCODE_STDOUT) != 0) { if ((symbol->output_options & BARCODE_STDOUT) != 0) {
#ifdef _MSC_VER #ifdef _MSC_VER
if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { 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); free(bitmap_file_start);
return ZINT_ERROR_FILE_ACCESS; return ZINT_ERROR_FILE_ACCESS;
} }
@ -185,7 +186,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
} else { } else {
if (!(bmp_file = fopen(symbol->outfile, "wb"))) { if (!(bmp_file = fopen(symbol->outfile, "wb"))) {
free(bitmap_file_start); 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; return ZINT_ERROR_FILE_ACCESS;
} }
} }

View File

@ -39,10 +39,6 @@
#include <math.h> #include <math.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#include <malloc.h> #include <malloc.h>
/* ceilf (C99) not before MSVC++2013 (C++ 12.0) */
#if _MSC_VER < 1800
#define ceilf (float) ceil
#endif
#endif #endif
/* Add solid bar */ /* Add solid bar */
@ -237,11 +233,11 @@ static int c1_look_ahead_test(const unsigned char source[], const int sourcelen,
if (sp >= position + 3) { if (sp >= position + 3) {
/* Step Q */ /* Step Q */
float cnt; float cnt;
ascii_rnded = (int) ceilf(ascii_count); ascii_rnded = (int) ceilf(stripf(ascii_count));
c40_rnded = (int) ceilf(c40_count); c40_rnded = (int) ceilf(stripf(c40_count));
text_rnded = (int) ceilf(text_count); text_rnded = (int) ceilf(stripf(text_count));
edi_rnded = (int) ceilf(edi_count); edi_rnded = (int) ceilf(stripf(edi_count));
byte_rnded = (int) ceilf(byte_count); byte_rnded = (int) ceilf(stripf(byte_count));
cnt = byte_count + 1.0f; cnt = byte_count + 1.0f;
if (cnt <= ascii_rnded && cnt <= c40_rnded && cnt <= text_rnded && cnt <= edi_rnded) { 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 */ /* Step K */
ascii_rnded = (int) ceilf(ascii_count); ascii_rnded = (int) ceilf(stripf(ascii_count));
c40_rnded = (int) ceilf(c40_count); c40_rnded = (int) ceilf(stripf(c40_count));
text_rnded = (int) ceilf(text_count); text_rnded = (int) ceilf(stripf(text_count));
edi_rnded = (int) ceilf(edi_count); edi_rnded = (int) ceilf(stripf(edi_count));
byte_rnded = (int) ceilf(byte_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) { if (byte_count <= ascii_rnded && byte_count <= c40_rnded && byte_count <= text_rnded && byte_count <= edi_rnded) {
return C1_BYTE; /* Step K1 */ return C1_BYTE; /* Step K1 */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions 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; codeword_count = 0;
i = 0; i = 0;
h = strlen(intermediate); h = (int) strlen(intermediate);
do { do {
if ((intermediate[i] >= '0') && (intermediate[i] <= '9')) { if ((intermediate[i] >= '0') && (intermediate[i] <= '9')) {
/* Numeric data */ /* Numeric data */
@ -340,7 +340,7 @@ INTERNAL int code_49(struct zint_symbol *symbol, unsigned char source[], int len
/* Expand into symbol */ /* Expand into symbol */
symbol->row_height[i] = 10; 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') { if (pattern[j] == '1') {
set_module(symbol, i, j); 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->rows = rows;
symbol->width = strlen(pattern); symbol->width = (int) strlen(pattern);
symbol->output_options |= BARCODE_BIND; symbol->output_options |= BARCODE_BIND;

View File

@ -462,7 +462,7 @@ void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *c
int i, max = length, cnt_len = 0; int i, max = length, cnt_len = 0;
if (length > 30) { /* 30*3 < errtxt 92 (100 - "Warning ") chars */ if (length > 30) { /* 30*3 < errtxt 92 (100 - "Warning ") chars */
sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */ 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; max = 30 - (cnt_len + 2) / 3;
} }
for (i = 0; i < max; i++) { for (i = 0; i < max; i++) {

View File

@ -31,7 +31,6 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
/* Used in some logic */
#ifndef __COMMON_H #ifndef __COMMON_H
#define __COMMON_H #define __COMMON_H
@ -57,23 +56,31 @@
#define ustrcat(target, source) strcat((char *) (target), (const char *) (source)) #define ustrcat(target, source) strcat((char *) (target), (const char *) (source))
#define ustrncat(target, source, count) strncat((char *) (target), (const char *) (source), (count)) #define ustrncat(target, source, count) strncat((char *) (target), (const char *) (source), (count))
#if defined(__GNUC__) && !defined(_WIN32) && !defined(ZINT_TEST) /* Removes excess precision from floats - see https://stackoverflow.com/q/503436/664741 */
# define INTERNAL __attribute__ ((visibility ("hidden"))) #define stripf(arg) (*((volatile float *) &(arg)))
#else /* despite the name, the test cases are referencing the INTERNAL functions, so they need to be exported */
# if defined(ZINT_TEST) #ifdef _MSC_VER
# if defined(DLL_EXPORT) || defined(PIC) || defined(_USRDLL) # if _MSC_VER < 1800 /* ceilf, floorf, roundf (C99) not before MSVC 2013 (C++ 12.0) */
# define INTERNAL __declspec(dllexport) # define ceilf (float) ceil
# elif defined(ZINT_DLL) # define floorf (float) floor
# define INTERNAL __declspec(dllimport) # define roundf(arg) ((float) floor((arg) + 0.5f))
# endif # endif
# endif # pragma warning(disable: 4244) /* conversion from int to float */
# if !defined(INTERNAL) # if _MSC_VER >= 1900 /* MSVC 2015 */
# define INTERNAL # pragma warning(disable: 4996) /* function or variable may be unsafe */
# endif # endif
#endif #endif
#if defined(ZINT_TEST) #if (defined(__GNUC__) || defined(__clang__)) && !defined(ZINT_TEST) && !defined(__MINGW32__)
#define STATIC_UNLESS_ZINT_TEST # 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 #else
#define STATIC_UNLESS_ZINT_TEST static #define STATIC_UNLESS_ZINT_TEST static
#endif #endif
@ -131,8 +138,8 @@ extern "C" {
INTERNAL int colour_to_blue(const int colour); INTERNAL int colour_to_blue(const int colour);
#ifdef ZINT_TEST #ifdef ZINT_TEST
void debug_test_codeword_dump(struct zint_symbol *symbol, const unsigned char *codewords, const int length); INTERNAL 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_int(struct zint_symbol *symbol, const int *codewords, const int length);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -44,10 +44,6 @@
#include <math.h> #include <math.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#include <malloc.h> #include <malloc.h>
/* ceilf (C99) not before MSVC++2013 (C++ 12.0) */
#if _MSC_VER < 1800
#define ceilf (float) ceil
#endif
#endif #endif
#include "common.h" #include "common.h"
#include "reedsol.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) */ /* At the end of data ... step (k) */
/* step (k)(1) */ /* step (k)(1) */
ascii_rnded = (int) ceilf(ascii_count); ascii_rnded = (int) ceilf(stripf(ascii_count));
b256_rnded = (int) ceilf(b256_count); b256_rnded = (int) ceilf(stripf(b256_count));
edf_rnded = (int) ceilf(edf_count); edf_rnded = (int) ceilf(stripf(edf_count));
text_rnded = (int) ceilf(text_count); text_rnded = (int) ceilf(stripf(text_count));
x12_rnded = (int) ceilf(x12_count); x12_rnded = (int) ceilf(stripf(x12_count));
c40_rnded = (int) ceilf(c40_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 if (ascii_rnded <= b256_rnded && ascii_rnded <= edf_rnded && ascii_rnded <= text_rnded && ascii_rnded <= x12_rnded
&& ascii_rnded <= c40_rnded) { && ascii_rnded <= c40_rnded) {

View File

@ -1,7 +1,7 @@
/* emf.c - Support for Microsoft Enhanced Metafile Format /* emf.c - Support for Microsoft Enhanced Metafile Format
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2016 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2016 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -33,6 +33,7 @@
/* Developed according to [MS-EMF] - v20160714, Released July 14, 2016 /* Developed according to [MS-EMF] - v20160714, Released July 14, 2016
* and [MS-WMF] - v20160714, Released July 14, 2016 */ * and [MS-WMF] - v20160714, Released July 14, 2016 */
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
@ -677,7 +678,7 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) {
emf_file = fopen(symbol->outfile, "wb"); emf_file = fopen(symbol->outfile, "wb");
} }
if (emf_file == NULL) { 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; return ZINT_ERROR_FILE_ACCESS;
} }

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -31,8 +31,8 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "common.h" #include "common.h"
#include <math.h> #include <math.h>
#ifdef _MSC_VER #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; RGBCur[0] = 0; RGBCur[1] = 0; RGBCur[2] = 0;
break; break;
default: /* error case - return */ default: /* error case - return */
strcpy(symbol->errtxt, "611: unknown pixel colour"); strcpy(symbol->errtxt, "612: unknown pixel colour");
return ZINT_ERROR_INVALID_DATA; return ZINT_ERROR_INVALID_DATA;
} }
/* Search, if RGB value is already present */ /* 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) { if ((symbol->output_options & BARCODE_STDOUT) != 0) {
#ifdef _MSC_VER #ifdef _MSC_VER
if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
#endif #endif
gif_file = stdout; gif_file = stdout;
} else { } else {
if (!(gif_file = fopen(symbol->outfile, "wb"))) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
} }

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions 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; 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) { if (zip_len != 0 && zip_len != 5 && zip_len != 9 && zip_len != 11) {
strcpy(symbol->errtxt, "453: Invalid ZIP code"); strcpy(symbol->errtxt, "453: Invalid ZIP code");
return ZINT_ERROR_INVALID_DATA; 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 */ /* 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_mul_u64(&accum, 10);
large_add_u64(&accum, ctoi(tracker[read])); 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 */ /* Translate 4-state data pattern to symbol */
read = 0; 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')) { if ((data_pattern[i] == '1') || (data_pattern[i] == '0')) {
set_module(symbol, 0, read); set_module(symbol, 0, read);
} }

View File

@ -1539,7 +1539,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) {
unsigned char *buffer; unsigned char *buffer;
long fileLen; long fileLen;
size_t n; size_t n;
int nRead = 0; size_t nRead = 0;
int ret; int ret;
if (!symbol) return ZINT_ERROR_INVALID_DATA; if (!symbol) return ZINT_ERROR_INVALID_DATA;
@ -1555,7 +1555,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) {
} else { } else {
file = fopen(filename, "rb"); file = fopen(filename, "rb");
if (!file) { 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); return error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
} }
file_opened = 1; file_opened = 1;
@ -1593,7 +1593,7 @@ int ZBarcode_Encode_File(struct zint_symbol *symbol, char *filename) {
do { do {
n = fread(buffer + nRead, 1, fileLen - nRead, file); n = fread(buffer + nRead, 1, fileLen - nRead, file);
if (ferror(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) { if (file_opened) {
fclose(file); 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); return error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
} }
nRead += n; nRead += n;
} while (!feof(file) && (0 < n) && (nRead < fileLen)); } while (!feof(file) && (0 < n) && ((long) nRead < fileLen));
if (file_opened) { if (file_opened) {
fclose(file); fclose(file);

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -128,7 +128,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le
int version_id; int version_id;
int mail_class; int mail_class;
int supply_chain_id; int supply_chain_id;
long item_id; unsigned int item_id;
char postcode[10]; char postcode[10];
int postcode_type; int postcode_type;
char pattern[10]; char pattern[10];
@ -138,7 +138,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le
unsigned char data[26]; unsigned char data[26];
int data_top, data_step; int data_top, data_step;
unsigned char check[7]; unsigned char check[7];
short int extender[27]; unsigned int extender[27];
char bar[80]; char bar[80];
int check_count; int check_count;
int i, j, len; int i, j, len;
@ -214,7 +214,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le
for (i = length - 17; i < (length - 9); i++) { for (i = length - 17; i < (length - 9); i++) {
if ((local_source[i] >= '0') && (local_source[i] <= '9')) { if ((local_source[i] >= '0') && (local_source[i] <= '9')) {
item_id *= 10; item_id *= 10;
item_id += (long) ctoi(local_source[i]); item_id += ctoi(local_source[i]);
} else { } else {
strcpy(symbol->errtxt, "586: Invalid Item ID"); strcpy(symbol->errtxt, "586: Invalid Item ID");
return ZINT_ERROR_INVALID_DATA; return ZINT_ERROR_INVALID_DATA;
@ -379,7 +379,6 @@ INTERNAL int mailmark(struct zint_symbol *symbol, unsigned char source[], int le
large_print(&cdv); large_print(&cdv);
} }
if (length == 22) { if (length == 22) {
data_top = 15; data_top = 15;
data_step = 8; data_step = 8;

View File

@ -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->fgcolour);
to_upper((unsigned char *) symbol->bgcolour); 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) { if (error_number == ZINT_ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "653: Malformed foreground colour target"); strcpy(symbol->errtxt, "653: Malformed foreground colour target");
return ZINT_ERROR_INVALID_OPTION; 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) { if (error_number == ZINT_ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "654: Malformed background colour target"); strcpy(symbol->errtxt, "654: Malformed background colour target");
return ZINT_ERROR_INVALID_OPTION; 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 comp_offset; /* Whitespace offset (if any) of main linear symbol due to having composite */
int upceanflag; /* UPC/EAN type flag */ int upceanflag; /* UPC/EAN type flag */
int i, j, latch; int i, j, latch;
int text_length = ustrlen(symbol->text); int text_length = (int) ustrlen(symbol->text);
latch = 0; latch = 0;
j = 0; j = 0;

View File

@ -3,7 +3,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -32,8 +32,8 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "common.h" #include "common.h"
#include "pcx.h" /* PCX header structure */ #include "pcx.h" /* PCX header structure */
#include <math.h> #include <math.h>
@ -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]); bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
header.manufacturer = 10; // ZSoft header.manufacturer = 10; // ZSoft
header.version = 5; // Version 3.0 header.version = 5; // Version 3.0
header.encoding = 1; // Run length encoding header.encoding = 1; // Run length encoding
@ -103,14 +102,14 @@ INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
if (symbol->output_options & BARCODE_STDOUT) { if (symbol->output_options & BARCODE_STDOUT) {
#ifdef _MSC_VER #ifdef _MSC_VER
if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
#endif #endif
pcx_file = stdout; pcx_file = stdout;
} else { } else {
if (!(pcx_file = fopen(symbol->outfile, "wb"))) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
} }

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -44,8 +44,8 @@ static const char *PlessTable[16] = {
}; };
static const char *MSITable[10] = { static const char *MSITable[10] = {
"12121212", "12121221", "12122112", "12122121", "12211212", "12211221", "12121212", "12121221", "12122112", "12122121", "12211212",
"12212112", "12212121", "21121212", "21121221" "12211221", "12212112", "12212121", "21121212", "21121221"
}; };
/* Not MSI/Plessey but the older Plessey standard */ /* 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; int i;
unsigned char *checkptr; unsigned char *checkptr;
static const char grid[9] = {1, 1, 1, 1, 0, 1, 0, 0, 1}; 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; int error_number;
if (length > 65) { if (length > 65) {
@ -105,56 +105,71 @@ INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], int len
strcat(dest, "331311313"); strcat(dest, "331311313");
expand(symbol, dest); expand(symbol, dest);
ustrcpy(symbol->text, source);
symbol->text[0] = '\0';
ustrncat(symbol->text, source, length);
free(checkptr); free(checkptr);
return error_number; 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 */ /* 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; 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++) { for (i = 0; i < length; i++) {
lookup(NEON, MSITable, source[i], dest); lookup(NEON, MSITable, source[i], dest);
} }
/* Stop character */ symbol->text[0] = '\0';
strcat(dest, "121"); ustrncat(symbol->text, source, length);
expand(symbol, dest);
ustrcpy(symbol->text, source);
return 0;
} }
/* MSI Plessey with Modulo 10 check digit - algorithm from Barcode Island /* MSI Plessey with Modulo 10 check digit */
* http://www.barcodeisland.com/ */ static void msi_plessey_mod10(struct zint_symbol *symbol, const unsigned char source[], const int length,
static int msi_plessey_mod10(struct zint_symbol *symbol, unsigned char source[], int length) { const int no_checktext, char dest[]) {
int i;
int i, wright, pump, n; char check_digit;
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");
/* draw data section */ /* draw data section */
for (i = 0; i < length; i++) { 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 */ /* calculate check digit */
wright = 0; check_digit = msi_check_digit_mod10(source, length);
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;
}
/* draw check digit */ /* draw check digit */
lookup(NEON, MSITable, itoc(pump), dest); lookup(NEON, MSITable, check_digit, dest);
/* Stop character */ symbol->text[0] = '\0';
strcat(dest, "121"); ustrncat(symbol->text, source, length);
expand(symbol, dest); if (!no_checktext) {
symbol->text[length] = check_digit;
ustrcpy(symbol->text, source);
symbol->text[length] = itoc(pump);
symbol->text[length + 1] = '\0'; symbol->text[length + 1] = '\0';
return error_number; }
} }
/* MSI Plessey with two Modulo 10 check digits - algorithm from /* MSI Plessey with two Modulo 10 check digits */
* Barcode Island http://www.barcodeisland.com/ */ static void msi_plessey_mod1010(struct zint_symbol *symbol, const unsigned char source[], const int length,
static int msi_plessey_mod1010(struct zint_symbol *symbol, unsigned char source[], const int src_len) { const int no_checktext, char dest[]) {
int i, n, wright, pump; int i;
unsigned long dau, pedwar, chwech; unsigned char temp[65 + 2 + 1];
char un[32], tri[32];
int error_number, h;
char dest[1000];
error_number = 0; /* Append check digits */
temp[0] = '\0';
if (src_len > 18) { ustrncat(temp, source, length);
/* No Entry Stack Smashers! limit because of str->number conversion*/ temp[length] = msi_check_digit_mod10(source, length);
strcpy(symbol->errtxt, "374: Input too long"); temp[length + 1] = msi_check_digit_mod10(temp, length + 1);
return ZINT_ERROR_TOO_LONG; temp[length + 2] = '\0';
}
/* start character */
strcpy(dest, "21");
/* draw data section */ /* draw data section */
for (i = 0; i < src_len; i++) { for (i = 0; i < length + 2; i++) {
lookup(NEON, MSITable, source[i], dest); lookup(NEON, MSITable, temp[i], dest);
} }
/* calculate first check digit */ if (no_checktext) {
wright = 0; symbol->text[0] = '\0';
ustrncat(symbol->text, source, length);
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) {
lookup(NEON, MSITable, '1', dest);
lookup(NEON, MSITable, '0', dest);
} else { } else {
lookup(NEON, MSITable, itoc(check), 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;
}
}
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;
} else {
lookup(NEON, MSITable, itoc(check), dest);
temp[temp_len++] = itoc(check);
temp[temp_len] = '\0';
}
/* 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';
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 = temp_len & 1;
for (; i < temp_len; i += 2) {
pedwar += ctoi(temp[i]);
}
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); ustrcpy(symbol->text, temp);
return error_number; }
}
/* 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);
}
/* 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, check_digit, dest);
}
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';
}
}
}
/* 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 {
temp[temp_len++] = check_digit;
}
/* Append second (mod 10) check digit */
temp[temp_len] = msi_check_digit_mod10(temp, temp_len);
temp[++temp_len] = '\0';
/* draw data section */
for (i = 0; i < temp_len; i++) {
lookup(NEON, MSITable, temp[i], dest);
}
if (no_checktext) {
symbol->text[0] = '\0';
ustrncat(symbol->text, source, length);
} else {
ustrcpy(symbol->text, temp);
}
} }
INTERNAL int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length) { INTERNAL int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length) {
int error_number; 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); error_number = is_sane(NEON, source, length);
if (error_number != 0) { 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; return ZINT_ERROR_INVALID_DATA;
} }
if (length > 65) {
if ((symbol->option_2 < 0) || (symbol->option_2 > 4)) { strcpy(symbol->errtxt, "372: Input too long");
symbol->option_2 = 0; return ZINT_ERROR_TOO_LONG;
} }
switch (symbol->option_2) { if (check_option >= 11 && check_option <= 16) { /* +10 means don't print check digits in HRT */
case 0: error_number = msi_plessey(symbol, source, length); 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; break;
case 1: error_number = msi_plessey_mod10(symbol, source, length); case 1: msi_plessey_mod10(symbol, source, length, no_checktext, dest);
break; break;
case 2: error_number = msi_plessey_mod1010(symbol, source, length); case 2: msi_plessey_mod1010(symbol, source, length, no_checktext, dest);
break; 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; 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; break;
} }
/* Stop character */
strcat(dest, "121");
expand(symbol, dest);
return error_number; return error_number;
} }

View File

@ -31,6 +31,9 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
#ifndef NO_PNG
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#include <fcntl.h> #include <fcntl.h>
@ -39,7 +42,6 @@
#endif #endif
#include "common.h" #include "common.h"
#ifndef NO_PNG
#include <png.h> #include <png.h>
#include <zlib.h> #include <zlib.h>
#include <setjmp.h> #include <setjmp.h>
@ -233,14 +235,14 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
if (symbol->output_options & BARCODE_STDOUT) { if (symbol->output_options & BARCODE_STDOUT) {
#ifdef _MSC_VER #ifdef _MSC_VER
if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
#endif #endif
graphic->outfile = stdout; graphic->outfile = stdout;
} else { } else {
if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
} }
@ -343,4 +345,7 @@ INTERNAL int png_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
return 0; 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 */ #endif /* NO_PNG */

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2008 - 2021 Robin Stuart <rstuart114@gmail.com>
Including bug fixes by Bryan Hatton Including bug fixes by Bryan Hatton
Redistribution and use in source and binary forms, with or without 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; writer = 0;
h = strlen(height_pattern); h = (int) strlen(height_pattern);
for (loopey = 0; loopey < h; loopey++) { for (loopey = 0; loopey < h; loopey++) {
if (height_pattern[loopey] == 'L') { if (height_pattern[loopey] == 'L') {
set_module(symbol, 0, writer); set_module(symbol, 0, writer);
@ -191,7 +191,7 @@ INTERNAL int planet_plot(struct zint_symbol *symbol, unsigned char source[], int
} }
writer = 0; writer = 0;
h = strlen(height_pattern); h = (int) strlen(height_pattern);
for (loopey = 0; loopey < h; loopey++) { for (loopey = 0; loopey < h; loopey++) {
if (height_pattern[loopey] == 'L') { if (height_pattern[loopey] == 'L') {
set_module(symbol, 0, writer); 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); /*check = */rm4scc(source, height_pattern, length);
writer = 0; writer = 0;
h = strlen(height_pattern); h = (int) strlen(height_pattern);
for (loopey = 0; loopey < h; loopey++) { for (loopey = 0; loopey < h; loopey++) {
if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {
set_module(symbol, 0, writer); set_module(symbol, 0, writer);
@ -392,7 +392,7 @@ INTERNAL int kix_code(struct zint_symbol *symbol, unsigned char source[], int le
} }
writer = 0; writer = 0;
h = strlen(height_pattern); h = (int) strlen(height_pattern);
for (loopey = 0; loopey < h; loopey++) { for (loopey = 0; loopey < h; loopey++) {
if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {
set_module(symbol, 0, writer); set_module(symbol, 0, writer);
@ -448,7 +448,7 @@ INTERNAL int daft_code(struct zint_symbol *symbol, unsigned char source[], int l
} }
writer = 0; writer = 0;
h = strlen(height_pattern); h = (int) strlen(height_pattern);
for (loopey = 0; loopey < h; loopey++) { for (loopey = 0; loopey < h; loopey++) {
if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) { if ((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0')) {
set_module(symbol, 0, writer); 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 */ /* Resolve pattern to 4-state symbols */
writer = 0; writer = 0;
h = strlen(pattern); h = (int) strlen(pattern);
for (loopey = 0; loopey < h; loopey++) { for (loopey = 0; loopey < h; loopey++) {
if ((pattern[loopey] == '2') || (pattern[loopey] == '1')) { if ((pattern[loopey] == '2') || (pattern[loopey] == '1')) {
set_module(symbol, 0, writer); set_module(symbol, 0, writer);

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009-2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -31,6 +31,7 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
#include <errno.h>
#include <locale.h> #include <locale.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
@ -169,7 +170,7 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
feps = fopen(symbol->outfile, "w"); feps = fopen(symbol->outfile, "w");
} }
if (feps == NULL) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
@ -260,13 +261,15 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
/* Start writing the header */ /* Start writing the header */
fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n"); fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n");
if (ZINT_VERSION_BUILD) { 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 { } else {
fprintf(feps, "%%%%Creator: Zint %d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE); 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, "%%%%Title: Zint Generated Symbol\n");
fprintf(feps, "%%%%Pages: 0\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"); fprintf(feps, "%%%%EndComments\n");
/* Definitions */ /* Definitions */
@ -314,7 +317,8 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
fprintf(feps, "%s\n", ps_color); fprintf(feps, "%s\n", ps_color);
} }
colour_rect_counter++; 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"); fprintf(feps, "TE\n");
} }
rect = rect->next; rect = rect->next;
@ -323,7 +327,8 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
} else { } else {
rect = symbol->vector->rectangles; rect = symbol->vector->rectangles;
while (rect) { 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"); fprintf(feps, "TE\n");
rect = rect->next; rect = rect->next;
} }
@ -366,7 +371,8 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
ex = hex->x + half_radius; ex = hex->x + half_radius;
fx = 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; hex = hex->next;
} }
@ -383,7 +389,8 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
if ((symbol->output_options & CMYK_COLOUR) == 0) { if ((symbol->output_options & CMYK_COLOUR) == 0) {
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper); fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper);
} else { } 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); fprintf(feps, "%.2f %.2f %.2f TD\n", circle->x, (symbol->vector->height - circle->y), radius);
if (circle->next) { if (circle->next) {
@ -405,12 +412,14 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
string = symbol->vector->strings; string = symbol->vector->strings;
if (string) { 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"; font = "Helvetica-Bold";
} else { } else {
font = "Helvetica"; 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, "/%s findfont\n", font);
fprintf(feps, "dup length dict begin\n"); fprintf(feps, "dup length dict begin\n");
fprintf(feps, "{1 index /FID ne {def} {pop pop} ifelse} forall\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, "matrix currentmatrix\n");
fprintf(feps, "/%s findfont\n", font); fprintf(feps, "/%s findfont\n", font);
fprintf(feps, "%.2f scalefont setfont\n", string->fsize); 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 */ if (string->halign == 0 || string->halign == 2) { /* Need width for middle or right align */
fprintf(feps, " (%s) stringwidth\n", ps_string); fprintf(feps, " (%s) stringwidth\n", ps_string);
} }

View File

@ -2175,7 +2175,7 @@ static void micro_populate_grid(unsigned char *grid, const int size, const char
int n, i; int n, i;
int y; int y;
n = strlen(full_stream); n = (int) strlen(full_stream);
y = size - 1; y = size - 1;
i = 0; i = 0;
do { do {

View File

@ -39,16 +39,6 @@
#include <malloc.h> #include <malloc.h>
#include <fcntl.h> #include <fcntl.h>
#include <io.h> #include <io.h>
/* 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 */ #endif /* _MSC_VER */
#include "common.h" #include "common.h"
@ -438,7 +428,7 @@ static void draw_string(unsigned char *pixbuf, const unsigned char input_string[
} }
letter_width += letter_gap; 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; string_left_hand = xposn - ((letter_width * string_length - letter_gap) * half_si) / 2;
if (odd_si) { 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[]) { static void to_iso8859_1(const unsigned char source[], unsigned char preprocessed[]) {
int j, i, input_length; int j, i, input_length;
input_length = ustrlen(source); input_length = (int) ustrlen(source);
j = 0; j = 0;
i = 0; i = 0;

View File

@ -2,7 +2,7 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2009 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -31,8 +31,8 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
#include <errno.h>
#include <locale.h> #include <locale.h>
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#ifdef _MSC_VER #ifdef _MSC_VER
@ -73,12 +73,13 @@ 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 */ /* Converts text to use HTML entity codes */
int i, html_pos; int i, len, html_pos;
html_pos = 0; html_pos = 0;
html_version[html_pos] = '\0'; html_version[html_pos] = '\0';
len = (int) ustrlen(string);
for (i = 0; i < (int) ustrlen(string); i++) { for (i = 0; i < len; i++) {
switch (string[i]) { switch (string[i]) {
case '>': case '>':
strcat(html_version, "&gt;"); strcat(html_version, "&gt;");
@ -136,7 +137,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
struct zint_vector_string *string; struct zint_vector_string *string;
char colour_code[7]; char colour_code[7];
int html_len; int len, html_len;
#ifdef _MSC_VER #ifdef _MSC_VER
char *html_string; char *html_string;
@ -162,9 +163,10 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
} }
} }
html_len = strlen((char *)symbol->text) + 1; len = (int) ustrlen(symbol->text);
html_len = len + 1;
for (i = 0; i < (int) strlen((char *)symbol->text); i++) { for (i = 0; i < len; i++) {
switch (symbol->text[i]) { switch (symbol->text[i]) {
case '>': case '>':
case '<': case '<':
@ -193,7 +195,7 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
fsvg = fopen(symbol->outfile, "w"); fsvg = fopen(symbol->outfile, "w");
} }
if (fsvg == NULL) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
@ -203,14 +205,16 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
fprintf(fsvg, "<?xml version=\"1.0\" standalone=\"no\"?>\n"); fprintf(fsvg, "<?xml version=\"1.0\" standalone=\"no\"?>\n");
fprintf(fsvg, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n"); fprintf(fsvg, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
fprintf(fsvg, " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); fprintf(fsvg, " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\"\n", (int) ceil(symbol->vector->width), (int) ceil(symbol->vector->height)); fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\"\n",
(int) ceil(symbol->vector->width), (int) ceil(symbol->vector->height));
fprintf(fsvg, " xmlns=\"http://www.w3.org/2000/svg\">\n"); fprintf(fsvg, " xmlns=\"http://www.w3.org/2000/svg\">\n");
fprintf(fsvg, " <desc>Zint Generated Symbol\n"); fprintf(fsvg, " <desc>Zint Generated Symbol\n");
fprintf(fsvg, " </desc>\n"); fprintf(fsvg, " </desc>\n");
fprintf(fsvg, "\n <g id=\"barcode\" fill=\"#%s\">\n", fgcolour_string); fprintf(fsvg, "\n <g id=\"barcode\" fill=\"#%s\">\n", fgcolour_string);
if (bg_alpha != 0) { if (bg_alpha != 0) {
fprintf(fsvg, " <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\"", (int) ceil(symbol->vector->width), (int) ceil(symbol->vector->height), bgcolour_string); fprintf(fsvg, " <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\"",
(int) ceil(symbol->vector->width), (int) ceil(symbol->vector->height), bgcolour_string);
if (bg_alpha != 0xff) { if (bg_alpha != 0xff) {
fprintf(fsvg, " opacity=\"%.3f\"", bg_alpha_opacity); fprintf(fsvg, " opacity=\"%.3f\"", bg_alpha_opacity);
} }
@ -219,7 +223,8 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
rect = symbol->vector->rectangles; rect = symbol->vector->rectangles;
while (rect) { while (rect) {
fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\"", rect->x, rect->y, rect->width, rect->height); fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\"",
rect->x, rect->y, rect->width, rect->height);
if (rect->colour != -1) { if (rect->colour != -1) {
pick_colour(rect->colour, colour_code); pick_colour(rect->colour, colour_code);
fprintf(fsvg, " fill=\"#%s\"", 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; ex = hex->x + half_radius;
fx = hex->x - half_radius; fx = hex->x - half_radius;
} }
fprintf(fsvg, " <path d=\"M %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f Z\"", ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy); fprintf(fsvg, " <path d=\"M %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f Z\"",
ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy);
if (fg_alpha != 0xff) { if (fg_alpha != 0xff) {
fprintf(fsvg, " opacity=\"%.3f\"", fg_alpha_opacity); fprintf(fsvg, " opacity=\"%.3f\"", fg_alpha_opacity);
} }
@ -299,7 +305,8 @@ INTERNAL int svg_plot(struct zint_symbol *symbol) {
circle = circle->next; 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; string = symbol->vector->strings;
while (string) { while (string) {
const char *halign = string->halign == 2 ? "end" : string->halign == 1 ? "start" : "middle"; const char *halign = string->halign == 2 ? "end" : string->halign == 1 ? "start" : "middle";

View File

@ -1,4 +1,4 @@
# Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com> # Copyright (C) 2009-2021 Robin Stuart <rstuart114@gmail.com>
# Adapted from qrencode/tests/CMakeLists.txt # Adapted from qrencode/tests/CMakeLists.txt
# Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org> # Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
# vim: set ts=4 sw=4 et : # 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} execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${BWIPP_TAR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tools) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tools)
endif() endif()
configure_file(${BWIPP_PS} ${CMAKE_CURRENT_BINARY_DIR}/tools/bwipp_dump.ps COPYONLY)
set(testcommon_SRCS testcommon.c testcommon.h) set(testcommon_SRCS testcommon.c testcommon.h)

View File

@ -12,10 +12,10 @@ ZINT_TEST option enabled:
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
In order to run the testsuite, the path of the zint library needs to be 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 communicated to the runtime linker. On UNIX-like systems, this is done by
by exporting LD_LIBRARY_PATH to the path containing the zint library, exporting LD_LIBRARY_PATH to the path containing the zint library, which is
which is <build-dir>/backend: <build-dir>/backend:
cd <project-dir> cd <project-dir>
cd build cd build
@ -25,37 +25,40 @@ 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 installed into a system library path ( /usr/lib for example ) prior to running
the tests. the tests.
To run all tests (within <build-dir>/backend/tests): To run all tests (within <build-dir>):
ctest 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 Tests can also be run individually, eg:
./test_vector
backend/tests/test_common
backend/tests/test_vector
To run a single test function within an individual test, use '-f <func-name>': To run a single test function within an individual test, use '-f <func-name>':
./test_common -f utf8_to_unicode backend/tests/test_common -f utf8_to_unicode
./test_dotcode -f input backend/tests/test_dotcode -f input
To run a single dataset item in a single test function, use '-i <index>': To run a single dataset item in a single test function, use '-i <index>':
./test_dotcode -f input -i 2 backend/tests/test_dotcode -f input -i 2
To show debug info (if any), use '-d <flag>': To show debug info (if any), use '-d <flag>':
./test_dotcode -f input -i 2 -d 1 backend/tests/test_dotcode -f input -i 2 -d 1
(for other flags see <project-dir>/backend/tests/testcommon.h) (for other flags see <project-dir>/backend/tests/testcommon.h)
To generate test data, use '-g': 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': To run a test against BWIPP (if any), use '-d 128':
./test_composite -d 128 backend/tests/test_composite -d 128
(see also <project-dir>/backend/tests/tools/run_bwipp_tests.sh) (see also <project-dir>/backend/tests/tools/run_bwipp_tests.sh)
@ -66,11 +69,11 @@ 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 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 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. runs the same test built against the zint-static library.

View File

@ -116,7 +116,7 @@ static void test_big5_utf8(int index) {
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { "_", -1, 0, 1, { 0xA1C4 }, "" }, /* 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); 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); assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol.errtxt);
if (ret == 0) { 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); 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]); 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]);
} }
} }

View File

@ -142,8 +142,8 @@ static void test_print(int index, int generate, int debug) {
if (generate) { if (generate) {
if (!testUtilExists(data_dir)) { if (!testUtilExists(data_dir)) {
ret = mkdir(data_dir, 0755); ret = testutil_mkdir(data_dir, 0755);
assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno));
} }
} }

View File

@ -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 length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data);
int out_length = length; int out_length = length;
int eci_length = get_eci_length(data[i].eci, (const unsigned char *) data[i].data, 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); 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); assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret);
if (ret == 0) { if (ret == 0) {

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions 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 (generate) {
if (!testUtilExists(data_dir)) { if (!testUtilExists(data_dir)) {
ret = mkdir(data_dir, 0755); ret = testutil_mkdir(data_dir, 0755);
assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno));
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -32,6 +32,19 @@
#include "testcommon.h" #include "testcommon.h"
#include "../large.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 } #define LI(l, h) { l, h }
int clz_u64(uint64_t x); int clz_u64(uint64_t x);
@ -181,7 +194,7 @@ static void test_clz_u64(int index) {
if (index != -1 && i != index) continue; if (index != -1 && i != index) continue;
ret = clz_u64(data[i].s); 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(); testFinish();
@ -214,9 +227,9 @@ static void test_load(int index) {
large_load(&data[i].t, &data[i].s); 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)); 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)); 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); 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)); 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)); 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); 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)); 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)); 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); 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)); 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)); 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); 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)); 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)); 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); 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(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",
assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%lX (%s) != expected lo 0x%lX (%s)\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)); 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)); 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); 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)); 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)); 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); large_dump(&data[i].t, dump);
assert_zero(strcmp(dump, data[i].expected), "i:%d { %lX, %lX } strcmp(%s, %s) != 0\n", assert_zero(strcmp(dump, data[i].expected), "i:%d { %" LX_FMT "X, %" LX_FMT "X } strcmp(%s, %s) != 0\n",
i, (unsigned long) data[i].t.lo, (unsigned long) data[i].t.hi, dump, data[i].expected); i, data[i].t.lo, data[i].t.hi, dump, data[i].expected);
} }
testFinish(); testFinish();

View File

@ -32,7 +32,6 @@
#include "testcommon.h" #include "testcommon.h"
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h>
static void test_checks(int index, int debug) { 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; FILE *fp;
fp = fopen(input_filename, "wb"); fp = fopen(input_filename, "wb");
assert_nonnull(fp, "i:%d fopen(%s) failed\n", i, input_filename); 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); assert_zero(fclose(fp), "i%d fclose() failed\n", i);
struct zint_symbol *symbol2 = ZBarcode_Create(); 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); ret = testUtilSymbolCmp(symbol2, symbol);
assert_zero(ret, "i:%d testUtilSymbolCmp symbol2 ret %d != 0\n", i, ret); 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); ZBarcode_Delete(symbol2);
} }
@ -334,6 +333,10 @@ static void test_encode_file_length(void) {
testStart(""); testStart("");
#ifdef _WIN32
testSkip("Test not compatible with Windows");
return;
#else
int ret; int ret;
char filename[] = "in.bin"; char filename[] = "in.bin";
char buf[ZINT_MAX_DATA_LEN + 1] = {0}; char buf[ZINT_MAX_DATA_LEN + 1] = {0};
@ -346,41 +349,42 @@ static void test_encode_file_length(void) {
// Empty file // Empty file
fd = creat(filename, S_IRUSR); fd = creat(filename, S_IRUSR);
assert_nonzero(fd, "Empty input file not created\n"); 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\n", filename); assert_zero(close(fd), "Empty close(%s) != 0 (%d: %s)\n", filename, errno, strerror(errno));
ret = ZBarcode_Encode_File(symbol, filename); 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_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 // Too large file
fd = creat(filename, S_IRUSR | S_IWUSR); 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)); ret = write(fd, buf, sizeof(buf));
assert_equal(ret, sizeof(buf), "Too large write ret %d != %d\n", ret, (int) 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); 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_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 // Unreadable file
fd = creat(filename, S_IWUSR); 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); ret = write(fd, buf, 1);
assert_equal(ret, 1, "Unreadable write ret %d != 1\n", ret); 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); 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_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); ZBarcode_Delete(symbol);
testFinish(); testFinish();
#endif /* _WIN32 */
} }
// #181 Nico Gunkel OSS-Fuzz (buffer not freed on fread() error) Note: unable to reproduce fread() error using this method // #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(); struct zint_symbol *symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n"); assert_nonnull(symbol, "Symbol not created\n");
(void)rmdir(dirname); // In case junk hanging around (void)testutil_rmdir(dirname); // In case junk hanging around
assert_zero(mkdir(dirname, 0700), "mkdir(%s, 0700) != 0\n", dirname); assert_zero(testutil_mkdir(dirname, 0700), "testutil_mkdir(%s, 0700) != 0 (%d: %s)\n", dirname, errno, strerror(errno));
ret = ZBarcode_Encode_File(symbol, dirname); 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_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); ZBarcode_Delete(symbol);

View File

@ -47,18 +47,26 @@ static void test_large(int index, int debug) {
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_MSI_PLESSEY, -1, "9", 55, 0, 1, 667 }, /* 0*/ { BARCODE_MSI_PLESSEY, -1, "9", 65, 0, 1, 787 },
/* 1*/ { BARCODE_MSI_PLESSEY, -1, "9", 56, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 1*/ { BARCODE_MSI_PLESSEY, -1, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 2*/ { BARCODE_MSI_PLESSEY, 1, "9", 18, 0, 1, 235 }, // 1 mod-10 check digit /* 2*/ { BARCODE_MSI_PLESSEY, 1, "9", 65, 0, 1, 799 }, // 1 mod-10 check digit
/* 3*/ { BARCODE_MSI_PLESSEY, 1, "9", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 3*/ { BARCODE_MSI_PLESSEY, 1, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 4*/ { BARCODE_MSI_PLESSEY, 2, "9", 18, 0, 1, 247 }, // 2 mod-10 check digits /* 4*/ { BARCODE_MSI_PLESSEY, 2, "9", 65, 0, 1, 811 }, // 2 mod-10 check digits
/* 5*/ { BARCODE_MSI_PLESSEY, 2, "9", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 5*/ { BARCODE_MSI_PLESSEY, 2, "9", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 6*/ { BARCODE_MSI_PLESSEY, 3, "9", 55, 0, 1, 679 }, // 1 mod-11 check digit /* 6*/ { BARCODE_MSI_PLESSEY, 3, "9", 65, 0, 1, 799 }, // 1 mod-11 check digit
/* 7*/ { BARCODE_MSI_PLESSEY, 3, "9", 56, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 7*/ { BARCODE_MSI_PLESSEY, 3, "9", 66, 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 /* 8*/ { BARCODE_MSI_PLESSEY, 3, "3", 65, 0, 1, 811 }, // 1 mod-11 double check digit "10"
/* 9*/ { BARCODE_MSI_PLESSEY, 4, "9", 19, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 9*/ { BARCODE_MSI_PLESSEY, 3, "3", 66, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 10*/ { BARCODE_PLESSEY, -1, "A", 65, 0, 1, 1107 }, /* 10*/ { BARCODE_MSI_PLESSEY, 4, "9", 65, 0, 1, 811 }, // 1 mod-11 and 1 mod-10 check digit
/* 11*/ { BARCODE_PLESSEY, -1, "A", 66, ZINT_ERROR_TOO_LONG, -1, -1 }, /* 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); 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" }, /* 0*/ { BARCODE_MSI_PLESSEY, -1, "1234567", "1234567" },
/* 1*/ { BARCODE_MSI_PLESSEY, 0, "1234567", "1234567" }, /* 1*/ { BARCODE_MSI_PLESSEY, 0, "1234567", "1234567" },
/* 2*/ { BARCODE_MSI_PLESSEY, 1, "1234567", "12345674" }, /* 2*/ { BARCODE_MSI_PLESSEY, 1, "1234567", "12345674" },
/* 3*/ { BARCODE_MSI_PLESSEY, 2, "1234567", "123456741" }, /* 3*/ { BARCODE_MSI_PLESSEY, 1 + 10, "1234567", "1234567" },
/* 4*/ { BARCODE_MSI_PLESSEY, 3, "1234567", "12345674" }, /* 4*/ { BARCODE_MSI_PLESSEY, 1, "9999999999", "99999999990" },
/* 5*/ { BARCODE_MSI_PLESSEY, 4, "1234567", "123456741" }, /* 5*/ { BARCODE_MSI_PLESSEY, 2, "1234567", "123456741" },
/* 6*/ { BARCODE_MSI_PLESSEY, 1, "123456", "1234566" }, /* 6*/ { BARCODE_MSI_PLESSEY, 2 + 10, "1234567", "1234567" },
/* 7*/ { BARCODE_MSI_PLESSEY, 2, "123456", "12345666" }, /* 7*/ { BARCODE_MSI_PLESSEY, 2, "9999999999", "999999999900" },
/* 8*/ { BARCODE_MSI_PLESSEY, 3, "123456", "1234560" }, /* 8*/ { BARCODE_MSI_PLESSEY, 3, "1234567", "12345674" },
/* 9*/ { BARCODE_MSI_PLESSEY, 4, "123456", "12345609" }, /* 9*/ { BARCODE_MSI_PLESSEY, 3 + 10, "1234567", "1234567" },
/* 10*/ { BARCODE_MSI_PLESSEY, 3, "2211", "221110" }, // Mod-11 check digit '10' /* 10*/ { BARCODE_MSI_PLESSEY, 3, "9999999999", "99999999995" },
/* 11*/ { BARCODE_MSI_PLESSEY, 4, "2211", "2211100" }, /* 11*/ { BARCODE_MSI_PLESSEY, 4, "1234567", "123456741" },
/* 12*/ { BARCODE_PLESSEY, -1, "0123456789ABCDEF", "0123456789ABCDEF" }, /* 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); 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, "", /* 4*/ { BARCODE_MSI_PLESSEY, 4, "1234567890", 0, 1, 151, "",
"1101001001001101001001101001001001101101001101001001001101001101001101101001001101101101101001001001101001001101001001001001001001101101001001001101001" "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" "1101001001101001001001101001001001001101001001001101001001001101001001001001001"
}, },
/* 6*/ { BARCODE_MSI_PLESSEY, 4, "2211", 0, 1, 91, "BWIPP (badmod11)", /* 8*/ { BARCODE_MSI_PLESSEY, 4, "2211", 0, 1, 91, "BWIPP (badmod11)",
"1101001001101001001001101001001001001101001001001101001001001101001001001001001001001001001" "1101001001101001001001101001001001001101001001001101001001001101001001001001001001001001001"
}, },
/* 7*/ { BARCODE_PLESSEY, -1, "0123456789ABCDEF", 0, 1, 323, "", /* 9*/ { BARCODE_PLESSEY, -1, "0123456789ABCDEF", 0, 1, 323, "",
"11101110100011101000100010001000111010001000100010001110100010001110111010001000100010001110100011101000111010001000111011101000111011101110100010001000100011101110100010001110100011101000111011101110100011101000100011101110111010001110111010001110111011101110111011101110111010001000111010001000100010001110001000101110111" "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" "1101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001101101001001001001001001101001"
}, },
}; };

View File

@ -196,8 +196,8 @@ static void test_print(int index, int generate, int debug) {
if (generate) { if (generate) {
if (!testUtilExists(data_dir)) { if (!testUtilExists(data_dir)) {
ret = mkdir(data_dir, 0755); ret = testutil_mkdir(data_dir, 0755);
assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno));
} }
} }

View File

@ -81,13 +81,13 @@ static void test_print(int index, int generate, int debug) {
if (generate) { if (generate) {
strcpy(data_dir, "data"); strcpy(data_dir, "data");
if (!testUtilExists(data_dir)) { if (!testUtilExists(data_dir)) {
ret = mkdir(data_dir, 0755); ret = testutil_mkdir(data_dir, 0755);
assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno));
} }
strcat(data_dir, "/print"); strcat(data_dir, "/print");
if (!testUtilExists(data_dir)) { if (!testUtilExists(data_dir)) {
ret = mkdir(data_dir, 0755); ret = testutil_mkdir(data_dir, 0755);
assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); 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 (generate) {
if (!testUtilExists(data_dir)) { if (!testUtilExists(data_dir)) {
ret = mkdir(data_dir, 0755); ret = testutil_mkdir(data_dir, 0755);
assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno));
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions 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 (generate) {
if (!testUtilExists(data_dir)) { if (!testUtilExists(data_dir)) {
ret = mkdir(data_dir, 0755); ret = testutil_mkdir(data_dir, 0755);
assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno));
} }
} }

View File

@ -111,8 +111,8 @@ static void test_print(int index, int generate, int debug) {
if (generate) { if (generate) {
if (!testUtilExists(data_dir)) { if (!testUtilExists(data_dir)) {
ret = mkdir(data_dir, 0755); ret = testutil_mkdir(data_dir, 0755);
assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno));
} }
} }

View File

@ -190,8 +190,8 @@ static void test_print(int index, int generate, int debug) {
if (generate) { if (generate) {
if (!testUtilExists(data_dir)) { if (!testUtilExists(data_dir)) {
ret = mkdir(data_dir, 0755); ret = testutil_mkdir(data_dir, 0755);
assert_zero(ret, "mkdir(%s) ret %d != 0\n", data_dir, ret); assert_zero(ret, "testutil_mkdir(%s) ret %d != 0 (%d: %s)\n", data_dir, ret, errno, strerror(errno));
} }
} }

View File

@ -529,9 +529,9 @@ static void test_stacking(int index, int debug) {
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_CODE128, -1, -1, -1, "A", "B", 50, 2, 46, 92, 116.1, -1, -1, -1 }, /* 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.1, 49, 0, 2 }, /* 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.1, 48, 0, 4 }, /* 2*/ { BARCODE_CODE128, BARCODE_BIND, -1, 2, "A", "B", 50, 2, 46, 92, 116, 48, 0, 4 },
}; };
int data_size = ARRAY_SIZE(data); int data_size = ARRAY_SIZE(data);

View File

@ -34,6 +34,14 @@
*/ */
#include "testcommon.h" #include "testcommon.h"
#ifdef _MSC_VER
#include <malloc.h>
#define testutil_alloca(nmemb) _alloca(nmemb)
#else
#define testutil_alloca(nmemb) alloca(nmemb)
#endif
#include "../eci.h" #include "../eci.h"
#ifndef NO_PNG #ifndef NO_PNG
#include <png.h> #include <png.h>
@ -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) { 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' }; 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 *e = expected;
const char *ep = expected + strlen(expected); const char *ep = expected + strlen(expected);
char buf[7]; 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 */ /* 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 (*d < 0x20 || *d >= 0x7F || *d == '^' || *d == '"' || *d == '\'') {
if (b + 4 >= be) { 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; return NULL;
} }
sprintf(b, "^%03u", *d++); 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; default: fprintf(stderr, "testUtilBwippEscape: unknown escape %c\n", *d); return NULL; break;
} }
if (b + 4 >= be) { 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; return NULL;
} }
sprintf(b, "^%03d", val); 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) { 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; return NULL;
} }
*b = '\0'; *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 */ #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) { 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_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' ../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' ../tools/bwipp_dump.ps"; // If data > 2K 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' ../tools/bwipp_dump.ps"; 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 symbology = symbol->symbology;
int data_len = length == -1 ? (int) strlen(data) : length; 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 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); int eci_length = get_eci_length(symbol->eci, (const unsigned char *) data, data_len);
char *converted = alloca(eci_length + 1); char *converted = (char *) testutil_alloca(eci_length + 1);
char *cmd = alloca(max_data_len + 1024); char *cmd = (char *) testutil_alloca(max_data_len + 1024);
const char *bwipp_barcode = NULL; const char *bwipp_barcode = NULL;
char *bwipp_opts = 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]; 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 linear_row_height;
int gs1_cvt; int gs1_cvt;
int user_mask; int user_mask;
@ -2227,7 +2236,7 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
} }
} }
} else { } 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; return -1;
} }
if (parse) { 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) ? " " : ""); sprintf(bwipp_opts_buf + (int) strlen(bwipp_opts_buf), "%sincludecheck", strlen(bwipp_opts_buf) ? " " : "");
const char *checktype = NULL; const char *checktype = NULL;
if (option_2 >= 11 && option_2 <= 16) {
option_2 -= 10; /* Remove no-check indicator */
}
if (option_2 == 2) { if (option_2 == 2) {
checktype = "mod1010"; checktype = "mod1010";
} else if (option_2 == 3) { } else if (option_2 == 3) {
checktype = "mod11 badmod11"; checktype = "mod11 badmod11";
} else if (option_2 == 4) { } else if (option_2 == 4) {
checktype = "mod1110 badmod11"; checktype = "mod1110 badmod11";
} else if (option_2 == 5) {
checktype = "ncrmod11 badmod11";
} else if (option_2 == 6) {
checktype = "ncrmod1110 badmod11";
} }
if (checktype) { if (checktype) {
sprintf(bwipp_opts_buf + (int) strlen(bwipp_opts_buf), "%schecktype=%s", strlen(bwipp_opts_buf) ? " " : "", 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) { 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 */ sprintf(scm_vv_buf, "[)>^03001^029%02d", option_2); /* [)>\R01\Gvv */
memmove(bwipp_data + 15, bwipp_data, strlen(bwipp_data) + 1); memmove(bwipp_data + 15, bwipp_data, strlen(bwipp_data) + 1);
memcpy(bwipp_data, scm_vv_buf, 15); 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); printf("i:%d testUtilBwipp: cmd %s\n", index, cmd);
} }
fp = popen(cmd, "r"); fp = testutil_popen(cmd, "r");
if (!fp) { if (!fp) {
fprintf(stderr, "i:%d testUtilBwipp: failed to run '%s'\n", index, cmd); fprintf(stderr, "i:%d testUtilBwipp: failed to run '%s'\n", index, cmd);
return -1; 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++) { for (r = 0; r < symbol->rows; r++) {
if (b + symbol->width > be) { 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); 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; return -1;
} }
cnt = fread(b, 1, symbol->width, fp); cnt = fread(b, 1, symbol->width, fp);
if (cnt != symbol->width) { 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); 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; return -1;
} }
b += cnt; b += cnt;
@ -2645,7 +2661,7 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
if (cnt != symbol->width) { 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", 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); index, symbol->width, cnt, h, r, bwipp_row_height[r], r, symbol->row_height[r], cmd);
pclose(fp); testutil_pclose(fp);
return -1; return -1;
} }
} }
@ -2654,11 +2670,11 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int
if (fgetc(fp) != EOF) { if (fgetc(fp) != EOF) {
fprintf(stderr, "i:%d testUtilBwipp: failed to read full stream (%s)\n", index, cmd); fprintf(stderr, "i:%d testUtilBwipp: failed to read full stream (%s)\n", index, cmd);
pclose(fp); testutil_pclose(fp);
return -1; return -1;
} }
pclose(fp); testutil_pclose(fp);
return 0; return 0;
} }

View File

@ -42,17 +42,38 @@
#define ZINT_DEBUG_TEST_BWIPP 128 #define ZINT_DEBUG_TEST_BWIPP 128
#define ZINT_DEBUG_TEST_PERFORMANCE 256 #define ZINT_DEBUG_TEST_PERFORMANCE 256
#ifdef _WIN32 #ifdef _MSC_VER
#include <malloc.h> #define testutil_popen(command, mode) _popen(command, mode)
#define alloca(nmemb) _malloca(nmemb) #define testutil_pclose(stream) _pclose(stream)
#define popen(command, mode) _popen(command, mode)
#define pclose(stream) _pclose(stream)
#else #else
#include <unistd.h> #include <unistd.h>
#define testutil_popen(command, mode) popen(command, mode)
#define testutil_pclose(stream) pclose(stream)
#endif #endif
#ifdef _WIN32
#include <direct.h>
#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 <stdio.h> #include <stdio.h>
#include <errno.h>
#include "../common.h" #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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -72,7 +93,9 @@ void testFinish(void);
void testSkip(const char *msg); void testSkip(const char *msg);
void testReport(); 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); void testRun(int argc, char *argv[], testFunction funcs[], int funcs_size);
#define assert_exp(__exp__, ...) \ #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 */ 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 *testUtilBarcodeName(int symbology);
const char *testUtilErrorName(int error_number); const char *testUtilErrorName(int error_number);
const char *testUtilInputModeName(int input_mode); const char *testUtilInputModeName(int input_mode);
@ -129,10 +153,13 @@ int testUtilHaveVnu();
int testUtilVerifyVnu(char *filename, int debug); int testUtilVerifyVnu(char *filename, int debug);
int testUtilHaveTiffInfo(); int testUtilHaveTiffInfo();
int testUtilVerifyTiffInfo(char *filename, int debug); 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 testUtilCanBwipp(int index, const struct zint_symbol *symbol, int option_1, int option_2, int option_3,
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 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 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 #ifdef __cplusplus
} }

View File

@ -6,10 +6,10 @@ set -e
function run_bwipp_test() { function run_bwipp_test() {
if [ -z "$2" ]; then if [ -z "$2" ]; then
echo -e "\n$1" echo -e "\n$1"
./$1 -d $(expr 128 + 16 + 32) || exit 1 backend/tests/$1 -d $(expr 128 + 16 + 32) || exit 1
else else
echo -e "\n$1 -f $2" 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 fi
} }

View File

@ -32,6 +32,7 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
@ -333,14 +334,14 @@ INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, unsigned char *pixelbuf)
if (symbol->output_options & BARCODE_STDOUT) { if (symbol->output_options & BARCODE_STDOUT) {
#ifdef _MSC_VER #ifdef _MSC_VER
if (-1 == _setmode(_fileno(stdout), _O_BINARY)) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
#endif #endif
tif_file = stdout; tif_file = stdout;
} else { } else {
if (!(tif_file = fopen(symbol->outfile, "wb+"))) { 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; return ZINT_ERROR_FILE_ACCESS;
} }
compression = TIF_LZW; compression = TIF_LZW;

View File

@ -1,7 +1,7 @@
/* ultra.c - Ultracode /* ultra.c - Ultracode
libzint - the open source barcode library libzint - the open source barcode library
Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com> Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions 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 char ultra_colour[] = "0CBMRYGKW";
//static const int ultra_maxsize[] = {34, 78, 158, 282}; // According to Table 1 //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 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++) { for (j = 0; j < 27; j++) {
latch = 0; latch = 0;
fraglen = strlen(fragment[j]); fraglen = (int) strlen(fragment[j]);
if ((position + fraglen) <= source_length) { if ((position + fraglen) <= source_length) {
latch = 1; latch = 1;
for (k = 0; k < fraglen; k++) { 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 */ /* 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 codeword_count = 0;
int i; int i;
int letters_encoded = 0; 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) */ /* 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 codeword_count = 0;
int i; int i;
int first_digit, second_digit, done; 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); fragno = ultra_find_fragment(data, length, i);
if (fragno != -1 && fragno != 26) { if (fragno != -1 && fragno != 26) {
fraglen = strlen(fragment[fragno]); fraglen = (int) strlen(fragment[fragno]);
predict_window += fraglen; predict_window += fraglen;
if (predict_window > length) { if (predict_window > length) {
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 */ /* 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 codeword_count = 0;
int subcodeword_count = 0; int subcodeword_count = 0;
int i; int i;
@ -451,32 +454,32 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn,
switch(fragno) { switch(fragno) {
case 17: // mailto: case 17: // mailto:
cw[codeword_count] = 276; cw[codeword_count] = 276;
sublocn += strlen(fragment[fragno]); sublocn += (int) strlen(fragment[fragno]);
codeword_count++; codeword_count++;
break; break;
case 18: // tel: case 18: // tel:
cw[codeword_count] = 277; cw[codeword_count] = 277;
sublocn += strlen(fragment[fragno]); sublocn += (int) strlen(fragment[fragno]);
codeword_count++; codeword_count++;
break; break;
case 26: // file: case 26: // file:
cw[codeword_count] = 278; cw[codeword_count] = 278;
sublocn += strlen(fragment[fragno]); sublocn += (int) strlen(fragment[fragno]);
codeword_count++; codeword_count++;
break; break;
case 0: // http:// case 0: // http://
cw[codeword_count] = 279; cw[codeword_count] = 279;
sublocn += strlen(fragment[fragno]); sublocn += (int) strlen(fragment[fragno]);
codeword_count++; codeword_count++;
break; break;
case 1: // https:// case 1: // https://
cw[codeword_count] = 280; cw[codeword_count] = 280;
sublocn += strlen(fragment[fragno]); sublocn += (int) strlen(fragment[fragno]);
codeword_count++; codeword_count++;
break; break;
case 4: // ftp:// case 4: // ftp://
cw[codeword_count] = 281; cw[codeword_count] = 281;
sublocn += strlen(fragment[fragno]); sublocn += (int) strlen(fragment[fragno]);
codeword_count++; codeword_count++;
break; break;
default: default:
@ -558,12 +561,12 @@ static float look_ahead_c43(unsigned char source[], int in_length, int in_locn,
if ((fragno >= 0) && (fragno <= 18)) { if ((fragno >= 0) && (fragno <= 18)) {
subcw[subcodeword_count] = fragno; // C43 Set 3 codewords 0 to 18 subcw[subcodeword_count] = fragno; // C43 Set 3 codewords 0 to 18
subcodeword_count++; subcodeword_count++;
sublocn += strlen(fragment[fragno]); sublocn += (int) strlen(fragment[fragno]);
} }
if ((fragno >= 19) && (fragno <= 25)) { if ((fragno >= 19) && (fragno <= 25)) {
subcw[subcodeword_count] = fragno + 17; // C43 Set 3 codewords 36 to 42 subcw[subcodeword_count] = fragno + 17; // C43 Set 3 codewords 36 to 42
subcodeword_count++; subcodeword_count++;
sublocn += strlen(fragment[fragno]); sublocn += (int) strlen(fragment[fragno]);
} }
if (fragno == -1) { if (fragno == -1) {
subcw[subcodeword_count] = posn(ultra_c43_set3, source[sublocn]) + 19; // C43 Set 3 codewords 19 to 35 subcw[subcodeword_count] = posn(ultra_c43_set3, source[sublocn]) + 19; // C43 Set 3 codewords 19 to 35
@ -637,8 +640,8 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c
char mode[in_length + 1]; char mode[in_length + 1];
int cw_fragment[in_length * 2 + 1]; int cw_fragment[in_length * 2 + 1];
#else #else
unsigned char * crop_source = (unsigned char *) _alloca((in_length + 1) * sizeof (unsigned char)); unsigned char * crop_source = (unsigned char *) _alloca(in_length + 1);
char * mode = (char *) _alloca((in_length + 1) * sizeof (char)); char * mode = (char *) _alloca(in_length + 1);
int * cw_fragment = (int *) _alloca((in_length * 2 + 1) * sizeof(int)); int * cw_fragment = (int *) _alloca((in_length * 2 + 1) * sizeof(int));
#endif /* _MSC_VER */ #endif /* _MSC_VER */
@ -769,10 +772,13 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c
input_locn = 0; input_locn = 0;
do { do {
end_char = input_locn + PREDICT_WINDOW; 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); eightbit_score = look_ahead_eightbit(crop_source, crop_length, input_locn, current_mode, end_char,
ascii_score = look_ahead_ascii(crop_source, crop_length, input_locn, current_mode, symbol_mode, end_char, cw_fragment, &fragment_length, &ascii_encoded, gs1); 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; 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'; mode[input_locn] = 'a';
current_mode = ASCII_MODE; current_mode = ASCII_MODE;
@ -824,21 +830,26 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c
switch(mode[input_locn]) { switch(mode[input_locn]) {
case 'a': 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; current_mode = ASCII_MODE;
break; break;
case 'c': case 'c':
subset = c43_should_latch_other(crop_source, crop_length, input_locn, 1 /*subset*/, gs1) ? 2 : 1; 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 */ /* 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 */ /* Temporary latch to submode 1 from Table 11 */
cw_fragment[0] = 256 + ((fragment_length - 5) / 2); 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 */ /* Temporary latch to submode 2 from Table 11 */
cw_fragment[0] = 262 + ((fragment_length - 5) / 2); 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 */ /* Temporary latch to submode 1 from Table 9 */
cw_fragment[0] = 274 + ((fragment_length - 5) / 2); cw_fragment[0] = 274 + ((fragment_length - 5) / 2);
} else { } else {
@ -846,7 +857,8 @@ static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned c
} }
break; break;
case '8': 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; current_mode = EIGHTBIT_MODE;
break; break;
} }
@ -870,7 +882,8 @@ INTERNAL int ultracode(struct zint_symbol *symbol, unsigned char source[], int l
int total_cws; int total_cws;
int pads; int pads;
int cw_memalloc; 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 i, j, locn;
int total_height, total_width; int total_height, total_width;
char tilepat[6]; char tilepat[6];
@ -943,7 +956,8 @@ INTERNAL int ultracode(struct zint_symbol *symbol, unsigned char source[], int l
rows = 5; rows = 5;
for (i = 2; i >= 0; i--) { 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--; rows--;
} }
} }
@ -1005,7 +1019,7 @@ INTERNAL int ultracode(struct zint_symbol *symbol, unsigned char source[], int l
#ifndef _MSC_VER #ifndef _MSC_VER
char pattern[total_height * total_width]; char pattern[total_height * total_width];
#else #else
pattern = (char *) _alloca(total_height * total_width * sizeof (char)); pattern = (char *) _alloca(total_height * total_width);
#endif /* _MSC_VER */ #endif /* _MSC_VER */
for (i = 0; i < (total_height * total_width); i++) { for (i = 0; i < (total_height * total_width); i++) {

View File

@ -138,10 +138,10 @@ static int vector_plot_add_string(struct zint_symbol *symbol,
string->y = y; string->y = y;
string->width = width; string->width = width;
string->fsize = fsize; string->fsize = fsize;
string->length = ustrlen(text); string->length = (int) ustrlen(text);
string->rotation = 0; string->rotation = 0;
string->halign = halign; 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; } if (!string->text) { free(string); return 0; }
ustrcpy(string->text, text); ustrcpy(string->text, text);

View File

@ -305,7 +305,7 @@ extern "C" {
#define ZINT_DEBUG_PRINT 1 #define ZINT_DEBUG_PRINT 1
#define ZINT_DEBUG_TEST 2 #define ZINT_DEBUG_TEST 2
#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(_MSC_VER) #ifdef _WIN32
# if defined(DLL_EXPORT) || defined(PIC) || defined(_USRDLL) # if defined(DLL_EXPORT) || defined(PIC) || defined(_USRDLL)
# define ZINT_EXTERN __declspec(dllexport) # define ZINT_EXTERN __declspec(dllexport)
# elif defined(ZINT_DLL) # elif defined(ZINT_DLL)

View File

@ -1,4 +1,4 @@
# Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com> # Copyright (C) 2021 Robin Stuart <rstuart114@gmail.com>
# Adapted from qrencode/tests/CMakeLists.txt # Adapted from qrencode/tests/CMakeLists.txt
# Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org> # Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
# vim: set ts=4 sw=4 et : # vim: set ts=4 sw=4 et :

View File

@ -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 --vers=1. To add a check digit but not show it in the human readable text, set
option_2 = 2 or --vers=2. 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 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 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, 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 Value of option_2 | Check Digits
------------------------------------------- -------------------------------------------
0 | None 0 | None
1 | Modulo-10 1 | Modulo-10 (Luhn)
2 | Modulo-10 & Modulo-10 2 | Modulo-10 & Modulo-10
3 | Modulo-11 3 | Modulo-11 (IBM)
4 | Modulo-11 & Modulo-10 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 Telepen
------------- -------------
6.1.7.1 Telepen Alpha 6.1.7.1 Telepen Alpha
@ -3196,6 +3201,8 @@ international standards:
> ISO/IEC JTC1/SC31N000 (Draft 2018-6-8) Information technology - Automatic > ISO/IEC JTC1/SC31N000 (Draft 2018-6-8) Information technology - Automatic
identification and data capture techniques - Rectangular Micro QR Code identification and data capture techniques - Rectangular Micro QR Code
(rMQR) bar code symbology specification (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) > Uniform Symbology Specification Code One (AIM Inc., 1994)
> ANSI/AIM BC12-1998 - Uniform Symbology Specification Channel Code > ANSI/AIM BC12-1998 - Uniform Symbology Specification Channel Code
> ANSI/AIM BC6-2000 - Uniform Symbology Specification Code 49 > ANSI/AIM BC6-2000 - Uniform Symbology Specification Code 49

View File

@ -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 <rstuart114@gmail.com>
project(zint_frontend) project(zint_frontend)
@ -13,10 +14,10 @@ set_target_properties(zint_frontend PROPERTIES OUTPUT_NAME "zint")
target_link_libraries(zint_frontend zint) target_link_libraries(zint_frontend zint)
if(NOT HAVE_GETOPT) if(NOT HAVE_GETOPT)
target_link_libraries(zint_frontend zint_bundled_getopt) target_link_libraries(zint_frontend zint_bundled_getopt)
endif(NOT HAVE_GETOPT) endif()
install(TARGETS zint_frontend DESTINATION "${BIN_INSTALL_DIR}" RUNTIME) install(TARGETS zint_frontend DESTINATION "${BIN_INSTALL_DIR}" RUNTIME)
if(ZINT_TEST) if(ZINT_TEST)
add_subdirectory(tests) add_subdirectory(tests)
endif(ZINT_TEST) endif()

View File

@ -29,9 +29,12 @@
#include <zint.h> #include <zint.h>
#else #else
#include <malloc.h> #include <malloc.h>
#include "getopt.h" #include "../getopt/getopt.h"
#include "zint.h" #include "zint.h"
#if _MSC_VER >= 1900 /* MSVC 2015 */
#pragma warning(disable: 4996) /* function or variable may be unsafe */
#endif #endif
#endif /* _MSC_VER */
/* It's assumed that int is at least 32 bits, the following will compile-time fail if not /* It's assumed that int is at least 32 bits, the following will compile-time fail if not
* https://stackoverflow.com/a/1980056/664741 */ * https://stackoverflow.com/a/1980056/664741 */
@ -330,6 +333,7 @@ static int get_barcode_name(const char *barcode_name) {
{ BARCODE_MAXICODE, "maxicode" }, { BARCODE_MAXICODE, "maxicode" },
{ BARCODE_MICROPDF417, "micropdf417" }, { BARCODE_MICROPDF417, "micropdf417" },
{ BARCODE_MICROQR, "microqr" }, { BARCODE_MICROQR, "microqr" },
{ BARCODE_MSI_PLESSEY, "msi" }, /* Synonym */
{ BARCODE_MSI_PLESSEY, "msiplessey" }, { BARCODE_MSI_PLESSEY, "msiplessey" },
{ BARCODE_NVE18, "nve18" }, { BARCODE_NVE18, "nve18" },
{ BARCODE_PDF417, "pdf417" }, { BARCODE_PDF417, "pdf417" },

View File

@ -2,8 +2,8 @@ Zint frontend test suite
------------------------ ------------------------
See <project-dir>/backend/tests/README to see how to build the test suite. See <project-dir>/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 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 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 this can be configured by prepending the PATH variable with the frontend's
directory inside the build directory: directory inside the build directory:

View File

@ -29,18 +29,80 @@
*/ */
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */
#include <errno.h>
#include "testcommon.h" #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) { static char *exec(const char *cmd, char *buf, int buf_size, int debug, int index) {
FILE *fp; FILE *fp;
int cnt; 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); if (debug & ZINT_DEBUG_TEST_PRINT) printf("%d: %s\n", index, cmd);
*buf = '\0'; *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) { if (!fp) {
fprintf(stderr, "exec: failed to run '%s'\n", cmd); fprintf(stderr, "exec: failed to run '%s'\n", cmd);
return NULL; 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); cnt = fread(buf, 1, buf_size, fp);
if (fgetc(fp) != EOF) { if (fgetc(fp) != EOF) {
fprintf(stderr, "exec: failed to read full stream (%s)\n", cmd); fprintf(stderr, "exec: failed to read full stream (%s)\n", cmd);
pclose(fp); testutil_pclose(fp);
return NULL; return NULL;
} }
pclose(fp); testutil_pclose(fp);
if (cnt) { if (cnt) {
if (buf[cnt - 1] == '\r' || buf[cnt - 1] == '\n') { 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) { static void arg_data(char *cmd, const char *opt, const char *data) {
if (data != NULL) { 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); 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 1;
} }
return 0; 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); assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd);
if (have_input1) { 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) { 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(""); testStart("");
#ifdef _WIN32
#define TEST_INPUT_LONG "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234"
#else
#define TEST_INPUT_LONG "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
#endif
struct item { struct item {
int b; int b;
int batch; int batch;
@ -305,19 +373,19 @@ static void test_input(int index, int debug) {
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n456\n", "test_batch~.png", 2, "test_batch1.png\000test_batch2.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, NULL, "123\n456\n7890123456789\n", NULL, 3, "123.png\000456.png\0007890123456789.png" }, /* 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" }, /* 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" }, /* 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, NULL, "123\n456\n7890123456789\nA\\xA0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_B.png" }, /* 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, NULL, "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_u00A0B.png" }, /* 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, NULL, "123\n456\n7890123456789\nA\\u00A0B\n", NULL, 4, "123.png\000456.png\0007890123456789.png\000A_B.png" }, /* 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, NULL, "\n", "test_batch.png", 0, NULL }, /* 7*/ { BARCODE_CODE128, 1, -1, 0, "gif", "\n", "test_batch.gif", 0, NULL },
/* 8*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n456\n", "test_67890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890~.png", 2, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png\000test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678902.png" }, /* 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_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png", 1, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.svg" }, /* 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_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.png", 1, "test_678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.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, NULL, "123\n", "test_batch.jpeg", 1, "test_batch.jpeg.png" }, /* 11*/ { BARCODE_CODE128, 1, -1, 0, "gif", "123\n", "test_batch.jpeg", 1, "test_batch.jpeg.gif" },
/* 12*/ { BARCODE_CODE128, 1, -1, 0, NULL, "123\n", "test_batch.jpg", 1, "test_batch.png" }, /* 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" }, /* 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" }, /* 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" }, /* 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; outfile = data[i].expected;
for (int j = 0; j < data[i].num_expected; j++) { 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_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; 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(); testFinish();
@ -375,7 +443,7 @@ static void test_stdin_input(int index, int debug) {
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { 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); 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_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_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(); 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); assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s)\n", i, buf, data[i].expected);
if (have_input1) { 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) { 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(""); testStart("");
#ifdef _WIN32
testSkip("Test not compatible with Windows");
return;
#endif
struct item { struct item {
int b; int b;
int mirror; int mirror;
@ -479,8 +552,8 @@ static void test_batch_large(int index, int debug) {
}; };
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = { struct item data[] = {
/* 0*/ { BARCODE_HANXIN, 0, "1", 7827, "out.png" }, /* 0*/ { BARCODE_HANXIN, 0, "1", 7827, "out.gif" },
/* 1*/ { BARCODE_HANXIN, 1, "1", 7827, "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.png" }, /* 1*/ { BARCODE_HANXIN, 1, "1", 7827, "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.gif" },
/* 2*/ { BARCODE_HANXIN, 0, "1", 7828, NULL }, /* 2*/ { BARCODE_HANXIN, 0, "1", 7828, NULL },
}; };
int data_size = ARRAY_SIZE(data); 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 (index != -1 && i != index) continue;
if ((debug & ZINT_DEBUG_TEST_PRINT) && !(debug & ZINT_DEBUG_TEST_LESS_NOISY)) printf("i:%d\n", i); 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) { if (debug & ZINT_DEBUG_PRINT) {
strcat(cmd, " --verbose"); 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); assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i), "i:%d exec(%s) NULL\n", i, cmd);
if (data[i].expected) { 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 { } 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) { 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" }, /* 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" }, /* 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" }, /* 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" }, /* 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" }, /* 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" }, /* 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 cmd[4096];
char buf[4096]; char buf[4096];
char *outfilename = "out.png"; char *outfilename = "out.gif";
for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue; if (index != -1 && i != index) continue;
strcpy(cmd, "zint -d '1'"); strcpy(cmd, "zint -d 1 --filetype=gif");
if (debug & ZINT_DEBUG_PRINT) { if (debug & ZINT_DEBUG_PRINT) {
strcat(cmd, " --verbose"); 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); 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) { 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," }, /* 34*/ { "upce", "1", NULL, 0, "symbology: 37," },
/* 35*/ { "upce chk", "12345670", NULL, 0, "symbology: 38," }, /* 35*/ { "upce chk", "12345670", NULL, 0, "symbology: 38," },
/* 36*/ { "POSTNET ", "12345678901", NULL, 0, "symbology: 40," }, /* 36*/ { "POSTNET ", "12345678901", NULL, 0, "symbology: 40," },
/* 37*/ { "MSI Plessey ", "1", NULL, 0, "symbology: 47," }, /* 37*/ { "msi", "1", NULL, 0, "symbology: 47," },
/* 38*/ { "fim ", "A", NULL, 0, "symbology: 49," }, /* 38*/ { "MSI Plessey ", "1", NULL, 0, "symbology: 47," },
/* 39*/ { "LOGMARS", "123456", NULL, 0, "symbology: 50," }, /* 39*/ { "fim ", "A", NULL, 0, "symbology: 49," },
/* 40*/ { " pharma", "123456", NULL, 0, "symbology: 51," }, /* 40*/ { "LOGMARS", "123456", NULL, 0, "symbology: 50," },
/* 41*/ { " pzn ", "1", NULL, 0, "symbology: 52," }, /* 41*/ { " pharma", "123456", NULL, 0, "symbology: 51," },
/* 42*/ { "pharma two", "4", NULL, 0, "symbology: 53," }, /* 42*/ { " pzn ", "1", NULL, 0, "symbology: 52," },
/* 43*/ { "BARCODE_PDF417", "1", NULL, 0, "symbology: 55," }, /* 43*/ { "pharma two", "4", NULL, 0, "symbology: 53," },
/* 44*/ { "barcodepdf417comp", "1", NULL, 0, "symbology: 56," }, /* 44*/ { "BARCODE_PDF417", "1", NULL, 0, "symbology: 55," },
/* 45*/ { "MaxiCode", "1", NULL, 0, "symbology: 57," }, /* 45*/ { "barcodepdf417comp", "1", NULL, 0, "symbology: 56," },
/* 46*/ { "QR CODE", "1", NULL, 0, "symbology: 58," }, /* 46*/ { "MaxiCode", "1", NULL, 0, "symbology: 57," },
/* 47*/ { "qr", "1", NULL, 0, "symbology: 58," }, // Synonym /* 47*/ { "QR CODE", "1", NULL, 0, "symbology: 58," },
/* 48*/ { "Code 128 B", "1", NULL, 0, "symbology: 60," }, /* 48*/ { "qr", "1", NULL, 0, "symbology: 58," }, // Synonym
/* 49*/ { "AUS POST", "12345678901234567890123", NULL, 0, "symbology: 63," }, /* 49*/ { "Code 128 B", "1", NULL, 0, "symbology: 60," },
/* 50*/ { "AusReply", "12345678", NULL, 0, "symbology: 66," }, /* 50*/ { "AUS POST", "12345678901234567890123", NULL, 0, "symbology: 63," },
/* 51*/ { "AUSROUTE", "12345678", NULL, 0, "symbology: 67," }, /* 51*/ { "AusReply", "12345678", NULL, 0, "symbology: 66," },
/* 52*/ { "AUS REDIRECT", "12345678", NULL, 0, "symbology: 68," }, /* 52*/ { "AUSROUTE", "12345678", NULL, 0, "symbology: 67," },
/* 53*/ { "isbnx", "123456789", NULL, 0, "symbology: 69," }, /* 53*/ { "AUS REDIRECT", "12345678", NULL, 0, "symbology: 68," },
/* 54*/ { "rm4scc", "1", NULL, 0, "symbology: 70," }, /* 54*/ { "isbnx", "123456789", NULL, 0, "symbology: 69," },
/* 55*/ { "DataMatrix", "1", NULL, 0, "symbology: 71," }, /* 55*/ { "rm4scc", "1", NULL, 0, "symbology: 70," },
/* 56*/ { "EAN14", "1", NULL, 0, "symbology: 72," }, /* 56*/ { "DataMatrix", "1", NULL, 0, "symbology: 71," },
/* 57*/ { "vin", "12345678701234567", NULL, 0, "symbology: 73," }, /* 57*/ { "EAN14", "1", NULL, 0, "symbology: 72," },
/* 58*/ { "CodaBlock-F", "1", NULL, 0, "symbology: 74," }, /* 58*/ { "vin", "12345678701234567", NULL, 0, "symbology: 73," },
/* 59*/ { "NVE18", "1", NULL, 0, "symbology: 75," }, /* 59*/ { "CodaBlock-F", "1", NULL, 0, "symbology: 74," },
/* 60*/ { "Japan Post", "1", NULL, 0, "symbology: 76," }, /* 60*/ { "NVE18", "1", NULL, 0, "symbology: 75," },
/* 61*/ { "Korea Post", "1", NULL, 0, "symbology: 77," }, /* 61*/ { "Japan Post", "1", NULL, 0, "symbology: 76," },
/* 62*/ { "DBar Stk", "1", NULL, 0, "symbology: 79," }, /* 62*/ { "Korea Post", "1", NULL, 0, "symbology: 77," },
/* 63*/ { "DBar Omn Stk", "1", NULL, 0, "symbology: 80," }, /* 63*/ { "DBar Stk", "1", NULL, 0, "symbology: 79," },
/* 64*/ { "DBar Exp Stk", "[20]01", NULL, 0, "symbology: 81," }, /* 64*/ { "DBar Omn Stk", "1", NULL, 0, "symbology: 80," },
/* 65*/ { "planet", "12345678901", NULL, 0, "symbology: 82," }, /* 65*/ { "DBar Exp Stk", "[20]01", NULL, 0, "symbology: 81," },
/* 66*/ { "MicroPDF417", "1", NULL, 0, "symbology: 84," }, /* 66*/ { "planet", "12345678901", NULL, 0, "symbology: 82," },
/* 67*/ { "USPS IMail", "12345678901234567890", NULL, 0, "symbology: 85," }, /* 67*/ { "MicroPDF417", "1", NULL, 0, "symbology: 84," },
/* 68*/ { "plessey", "1", NULL, 0, "symbology: 86," }, /* 68*/ { "USPS IMail", "12345678901234567890", NULL, 0, "symbology: 85," },
/* 69*/ { "telepen num", "1", NULL, 0, "symbology: 87," }, /* 69*/ { "plessey", "1", NULL, 0, "symbology: 86," },
/* 70*/ { "ITF14", "1", NULL, 0, "symbology: 89," }, /* 70*/ { "telepen num", "1", NULL, 0, "symbology: 87," },
/* 71*/ { "KIX", "1", NULL, 0, "symbology: 90," }, /* 71*/ { "ITF14", "1", NULL, 0, "symbology: 89," },
/* 72*/ { "Aztec", "1", NULL, 0, "symbology: 92," }, /* 72*/ { "KIX", "1", NULL, 0, "symbology: 90," },
/* 73*/ { "daft", "D", NULL, 0, "symbology: 93," }, /* 73*/ { "Aztec", "1", NULL, 0, "symbology: 92," },
/* 74*/ { "DPD", "0123456789012345678901234567", NULL, 0, "symbology: 96," }, /* 74*/ { "daft", "D", NULL, 0, "symbology: 93," },
/* 75*/ { "Micro QR", "1", NULL, 0, "symbology: 97," }, /* 75*/ { "DPD", "0123456789012345678901234567", NULL, 0, "symbology: 96," },
/* 76*/ { "hibc128", "1", NULL, 0, "symbology: 98," }, /* 76*/ { "Micro QR", "1", NULL, 0, "symbology: 97," },
/* 77*/ { "hibccode128", "1", NULL, 0, "symbology: 98," }, // Synonym /* 77*/ { "hibc128", "1", NULL, 0, "symbology: 98," },
/* 78*/ { "hibc39", "1", NULL, 0, "symbology: 99," }, /* 78*/ { "hibccode128", "1", NULL, 0, "symbology: 98," }, // Synonym
/* 79*/ { "hibccode39", "1", NULL, 0, "symbology: 99," }, // Synonym /* 79*/ { "hibc39", "1", NULL, 0, "symbology: 99," },
/* 80*/ { "hibcdatamatrix", "1", NULL, 0, "symbology: 102," }, // Synonym /* 80*/ { "hibccode39", "1", NULL, 0, "symbology: 99," }, // Synonym
/* 81*/ { "hibcdm", "1", NULL, 0, "symbology: 102," }, /* 81*/ { "hibcdatamatrix", "1", NULL, 0, "symbology: 102," }, // Synonym
/* 82*/ { "HIBC qr", "1", NULL, 0, "symbology: 104," }, /* 82*/ { "hibcdm", "1", NULL, 0, "symbology: 102," },
/* 83*/ { "HIBC QR Code", "1", NULL, 0, "symbology: 104," }, // Synonym /* 83*/ { "HIBC qr", "1", NULL, 0, "symbology: 104," },
/* 84*/ { "HIBCPDF", "1", NULL, 0, "symbology: 106," }, /* 84*/ { "HIBC QR Code", "1", NULL, 0, "symbology: 104," }, // Synonym
/* 85*/ { "HIBCPDF417", "1", NULL, 0, "symbology: 106," }, // Synonym /* 85*/ { "HIBCPDF", "1", NULL, 0, "symbology: 106," },
/* 86*/ { "HIBCMICPDF", "1", NULL, 0, "symbology: 108," }, /* 86*/ { "HIBCPDF417", "1", NULL, 0, "symbology: 106," }, // Synonym
/* 87*/ { "HIBC Micro PDF", "1", NULL, 0, "symbology: 108," }, // Synonym /* 87*/ { "HIBCMICPDF", "1", NULL, 0, "symbology: 108," },
/* 88*/ { "HIBC Micro PDF417", "1", NULL, 0, "symbology: 108," }, // Synonym /* 88*/ { "HIBC Micro PDF", "1", NULL, 0, "symbology: 108," }, // Synonym
/* 89*/ { "HIBC BlockF", "1", NULL, 0, "symbology: 110," }, /* 89*/ { "HIBC Micro PDF417", "1", NULL, 0, "symbology: 108," }, // Synonym
/* 90*/ { "HIBC CodaBlock-F", "1", NULL, 0, "symbology: 110," }, // Synonym /* 90*/ { "HIBC BlockF", "1", NULL, 0, "symbology: 110," },
/* 91*/ { "HIBC Aztec", "1", NULL, 0, "symbology: 112," }, /* 91*/ { "HIBC CodaBlock-F", "1", NULL, 0, "symbology: 110," }, // Synonym
/* 92*/ { "DotCode", "1", NULL, 0, "symbology: 115," }, /* 92*/ { "HIBC Aztec", "1", NULL, 0, "symbology: 112," },
/* 93*/ { "Han Xin", "1", NULL, 0, "symbology: 116," }, /* 93*/ { "DotCode", "1", NULL, 0, "symbology: 115," },
/* 94*/ { "Mailmark", "01000000000000000AA00AA0A", NULL, 0, "symbology: 121," }, /* 94*/ { "Han Xin", "1", NULL, 0, "symbology: 116," },
/* 95*/ { "azrune", "1", NULL, 0, "symbology: 128," }, /* 95*/ { "Mailmark", "01000000000000000AA00AA0A", NULL, 0, "symbology: 121," },
/* 96*/ { "aztecrune", "1", NULL, 0, "symbology: 128," }, // Synonym /* 96*/ { "azrune", "1", NULL, 0, "symbology: 128," },
/* 97*/ { "aztecrunes", "1", NULL, 0, "symbology: 128," }, // Synonym /* 97*/ { "aztecrune", "1", NULL, 0, "symbology: 128," }, // Synonym
/* 98*/ { "code32", "1", NULL, 0, "symbology: 129," }, /* 98*/ { "aztecrunes", "1", NULL, 0, "symbology: 128," }, // Synonym
/* 99*/ { "eanx cc", "[20]01", "1234567890128", 0, "symbology: 130," }, /* 99*/ { "code32", "1", NULL, 0, "symbology: 129," },
/*100*/ { "eancc", "[20]01", "1234567890128", 0, "symbology: 130," }, /*100*/ { "eanx cc", "[20]01", "1234567890128", 0, "symbology: 130," },
/*101*/ { "GS1 128 CC", "[01]12345678901231", "[20]01", 0, "symbology: 131," }, /*101*/ { "eancc", "[20]01", "1234567890128", 0, "symbology: 130," },
/*102*/ { "dbaromncc", "[20]01", "1234567890123", 0, "symbology: 132," }, /*102*/ { "GS1 128 CC", "[01]12345678901231", "[20]01", 0, "symbology: 131," },
/*103*/ { "dbarltdcc", "[20]01", "1234567890123", 0, "symbology: 133," }, /*103*/ { "dbaromncc", "[20]01", "1234567890123", 0, "symbology: 132," },
/*104*/ { "dbarexpcc", "[20]01", "[01]12345678901231", 0, "symbology: 134," }, /*104*/ { "dbarltdcc", "[20]01", "1234567890123", 0, "symbology: 133," },
/*105*/ { "upcacc", "[20]01", "12345678901", 0, "symbology: 135," }, /*105*/ { "dbarexpcc", "[20]01", "[01]12345678901231", 0, "symbology: 134," },
/*106*/ { "upcecc", "[20]01", "1234567", 0, "symbology: 136," }, /*106*/ { "upcacc", "[20]01", "12345678901", 0, "symbology: 135," },
/*107*/ { "dbar stk cc", "[20]01", "1234567890123", 0, "symbology: 137," }, /*107*/ { "upcecc", "[20]01", "1234567", 0, "symbology: 136," },
/*108*/ { "dbaromnstkcc", "[20]01", "1234567890123", 0, "symbology: 138," }, /*108*/ { "dbar stk cc", "[20]01", "1234567890123", 0, "symbology: 137," },
/*109*/ { "dbarexpstkcc", "[20]01", "[01]12345678901231", 0, "symbology: 139," }, /*109*/ { "dbaromnstkcc", "[20]01", "1234567890123", 0, "symbology: 138," },
/*110*/ { "Channel", "1", NULL, 0, "symbology: 140," }, /*110*/ { "dbarexpstkcc", "[20]01", "[01]12345678901231", 0, "symbology: 139," },
/*111*/ { "CodeOne", "1", NULL, 0, "symbology: 141," }, /*111*/ { "Channel", "1", NULL, 0, "symbology: 140," },
/*112*/ { "Grid Matrix", "1", NULL, 0, "symbology: 142," }, /*112*/ { "CodeOne", "1", NULL, 0, "symbology: 141," },
/*113*/ { "UPN QR", "1", NULL, 0, "symbology: 143," }, /*113*/ { "Grid Matrix", "1", NULL, 0, "symbology: 142," },
/*114*/ { "UPN QR Code", "1", NULL, 0, "symbology: 143," }, // Synonym /*114*/ { "UPN QR", "1", NULL, 0, "symbology: 143," },
/*115*/ { "ultra", "1", NULL, 0, "symbology: 144," }, /*115*/ { "UPN QR Code", "1", NULL, 0, "symbology: 143," }, // Synonym
/*116*/ { "ultracode", "1", NULL, 0, "symbology: 144," }, // Synonym /*116*/ { "ultra", "1", NULL, 0, "symbology: 144," },
/*117*/ { "rMQR", "1", NULL, 0, "symbology: 145," }, /*117*/ { "ultracode", "1", NULL, 0, "symbology: 144," }, // Synonym
/*118*/ { "x", "1", NULL, 1, "Error 119: Invalid barcode type 'x'" }, /*118*/ { "rMQR", "1", NULL, 0, "symbology: 145," },
/*119*/ { "\177", "1", NULL, 1, "Error 119: Invalid barcode type '\177'" }, /*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); int data_size = ARRAY_SIZE(data);
char cmd[4096]; char cmd[4096];
char buf[8192]; char buf[8192];
char *outfilename = "out.png"; char *outfilename = "out.gif";
for (int i = 0; i < data_size; i++) { for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue; if (index != -1 && i != index) continue;
strcpy(cmd, "zint "); strcpy(cmd, "zint --filetype=gif");
strcat(cmd, " --verbose"); strcat(cmd, " --verbose");
arg_data(cmd, "-b ", data[i].bname); 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(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); 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) { 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);
} }
} }

View File

@ -32,10 +32,20 @@
<property name="buddy" > <property name="buddy" >
<cstring>cmbMSICheck</cstring> <cstring>cmbMSICheck</cstring>
</property> </property>
<property name="toolTip">
<string>Mod-10 uses Luhn algorithm
Mod-11 (IBM) uses IBM weightings
Mod-11 (NCR) uses NCR weightings</string>
</property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QComboBox" name="cmbMSICheck" > <widget class="QComboBox" name="cmbMSICheck" >
<property name="toolTip">
<string>Mod-10 uses Luhn algorithm
Mod-11 (IBM) uses IBM weightings
Mod-11 (NCR) uses NCR weightings</string>
</property>
<item> <item>
<property name="text" > <property name="text" >
<string>None</string> <string>None</string>
@ -53,18 +63,41 @@
</item> </item>
<item> <item>
<property name="text" > <property name="text" >
<string>Mod-11</string> <string>Mod-11 (IBM)</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text" > <property name="text" >
<string>Mod-11 &amp; Mod-10</string> <string>Mod-11 (IBM) &amp; Mod-10</string>
</property>
</item>
<item>
<property name="text" >
<string>Mod-11 (NCR)</string>
</property>
</item>
<item>
<property name="text" >
<string>Mod-11 (NCR) &amp; Mod-10</string>
</property> </property>
</item> </item>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="QCheckBox" name="chkMSICheckText">
<property name="text">
<string>Do not show check digit(s) in &amp;Text</string>
</property>
<property name="toolTip">
<string>Add check digit(s) but do not display in Human Readable Text</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer" > <spacer name="verticalSpacer" >
<property name="orientation" > <property name="orientation" >

View File

@ -594,8 +594,8 @@ p, li { white-space: pre-wrap; }
<item> <item>
<widget class="QCheckBox" name="chkGS1Parens"> <widget class="QCheckBox" name="chkGS1Parens">
<property name="toolTip"> <property name="toolTip">
<string>Use parentheses "()" instead of square brackets "[]" <string>Process parentheses "()" instead of square brackets "[]"
to delimit GS1 application identifiers as GS1 application identifiers delimiters
(ignored if disabled)</string> (ignored if disabled)</string>
</property> </property>
<property name="text"> <property name="text">

View File

@ -62,11 +62,11 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags fl)
"Codablock-F (and HIBC)", "Codablock-F (and HIBC)",
"Code 11", "Code 11",
"Code 128 (ISO 15417) (and GS1-128 and HIBC)", "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 Data Logic",
"Code 2 of 5 IATA", "Code 2 of 5 IATA",
"Code 2 of 5 Industrial", "Code 2 of 5 Industrial",
"Code 2 of 5 Interleaved", "Code 2 of 5 Interleaved (ISO 16390)",
"Code 2 of 5 Standard (Matrix)", "Code 2 of 5 Standard (Matrix)",
"Code 32 (Italian Pharmacode)", "Code 32 (Italian Pharmacode)",
"Code 39 (ISO 16388) (and HIBC)", "Code 39 (ISO 16388) (and HIBC)",
@ -488,11 +488,11 @@ void MainWindow::on_encoded()
void MainWindow::filter_symbologies() void MainWindow::filter_symbologies()
{ {
QString filter = filter_bstyle->text().simplified(); /* `simplified()` trims and reduces inner whitespace to a single space - nice! */ QString filter = filter_bstyle->text().simplified(); /* `simplified()` trims and reduces inner whitespace to a single space - nice! */
QListView *view = qobject_cast<QListView *>(bstyle->view()); QListView *lview = qobject_cast<QListView *>(bstyle->view());
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(bstyle->model()); QStandardItemModel *model = qobject_cast<QStandardItemModel*>(bstyle->model());
QStandardItem *item; QStandardItem *item;
if (!view || !model) { if (!lview || !model) {
return; return;
} }
@ -510,7 +510,7 @@ void MainWindow::filter_symbologies()
if (filter_cnt) { if (filter_cnt) {
for (int i = 0; i < cnt; i++) { for (int i = 0; i < cnt; i++) {
bool hidden = view->isRowHidden(i); bool hidden = lview->isRowHidden(i);
bool hide = true; bool hide = true;
for (int j = 0; j < filter_cnt; j++) { for (int j = 0; j < filter_cnt; j++) {
if (bstyle->itemText(i).contains(filter_list[j], Qt::CaseInsensitive)) { 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 // https://stackoverflow.com/questions/25172220/how-to-hide-qcombobox-items-instead-of-clearing-them-out
item = model->item(i); item = model->item(i);
item->setFlags(hide ? item->flags() & ~Qt::ItemIsEnabled : item->flags() | Qt::ItemIsEnabled); item->setFlags(hide ? item->flags() & ~Qt::ItemIsEnabled : item->flags() | Qt::ItemIsEnabled);
view->setRowHidden(i, hide); lview->setRowHidden(i, hide);
} }
} }
} else { } else {
for (int i = 0; i < cnt; i++) { for (int i = 0; i < cnt; i++) {
if (view->isRowHidden(i)) { if (lview->isRowHidden(i)) {
item = model->item(i); item = model->item(i);
item->setFlags(item->flags() | Qt::ItemIsEnabled); 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; return;
} }
QMimeData *data = new QMimeData; QMimeData *mdata = new QMimeData;
data->setImageData(QImage(filename)); mdata->setImageData(QImage(filename));
clipboard->setMimeData(data, QClipboard::Clipboard); clipboard->setMimeData(mdata, QClipboard::Clipboard);
QFile::remove(filename); QFile::remove(filename);
@ -584,9 +584,9 @@ void MainWindow::copy_to_clipboard_bmp()
return; return;
} }
QMimeData *data = new QMimeData; QMimeData *mdata = new QMimeData;
data->setImageData(QImage(filename)); mdata->setImageData(QImage(filename));
clipboard->setMimeData(data, QClipboard::Clipboard); clipboard->setMimeData(mdata, QClipboard::Clipboard);
QFile::remove(filename); QFile::remove(filename);
} }
@ -689,6 +689,8 @@ void MainWindow::change_options()
file.close(); file.close();
tabMain->insertTab(1, m_optionWidget, tr("MSI Pless&ey")); tabMain->insertTab(1, m_optionWidget, tr("MSI Pless&ey"));
connect(m_optionWidget->findChild<QObject*>("cmbMSICheck"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(m_optionWidget->findChild<QObject*>("cmbMSICheck"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("cmbMSICheck"), SIGNAL(currentIndexChanged( int )), SLOT(msi_plessey_ui_set()));
connect(m_optionWidget->findChild<QObject*>("chkMSICheckText"), SIGNAL(clicked( bool )), SLOT(update_preview()));
} else if (symbology == BARCODE_CODE11) { } else if (symbology == BARCODE_CODE11) {
QFile file(":/grpC11.ui"); 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<QCheckBox*>("chkMSICheckText") : nullptr;
if (checkBox) {
checkBox->setEnabled(get_combobox_index("cmbMSICheck") > 0);
}
}
// Taken from https://stackoverflow.com/questions/38915001/disable-specific-items-in-qcombobox // Taken from https://stackoverflow.com/questions/38915001/disable-specific-items-in-qcombobox
void MainWindow::combobox_item_enabled(QComboBox *comboBox, int index, bool enabled) void MainWindow::combobox_item_enabled(QComboBox *comboBox, int index, bool enabled)
{ {
@ -1280,7 +1292,11 @@ void MainWindow::update_preview()
case BARCODE_MSI_PLESSEY: case BARCODE_MSI_PLESSEY:
m_bc.bc.setSymbol(BARCODE_MSI_PLESSEY); m_bc.bc.setSymbol(BARCODE_MSI_PLESSEY);
m_bc.bc.setOption2(m_optionWidget->findChild<QComboBox*>("cmbMSICheck")->currentIndex()); item_val = get_combobox_index("cmbMSICheck");
if (item_val && m_optionWidget->findChild<QCheckBox*>("chkMSICheckText")->isChecked()) {
item_val += 10;
}
m_bc.bc.setOption2(item_val);
break; break;
case BARCODE_CODE11: case BARCODE_CODE11:
@ -1614,7 +1630,7 @@ const char *MainWindow::get_setting_name(int symbology) {
int define; int define;
int val; int val;
}; };
static const struct item data[] = { static const struct item ndata[] = {
{ "", -1, 0 }, { "", -1, 0 },
{ "code11", BARCODE_CODE11, 1 }, { "code11", BARCODE_CODE11, 1 },
{ "c25standard", BARCODE_C25STANDARD, 2 }, { "c25standard", BARCODE_C25STANDARD, 2 },
@ -1762,16 +1778,16 @@ const char *MainWindow::get_setting_name(int symbology) {
{ "ultra", BARCODE_ULTRA, 144 }, { "ultra", BARCODE_ULTRA, 144 },
{ "rmqr", BARCODE_RMQR, 145 }, { "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) { if (symbology < 0 || symbology >= data_size) {
return ""; return "";
} }
if (data[symbology].val != symbology || (data[symbology].define != -1 && data[symbology].define != symbology)) { // Self-check if (ndata[symbology].val != symbology || (ndata[symbology].define != -1 && ndata[symbology].define != symbology)) { // Self-check
fprintf(stderr, "MainWindow::get_setting_name: data table out of sync (%d)\n", symbology); fprintf(stderr, "MainWindow::get_setting_name: ndata table out of sync (%d)\n", symbology);
return ""; return "";
} }
return data[symbology].name; return ndata[symbology].name;
} }
/* Helper to return index of selected radio button in group, checking for NULL */ /* 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: case BARCODE_MSI_PLESSEY:
settings.setValue("studio/bc/msi_plessey/check_digit", get_combobox_index("cmbMSICheck")); 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; break;
case BARCODE_CODE11: case BARCODE_CODE11:
@ -2106,9 +2123,9 @@ void MainWindow::load_sub_settings(QSettings &settings, int symbology) {
const char *name = get_setting_name(symbology); const char *name = get_setting_name(symbology);
if (*name) { if (*name) {
const QString &data = settings.value(QString("studio/bc/%1/data").arg(name), "").toString(); const QString &tdata = settings.value(QString("studio/bc/%1/data").arg(name), "").toString();
if (!data.isEmpty()) { if (!tdata.isEmpty()) {
txtData->setText(data); txtData->setText(tdata);
} }
if (!grpComposite->isHidden()) { if (!grpComposite->isHidden()) {
const QString &composite_text = settings.value(QString("studio/bc/%1/composite_text").arg(name), "").toString(); 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: case BARCODE_MSI_PLESSEY:
set_combobox_from_setting(settings, "studio/bc/msi_plessey/check_digit", "cmbMSICheck"); 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; break;
case BARCODE_CODE11: case BARCODE_CODE11:

View File

@ -122,6 +122,7 @@ public slots:
void composite_ui_set(); void composite_ui_set();
void composite_ean_check(); void composite_ean_check();
void maxi_primary(); void maxi_primary();
void msi_plessey_ui_set();
void change_print_scale(); void change_print_scale();
void change_cmyk(); void change_cmyk();
void autoheight_ui_set(); void autoheight_ui_set();

View File

@ -16,6 +16,12 @@
***************************************************************************/ ***************************************************************************/
/* vim: set ts=4 sw=4 et : */ /* 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 <QDebug> //#include <QDebug>
#include "qzint.h" #include "qzint.h"
#include <stdio.h> #include <stdio.h>

View File

@ -31,6 +31,7 @@ First build zlib:
cd zlib cd zlib
nmake -f win32\Makefile.msc clean
nmake -f win32\Makefile.msc LOC="-DASMV -DASMINF=" OBJA="inffas32.obj match686.obj" nmake -f win32\Makefile.msc LOC="-DASMV -DASMINF=" OBJA="inffas32.obj match686.obj"
cd .. cd ..
@ -39,14 +40,9 @@ and then lpng:
cd lpng cd lpng
cmake -G"Visual Studio 15 2017"^ cmake -G "Visual Studio 15 2017" -DCMAKE_BUILD_TYPE=Release^
-DCMAKE_BUILD_TYPE=Release^ -DPNG_BUILD_ZLIB=ON -DZLIB_INCLUDE_DIRS=..\zlib^
-DPNG_BUILD_ZLIB=ON^ -DPNG_STATIC=ON -DPNG_SHARED=OFF -B build
-DZLIB_INCLUDE_DIRS=..\zlib^
-DPNG_STATIC=ON^
-DPNG_SHARED=OFF^
-H.^
-Bbuild
cmake --build build --config Release cmake --build build --config Release
@ -91,21 +87,104 @@ You should now be able to run Zint Studio:
zint\frontend_qt\release\qtZint 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 Visual Studio 2015
------------------ ------------------
The solution and project files for Visual Studio 2015 have been moved to the 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 sub-directory vs2015. The steps are almost the same as for Visual Studio 2017,
above and adapting the settings from the Visual Studio 2017 project files (and except that "rc.exe" may not be available. If so, you need to install a Windows
adding any sources missing), they should be pretty serviceable. 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 For information on building a standalone version of Zint Studio using Visual
Studio 2015, see "frontend_qt/howto_build_qzint_using_msvs2015.txt" 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 Visual C++ 6
------------ ------------
The zint library and command line tool can be built using VC6.
See "win32\zint_cmdline_vc6\readme.txt" 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) Using the Qt Maintenance Tool (see the Visual Studio 2017 instructions above)
install the "MinGW 7.3.0 32-bit" component. install the "MinGW 7.3.0 32-bit" component.
(Note the Qt MinGW version does not necessarily have to match the version of (Note the Qt MinGW versions actually refer to Mingw-w64, the 64-bit fork of
MinGW installed, but the closer the better). 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) 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: Go into the directory you want to use and clone zint and libpng:
PROJECT_DIR="<project-directory>" cd <project-directory>
cd ${PROJECT_DIR} PROJECT_DIR="$(pwd)"
git clone https://git.code.sf.net/p/zint/code zint git clone https://git.code.sf.net/p/zint/code zint
git clone https://git.code.sf.net/p/libpng/code lpng 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 sed -i 's/\r//' pnglibconf.h
(ignore "preserving permissions" warning if any)
And then do the make again: And then do the make again:
make make

View File

@ -243,11 +243,11 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
> >
<File <File
RelativePath="..\frontend\getopt.c" RelativePath="..\getopt\getopt.c"
> >
</File> </File>
<File <File
RelativePath="..\frontend\getopt1.c" RelativePath="..\getopt\getopt1.c"
> >
</File> </File>
<File <File
@ -261,7 +261,7 @@
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
> >
<File <File
RelativePath=".\frontend\getopt.h" RelativePath=".\getopt\getopt.h"
> >
</File> </File>
<File <File

View File

@ -95,6 +95,7 @@
<OutDir>$(SolutionDir)$(Configuration)\</OutDir> <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir> <IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<TargetName>zintd</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
@ -103,6 +104,7 @@
<OutDir>$(SolutionDir)$(Configuration)\</OutDir> <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir> <IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<TargetName>zint</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>

View File

@ -224,13 +224,13 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\frontend\getopt.c" /> <ClCompile Include="..\..\getopt\getopt.c" />
<ClCompile Include="..\..\frontend\getopt1.c" /> <ClCompile Include="..\..\getopt\getopt1.c" />
<ClCompile Include="..\..\frontend\main.c" /> <ClCompile Include="..\..\frontend\main.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\frontend\resource.h" /> <ClInclude Include="..\..\frontend\resource.h" />
<ClInclude Include="..\..\frontend\getopt.h" /> <ClInclude Include="..\..\getopt\getopt.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\..\frontend\zint.rc" /> <ResourceCompile Include="..\..\frontend\zint.rc" />

View File

@ -84,13 +84,13 @@
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\frontend\getopt.c" /> <ClCompile Include="..\..\getopt\getopt.c" />
<ClCompile Include="..\..\frontend\getopt1.c" /> <ClCompile Include="..\..\getopt\getopt1.c" />
<ClCompile Include="..\..\frontend\main.c" /> <ClCompile Include="..\..\frontend\main.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\frontend\resource.h" /> <ClInclude Include="..\..\frontend\resource.h" />
<ClInclude Include="..\..\frontend\getopt.h" /> <ClInclude Include="..\..\getopt\getopt.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\..\frontend\zint.rc" /> <ResourceCompile Include="..\..\frontend\zint.rc" />

View File

@ -84,13 +84,13 @@
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\frontend\getopt.c" /> <ClCompile Include="..\getopt\getopt.c" />
<ClCompile Include="..\frontend\getopt1.c" /> <ClCompile Include="..\getopt\getopt1.c" />
<ClCompile Include="..\frontend\main.c" /> <ClCompile Include="..\frontend\main.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\frontend\resource.h" /> <ClInclude Include="..\frontend\resource.h" />
<ClInclude Include="frontend\getopt.h" /> <ClInclude Include="..\getopt\getopt.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\frontend\zint.rc" /> <ResourceCompile Include="..\frontend\zint.rc" />

View File

@ -1,5 +1,5 @@
Harald Oehlmann Harald Oehlmann
2016-01-12 2021-06-10
Why to use VC6 ? Why to use VC6 ?
It avoids DLL Hell as the runtime is present on all Windows Versions since XP. 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: 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 * 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 cd $ZR\..\zlib
nmake -f win32\Makefile.msc nmake -f win32\Makefile.msc
-> generates zlib.lib, zlib1.dll -> generates zlib.lib, zlib1.dll
-> generates $ZR\..\lpng\libpng.lib
b) lpng (current version: 1.6.20) b) lpng (current version: 1.6.37)
* put libpng to $ZR/../lpng * put libpng to $ZR\..\lpng
cd $ZR\..\lpng cd $ZR\..\lpng
nmake -f scripts\makefile.vcwin32 nmake -f scripts\makefile.vcwin32
-> generates $ZR\..\lpng\libpng.lib -> generates $ZR\..\lpng\libpng.lib
c) open the files in this folder with the msvc6 gui and compile
c) open zint_cmdline_vc6.dsp in this folder with the msvc6 gui and compile

View File

@ -164,11 +164,11 @@ SOURCE=..\..\backend\general_field.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\frontend\getopt.c SOURCE=..\..\getopt\getopt.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\frontend\getopt1.c SOURCE=..\..\getopt\getopt1.c
# End Source File # End Source File
# Begin Source File # Begin Source File