| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- /*
- libzint - the open source barcode library
- Copyright (C) 2023-2024 Robin Stuart <rstuart114@gmail.com>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the project nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- */
- /* SPDX-License-Identifier: BSD-3-Clause */
- #include <errno.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <locale.h>
- #include <math.h>
- #include <sys/stat.h>
- #include "testcommon.h"
- #include "../common.h"
- #include "../filemem.h"
- static void test_svg(const testCtx *const p_ctx) {
- int debug = p_ctx->debug;
- struct item {
- int symbology;
- int output_options;
- char *outfile;
- char *data;
- int length;
- int ret;
- char *expected;
- };
- /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */
- struct item data[] = {
- /* 0*/ { BARCODE_CODE128, BARCODE_MEMORY_FILE, "out.svg", "ABCDEF", -1, 0,
- "<?xml version=\"1.0\" standalone=\"no\"?>\n"
- "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
- "<svg width=\"202\" height=\"117\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n"
- " <desc>Zint Generated Symbol</desc>\n"
- " <g id=\"barcode\" fill=\"#000000\">\n"
- " <rect x=\"0\" y=\"0\" width=\"202\" height=\"117\" fill=\"#FFFFFF\"/>\n"
- " <path d=\"M0 0h4v100h-4ZM6 0h2v100h-2ZM12 0h2v100h-2ZM22 0h2v100h-2ZM26 0h2v100h-2ZM34 0h4v100h-4ZM44 0h2v100h-2ZM52 0h2v100h-2ZM56 0h4v100h-4ZM66 0h2v100h-2ZM74 0h2v100h-2ZM82 0h4v100h-4ZM88 0h2v100h-2ZM92 0h4v100h-4ZM102 0h2v100h-2ZM110 0h2v100h-2ZM118 0h4v100h-4ZM124 0h2v100h-2ZM132 0h2v100h-2ZM140 0h4v100h-4ZM150 0h2v100h-2ZM154 0h2v100h-2ZM158 0h4v100h-4ZM168 0h6v100h-6ZM176 0h4v100h-4ZM186 0h6v100h-6ZM194 0h2v100h-2ZM198 0h4v100h-4Z\"/>\n"
- " <text x=\"101\" y=\"113.34\" text-anchor=\"middle\" font-family=\"Arimo, Arial, sans-serif\" font-size=\"14\">\n"
- " ABCDEF\n"
- " </text>\n"
- " </g>\n"
- "</svg>\n"
- },
- };
- int data_size = ARRAY_SIZE(data);
- int i, length, ret;
- struct zint_symbol *symbol = NULL;
- testStartSymbol("test_svg", &symbol);
- for (i = 0; i < data_size; i++) {
- if (testContinue(p_ctx, i)) continue;
- symbol = ZBarcode_Create();
- assert_nonnull(symbol, "Symbol not created\n");
- length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, data[i].output_options, data[i].data, data[i].length, debug);
- strcpy(symbol->outfile, data[i].outfile);
- ret = ZBarcode_Encode_and_Print(symbol, TU(data[i].data), length, 0);
- assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_and_Print(%d) ret %d != %d (%s)\n",
- i, data[i].symbology, ret, data[i].ret, symbol->errtxt);
- if (ret < ZINT_ERROR) {
- const int expected_size = (int) strlen(data[i].expected);
- assert_nonnull(symbol->memfile, "i:%d memfile NULL (%s)\n", i, symbol->errtxt);
- assert_equal(symbol->memfile_size, expected_size, "i:%d memfile_size %d != %d (%s)\n",
- i, symbol->memfile_size, expected_size, symbol->errtxt);
- ret = memcmp(symbol->memfile, data[i].expected, symbol->memfile_size);
- assert_zero(ret, "i:%d memcmp() %d != 0\n", i, ret);
- } else {
- assert_null(symbol->memfile, "i:%d memfile != NULL (%s)\n", i, symbol->errtxt);
- assert_zero(symbol->memfile_size, "i:%d memfile_size != 0 (%s)\n", i, symbol->errtxt);
- }
- ZBarcode_Delete(symbol);
- }
- testFinish();
- }
- #if defined(_WIN32) || (defined(__sun) && defined(__SVR4))
- #define ZINT_TEST_NO_FMEMOPEN
- #endif
- #ifndef ZINT_TEST_NO_FMEMOPEN
- extern FILE *fmemopen(void *buf, size_t size, const char *mode);
- #endif
- static void test_putsf(const testCtx *const p_ctx) {
- int debug = p_ctx->debug;
- struct item {
- const char *prefix;
- int dp;
- float arg;
- const char *locale;
- const char *expected;
- };
- /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */
- struct item data[] = {
- /* 0*/ { "", 2, 1234.123, "", "1234.12" },
- /* 1*/ { "", 3, 1234.123, "", "1234.123" },
- /* 2*/ { "prefix ", 4, 1234.123, "", "prefix 1234.123" },
- /* 3*/ { "", 2, -1234.126, "", "-1234.13" },
- /* 4*/ { "", 2, 1234.1, "", "1234.1" },
- /* 5*/ { "", 3, 1234.1, "", "1234.1" },
- /* 6*/ { "", 4, 1234.1, "", "1234.1" },
- /* 7*/ { "", 2, 1234.0, "", "1234" },
- /* 8*/ { "", 2, -1234.0, "", "-1234" },
- /* 9*/ { "", 3, 1234.1234, "de_DE.UTF-8", "1234.123" },
- /* 10*/ { "", 4, -1234.1234, "de_DE.UTF-8", "-1234.1234" },
- /* 11*/ { "prefix ", 4, -1234.1234, "de_DE.UTF-8", "prefix -1234.1234" },
- };
- int data_size = ARRAY_SIZE(data);
- int i, j;
- struct zint_symbol symbol_data = {0};
- struct zint_symbol *const symbol = &symbol_data;
- struct filemem fm;
- struct filemem *const fmp = &fm;
- #ifndef ZINT_TEST_NO_FMEMOPEN
- FILE *fp;
- char buf[512] = {0}; /* Suppress clang-16/17 run-time exception MemorySanitizer: use-of-uninitialized-value */
- #endif
- testStart("test_putsf");
- for (j = 0; j < 2; j++) { /* 1st `memfile`, then file */
- #ifdef ZINT_TEST_NO_FMEMOPEN
- if (j == 1) break; /* Skip file test on Windows/Solaris */
- #endif
- for (i = 0; i < data_size; i++) {
- const char *locale = NULL;
- int expected_size;
- if (testContinue(p_ctx, i)) continue;
- ZBarcode_Reset(symbol);
- if (j == 1) {
- #ifndef ZINT_TEST_NO_FMEMOPEN
- buf[0] = '\0';
- fp = fmemopen(buf, sizeof(buf), "w");
- assert_nonnull(fp, "%d: fmemopen fail (%d, %s)\n", i, errno, strerror(errno));
- #endif
- } else {
- symbol->output_options |= BARCODE_MEMORY_FILE;
- }
- assert_nonzero(fm_open(fmp, symbol, "w"), "i:%d: fm_open fail (%d, %s)\n", i, fmp->err, strerror(fmp->err));
- if (j == 1) {
- #ifndef ZINT_TEST_NO_FMEMOPEN
- /* Hack in `fmemopen()` fp */
- assert_zero(fclose(fmp->fp), "i:%d fclose(fmp->fp) fail (%d, %s)\n", i, errno, strerror(errno));
- fmp->fp = fp;
- #endif
- }
- if (data[i].locale && data[i].locale[0]) {
- locale = setlocale(LC_ALL, data[i].locale);
- if (!locale) { /* May not be available - warn unless quiet mode */
- if (!(debug & ZINT_DEBUG_TEST_LESS_NOISY)) {
- printf("i:%d: Warning: locale \"%s\" not available\n", i, data[i].locale);
- }
- }
- }
- fm_putsf(data[i].prefix, data[i].dp, data[i].arg, fmp);
- assert_nonzero(fm_close(fmp, symbol), "i:%d: fm_close fail (%d, %s)\n", i, fmp->err, strerror(fmp->err));
- if (locale) {
- assert_nonnull(setlocale(LC_ALL, locale), "i:%d: setlocale(%s) restore fail (%d, %s)\n",
- i, locale, errno, strerror(errno));
- }
- if (j == 1) {
- #ifndef ZINT_TEST_NO_FMEMOPEN
- assert_zero(strcmp(buf, data[i].expected), "%d: strcmp(%s, %s) != 0\n", i, buf, data[i].expected);
- #endif
- } else {
- expected_size = (int) strlen(data[i].expected);
- assert_equal(symbol->memfile_size, expected_size, "i:%d: memfile_size %d != expected_size %d\n",
- i, symbol->memfile_size, expected_size);
- assert_nonnull(symbol->memfile, "i:%d memfile NULL\n", i);
- assert_zero(memcmp(symbol->memfile, data[i].expected, expected_size), "i:%d: memcmp(%.*s, %.*s) != 0\n",
- i, symbol->memfile_size, symbol->memfile, expected_size, data[i].expected);
- }
- ZBarcode_Clear(symbol);
- }
- }
- testFinish();
- }
- static void test_printf(const testCtx *const p_ctx) {
- int debug = p_ctx->debug;
- int ret;
- int j;
- struct zint_symbol symbol_data = {0};
- struct zint_symbol *const symbol = &symbol_data;
- struct filemem fm;
- struct filemem *const fmp = &fm;
- const char outfile[] = "test_printf.tst";
- unsigned char filebuf[32768];
- int filebuf_size;
- const char fmt1[] = "\n%s%04d\n\032\nwow\n\r\n%.2s\n"; /* '\032' SUB (^Z) */
- const char expected1[] = "\ngosh0123\n\032\nwow\n\r\nge\n";
- #ifdef _WIN32
- /* On Windows, non-binary (i.e. text) files, LF -> LF+CR (note, actual files only, not memfiles) */
- const char expected1_text_file[] = "\r\ngosh0123\r\n\032\r\nwow\r\n\r\r\nge\r\n";
- #endif
- const char *expected;
- int expected_size;
- (void)debug;
- testStart("test_printf");
- for (j = 0; j < 2; j++) { /* 1st memfile, then file */
- ZBarcode_Reset(symbol);
- /* Binary */
- expected = expected1;
- if (j == 1) {
- strcpy(symbol->outfile, outfile);
- } else {
- symbol->output_options |= BARCODE_MEMORY_FILE;
- }
- ret = fm_open(fmp, symbol, "wb");
- assert_equal(ret, 1, "fm_open ret %d != 1\n", ret);
- ret = fm_printf(fmp, fmt1, "gosh", 123, "gee");
- assert_equal(ret, 1, "fm_printf ret %d != 1\n", ret);
- ret = fm_close(fmp, symbol);
- assert_equal(ret, 1, "fm_close ret %d != 1\n", ret);
- expected_size = (int) strlen(expected);
- if (j == 1) {
- ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size);
- assert_zero(ret, "testUtilReadFile(%s) %d != 0\n", symbol->outfile, ret);
- assert_equal((int) filebuf_size, expected_size, "filebuf_size %d != %d\n", filebuf_size, expected_size);
- assert_zero(memcmp(filebuf, expected, filebuf_size), "memcmp(%.*s, %s) != 0\n",
- filebuf_size, filebuf, expected);
- if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) {
- assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile);
- }
- } else {
- assert_nonnull(symbol->memfile, "memfile NULL (%d: %s)\n", fmp->err, strerror(fmp->err));
- assert_equal(symbol->memfile_size, expected_size, "mempos %d != %d\n",
- symbol->memfile_size, expected_size);
- assert_zero(memcmp(symbol->memfile, expected, symbol->memfile_size), "memcmp(%.*s, %s) != 0\n",
- symbol->memfile_size, symbol->memfile, expected);
- }
- /* Non-binary */
- expected = expected1;
- if (j == 1) {
- strcpy(symbol->outfile, outfile);
- #ifdef _WIN32
- expected = expected1_text_file;
- #endif
- } else {
- symbol->output_options |= BARCODE_MEMORY_FILE;
- }
- ret = fm_open(fmp, symbol, "w");
- assert_equal(ret, 1, "fm_open ret %d != 1\n", ret);
- ret = fm_printf(fmp, fmt1, "gosh", 123, "gee");
- assert_equal(ret, 1, "fm_printf ret %d != 1\n", ret);
- ret = fm_close(fmp, symbol);
- assert_equal(ret, 1, "fm_close ret %d != 1\n", ret);
- expected_size = (int) strlen(expected);
- if (j == 1) {
- ret = testUtilReadFile(symbol->outfile, filebuf, sizeof(filebuf), &filebuf_size);
- assert_zero(ret, "testUtilReadFile(%s) %d != 0\n", symbol->outfile, ret);
- assert_equal((int) filebuf_size, expected_size, "filebuf_size %d != %d\n", filebuf_size, expected_size);
- assert_zero(memcmp(filebuf, expected, filebuf_size), "memcmp(%.*s, %s) != 0\n",
- filebuf_size, filebuf, expected);
- if (!(debug & ZINT_DEBUG_TEST_KEEP_OUTFILE)) {
- assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile);
- }
- } else {
- assert_nonnull(symbol->memfile, "mem NULL (%d: %s)\n", fmp->err, strerror(fmp->err));
- assert_equal(symbol->memfile_size, expected_size, "mempos %d != %d\n",
- symbol->memfile_size, expected_size);
- assert_zero(memcmp(symbol->memfile, expected, symbol->memfile_size), "memcmp(%.*s, %s) != 0\n",
- symbol->memfile_size, symbol->memfile, expected);
- }
- ZBarcode_Clear(symbol);
- }
- testFinish();
- }
- static void test_seek(const testCtx *const p_ctx) {
- int debug = p_ctx->debug;
- int ret;
- int j;
- struct zint_symbol symbol_data = {0};
- struct zint_symbol *const symbol = &symbol_data;
- struct filemem fm;
- struct filemem *const fmp = &fm;
- const char outfile[] = "test_seek.tst";
- (void)debug;
- testStart("test_seek");
- for (j = 0; j < 2; j++) { /* 1st memfile, then file */
- ZBarcode_Reset(symbol);
- if (j == 1) {
- strcpy(symbol->outfile, outfile);
- } else {
- symbol->output_options |= BARCODE_MEMORY_FILE;
- }
- ret = fm_open(fmp, symbol, "wb");
- assert_equal(ret, 1, "j:%d fm_open ret %d != 1\n", j, ret);
- ret = fm_puts("1234567890", fmp);
- assert_equal(ret, 1, "j:%d fm_puts ret %d != 1\n", j, ret);
- if (j != 1) {
- assert_nonnull(fmp->mem, "mem NULL (%d: %s)\n", fmp->err, strerror(fmp->err));
- assert_equal(fmp->mempos, 10, "mempos %d != 10\n", (int) fmp->mempos);
- assert_zero(memcmp(fmp->mem, "1234567890", fmp->mempos), "memcmp fail\n");
- }
- ret = fm_seek(fmp, -10, SEEK_CUR);
- assert_equal(ret, 1, "j:%d fm_seek ret %d != 1 (%d: %s)\n", j, ret, fmp->err, strerror(fmp->err));
- ret = fm_error(fmp);
- assert_zero(ret, "j:%d fm_error ret %d != 0\n", j, ret);
- ret = (int) fm_tell(fmp);
- assert_zero(ret, "j:%d fm_tell ret %d != 0\n", j, ret);
- ret = fm_seek(fmp, 0, SEEK_END);
- assert_equal(ret, 1, "j:%d fm_seek ret %d != 1\n", j, ret);
- ret = fm_error(fmp);
- assert_zero(ret, "j:%d fm_error ret %d != 0\n", j, ret);
- ret = (int) fm_tell(fmp);
- assert_equal(ret, 10, "j:%d fm_tell ret %d != 10\n", j, ret);
- ret = fm_seek(fmp, -1, SEEK_SET);
- assert_zero(ret, "j:%d fm_seek ret %d != 1\n", j, ret);
- assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
- ret = fm_close(fmp, symbol);
- assert_zero(ret, "j:%d fm_close ret %d != 0\n", j, ret);
- assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
- if (j == 1) {
- assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile);
- }
- ret = fm_open(fmp, symbol, "wb");
- assert_equal(ret, 1, "j:%d fm_open ret %d != 1\n", j, ret);
- ret = fm_seek(fmp, LONG_MAX, SEEK_CUR);
- if (j == 1) { /* May work on some file systems */
- if (ret == 0) {
- assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
- }
- } else {
- assert_zero(ret, "j:%d fm_seek ret %d != 0\n", j, ret);
- assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
- }
- ret = fm_close(fmp, symbol);
- if (j == 1) { /* See above */
- if (ret == 0) {
- assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
- }
- } else {
- assert_zero(ret, "j:%d fm_close ret %d != 0\n", j, ret);
- assert_equal(fmp->err, EINVAL, "j:%d fmp->err %d (%s) != EINVAL\n", j, fmp->err, strerror(fmp->err));
- }
- if (j == 1) {
- assert_zero(testUtilRemove(symbol->outfile), "testUtilRemove(%s) != 0\n", symbol->outfile);
- }
- ZBarcode_Clear(symbol);
- }
- testFinish();
- }
- static void test_large(const testCtx *const p_ctx) {
- int debug = p_ctx->debug;
- int ret;
- struct zint_symbol *symbol = NULL;
- char data[] = "1";
- int expected_size = 354879;
- (void)debug;
- testStart("test_large");
- symbol = ZBarcode_Create();
- assert_nonnull(symbol, "Symbol not created\n");
- symbol->symbology = BARCODE_HANXIN;
- symbol->output_options |= BARCODE_MEMORY_FILE;
- strcpy(symbol->outfile, "out.gif"); /* Use GIF in case ZINT_NO_PNG */
- symbol->option_2 = 84;
- symbol->scale = 10.0f; /* Could go up to 86.5 (pixel buffer 0x3FB913B1, file size 8868579) but very very slow */
- ret = ZBarcode_Encode_and_Print(symbol, TU(data), -1, 0);
- assert_zero(ret, "ZBarcode_Encode_and_Print ret %d != 0 (%s)\n", ret, symbol->errtxt);
- assert_nonnull(symbol->memfile, "memfile NULL (%s)\n", symbol->errtxt);
- assert_equal(symbol->memfile_size, expected_size, "memfile_size %d != expected %d\n",
- symbol->memfile_size, expected_size);
- symbol->scale = 87.0f; /* Too large (pixel buffer > 1GB) */
- ret = ZBarcode_Print(symbol, 0);
- assert_equal(ret, ZINT_ERROR_MEMORY, "ZBarcode_Print ret %d != ZINT_ERROR_MEMORY (%s)\n", ret, symbol->errtxt);
- ZBarcode_Delete(symbol);
- testFinish();
- }
- int main(int argc, char *argv[]) {
- testFunction funcs[] = { /* name, func */
- { "test_svg", test_svg },
- { "test_putsf", test_putsf },
- { "test_printf", test_printf },
- { "test_seek", test_seek },
- { "test_large", test_large },
- };
- testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
- testReport();
- return 0;
- }
- /* vim: set ts=4 sw=4 et : */
|