large.c: replace binary_load/add() etc with uint64_t based large_load/add() etc for performance

This commit is contained in:
gitlost 2020-06-14 14:42:40 +01:00
parent 3690c19749
commit e8a238aad1
14 changed files with 1566 additions and 804 deletions

View File

@ -1200,7 +1200,7 @@ INTERNAL int code_one(struct zint_symbol *symbol, unsigned char source[], int le
if (symbol->option_2 == 9) {
/* Version S */
int codewords;
short int elreg[112];
large_int elreg;
unsigned int data[15], ecc[15];
int stream[30];
int block_width;
@ -1230,20 +1230,14 @@ INTERNAL int code_one(struct zint_symbol *symbol, unsigned char source[], int le
block_width = 2;
}
binary_load(elreg, (char *) source, length);
large_load_str_u64(&elreg, source, length);
for (i = 0; i < 15; i++) {
data[i] = 0;
ecc[i] = 0;
}
for (i = 0; i < codewords; i++) {
data[codewords - i - 1] += 1 * elreg[(i * 5)];
data[codewords - i - 1] += 2 * elreg[(i * 5) + 1];
data[codewords - i - 1] += 4 * elreg[(i * 5) + 2];
data[codewords - i - 1] += 8 * elreg[(i * 5) + 3];
data[codewords - i - 1] += 16 * elreg[(i * 5) + 4];
}
large_uint_array(&elreg, data, codewords, 5 /*bits*/);
rs_init_gf(0x25);
rs_init_code(codewords, 1);

View File

@ -59,7 +59,13 @@
#define INTERNAL __attribute__ ((visibility ("hidden")))
#else
#define INTERNAL
#endif /* defined(__GNUC__) && !defined(ZINT_TEST) */
#endif
#if defined(ZINT_TEST)
#define STATIC_UNLESS_ZINT_TEST
#else
#define STATIC_UNLESS_ZINT_TEST static
#endif
#ifdef __cplusplus
extern "C" {

View File

@ -34,7 +34,6 @@
/* The function "USPS_MSB_Math_CRC11GenerateFrameCheckSequence"
is Copyright (C) 2006 United States Postal Service */
#include <string.h>
#include <stdio.h>
#include "common.h"
#include "large.h"
@ -247,8 +246,9 @@ INTERNAL int imail(struct zint_symbol *symbol, unsigned char source[], int lengt
char data_pattern[200];
int error_number;
int i, j, read;
char zip[35], tracker[35], zip_adder[11], temp[2];
short int accum[112], x_reg[112], y_reg[112];
char zip[35], tracker[35], temp[2];
large_int accum;
large_int byte_array_reg;
unsigned char byte_array[13];
unsigned short usps_crc;
int codeword[10];
@ -315,184 +315,62 @@ INTERNAL int imail(struct zint_symbol *symbol, unsigned char source[], int lengt
/* Routing code first */
for (i = 0; i < 112; i++) {
accum[i] = 0;
}
for (read = 0; read < zip_len; read++) {
binary_multiply(accum, "10");
binary_load(x_reg, "0", 1);
for (i = 0; i < 4; i++) {
if (ctoi(zip[read]) & (0x01 << i)) x_reg[i] = 1;
}
binary_add(accum, x_reg);
}
large_load_str_u64(&accum, (unsigned char *) zip, zip_len);
/* add weight to routing code */
for (i = 0; i < 112; i++) {
x_reg[i] = accum[i];
}
if (zip_len > 9) {
strcpy(zip_adder, "1000100001");
} else {
if (zip_len > 5) {
strcpy(zip_adder, "100001");
} else {
if (zip_len > 0) {
strcpy(zip_adder, "1");
} else {
strcpy(zip_adder, "0");
large_add_u64(&accum, 1000100001);
} else if (zip_len > 5) {
large_add_u64(&accum, 100001);
} else if (zip_len > 0) {
large_add_u64(&accum, 1);
}
}
}
for (i = 0; i < 112; i++) {
accum[i] = 0;
}
for (read = 0, len = strlen(zip_adder); read < len; read++) {
binary_multiply(accum, "10");
binary_load(y_reg, "0", 1);
for (i = 0; i < 4; i++) {
if (ctoi(zip_adder[read]) & (0x01 << i)) y_reg[i] = 1;
}
binary_add(accum, y_reg);
}
binary_add(accum, x_reg);
/* tracking code */
/* multiply by 10 */
binary_multiply(accum, "10");
binary_load(y_reg, "0", 1);
large_mul_u64(&accum, 10);
/* add first digit of tracker */
for (i = 0; i < 4; i++) {
if (ctoi(tracker[0]) & (0x01 << i)) y_reg[i] = 1;
}
binary_add(accum, y_reg);
large_add_u64(&accum, ctoi(tracker[0]));
/* multiply by 5 */
binary_multiply(accum, "5");
binary_load(y_reg, "0", 1);
large_mul_u64(&accum, 5);
/* add second digit */
for (i = 0; i < 4; i++) {
if (ctoi(tracker[1]) & (0x01 << i)) y_reg[i] = 1;
}
binary_add(accum, y_reg);
large_add_u64(&accum, ctoi(tracker[1]));
/* and then the rest */
for (read = 2, len = strlen(tracker); read < len; read++) {
binary_multiply(accum, "10");
binary_load(y_reg, "0", 1);
for (i = 0; i < 4; i++) {
if (ctoi(tracker[read]) & (0x01 << i)) y_reg[i] = 1;
}
binary_add(accum, y_reg);
large_mul_u64(&accum, 10);
large_add_u64(&accum, ctoi(tracker[read]));
}
/* *** Step 2 - Generation of 11-bit CRC on Binary Data *** */
accum[103] = 0;
accum[102] = 0;
large_load(&byte_array_reg, &accum);
for (j = 0; j < 13; j++) {
i = 96 - (8 * j);
byte_array[j] = 0;
byte_array[j] += accum[i];
byte_array[j] += 2 * accum[i + 1];
byte_array[j] += 4 * accum[i + 2];
byte_array[j] += 8 * accum[i + 3];
byte_array[j] += 16 * accum[i + 4];
byte_array[j] += 32 * accum[i + 5];
byte_array[j] += 64 * accum[i + 6];
byte_array[j] += 128 * accum[i + 7];
}
large_unset_bit(&byte_array_reg, 102);
large_unset_bit(&byte_array_reg, 103);
large_uchar_array(&byte_array_reg, byte_array, 13, 8 /*bits*/);
usps_crc = USPS_MSB_Math_CRC11GenerateFrameCheckSequence(byte_array);
/* *** Step 3 - Conversion from Binary Data to Codewords *** */
/* start with codeword J which is base 636 */
for (i = 0; i < 112; i++) {
x_reg[i] = 0;
y_reg[i] = 0;
}
x_reg[101] = 1;
x_reg[98] = 1;
x_reg[97] = 1;
x_reg[96] = 1;
x_reg[95] = 1;
x_reg[94] = 1;
for (i = 92; i >= 0; i--) {
y_reg[i] = !islarger(x_reg, accum);
if (y_reg[i] == 1) {
binary_subtract(accum, x_reg);
}
shiftdown(x_reg);
}
codeword[9] = (accum[9] * 512) + (accum[8] * 256) + (accum[7] * 128) + (accum[6] * 64) +
(accum[5] * 32) + (accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) +
(accum[1] * 2) + accum[0];
codeword[9] = large_div_u64(&accum, 636);
/* then codewords I to B with base 1365 */
for (j = 8; j > 0; j--) {
for (i = 0; i < 112; i++) {
accum[i] = y_reg[i];
y_reg[i] = 0;
x_reg[i] = 0;
}
x_reg[101] = 1;
x_reg[99] = 1;
x_reg[97] = 1;
x_reg[95] = 1;
x_reg[93] = 1;
x_reg[91] = 1;
for (i = 91; i >= 0; i--) {
y_reg[i] = !islarger(x_reg, accum);
if (y_reg[i] == 1) {
binary_subtract(accum, x_reg);
}
shiftdown(x_reg);
codeword[j] = large_div_u64(&accum, 1365);
}
codeword[j] = (accum[10] * 1024) + (accum[9] * 512) + (accum[8] * 256) +
(accum[7] * 128) + (accum[6] * 64) + (accum[5] * 32) +
(accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) +
(accum[1] * 2) + accum[0];
}
codeword[0] = (y_reg[10] * 1024) + (y_reg[9] * 512) + (y_reg[8] * 256) +
(y_reg[7] * 128) + (y_reg[6] * 64) + (y_reg[5] * 32) +
(y_reg[4] * 16) + (y_reg[3] * 8) + (y_reg[2] * 4) +
(y_reg[1] * 2) + y_reg[0];
for (i = 0; i < 8; i++) {
if (codeword[i] == 1365) {
codeword[i] = 0;
codeword[i + 1]++;
}
}
codeword[0] = large_lo(&accum);
/* *** Step 4 - Inserting Additional Information into Codewords *** */

View File

@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -31,181 +31,287 @@
*/
/* vim: set ts=4 sw=4 et : */
/* `large_mul_u64()` and `large_div_u64()` are adapted from articles by F. W. Jacob
* https://www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
* "This article, along with any associated source code and files, is licensed under The BSD License"
* http://www.codeproject.com/Tips/785014/UInt-Division-Modulus
* "This article, along with any associated source code and files, is licensed under The BSD License"
*
* These in turn are based on Hacker's Delight (2nd Edition, 2012) by Henry S. Warren, Jr.
* "You are free to use, copy, and distribute any of the code on this web site, whether modified by you or not."
* https://web.archive.org/web/20190716204559/http://www.hackersdelight.org/permissions.htm
*
* `clz_u64()` and other bits and pieces are adapted from r128.h by Alan Hickman (fahickman)
* https://github.com/fahickman/r128/blob/master/r128.h
* "R128 is released into the public domain. See LICENSE for details." LICENSE is The Unlicense.
*/
#include <stdio.h>
#include <string.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
#include "common.h"
#include "large.h"
INTERNAL void binary_add(short int accumulator[], short int input_buffer[]) { /* Binary addition */
int i, carry;
carry = 0;
#define MASK32 0xFFFFFFFF
for (i = 0; i < 112; i++) {
int done = 0;
if (((input_buffer[i] == 0) && (accumulator[i] == 0))
&& ((carry == 0) && (done == 0))) {
accumulator[i] = 0;
carry = 0;
done = 1;
}
if (((input_buffer[i] == 0) && (accumulator[i] == 0))
&& ((carry == 1) && (done == 0))) {
accumulator[i] = 1;
carry = 0;
done = 1;
}
if (((input_buffer[i] == 0) && (accumulator[i] == 1))
&& ((carry == 0) && (done == 0))) {
accumulator[i] = 1;
carry = 0;
done = 1;
}
if (((input_buffer[i] == 0) && (accumulator[i] == 1))
&& ((carry == 1) && (done == 0))) {
accumulator[i] = 0;
carry = 1;
done = 1;
}
if (((input_buffer[i] == 1) && (accumulator[i] == 0))
&& ((carry == 0) && (done == 0))) {
accumulator[i] = 1;
carry = 0;
done = 1;
}
if (((input_buffer[i] == 1) && (accumulator[i] == 0))
&& ((carry == 1) && (done == 0))) {
accumulator[i] = 0;
carry = 1;
done = 1;
}
if (((input_buffer[i] == 1) && (accumulator[i] == 1))
&& ((carry == 0) && (done == 0))) {
accumulator[i] = 0;
carry = 1;
done = 1;
}
if (((input_buffer[i] == 1) && (accumulator[i] == 1))
&& ((carry == 1) && (done == 0))) {
accumulator[i] = 1;
carry = 1;
done = 1;
/* Convert decimal string `s` of (at most) length `length` to 64-bit and place in 128-bit `t` */
INTERNAL void large_load_str_u64(large_int *t, const unsigned char *s, int length) {
uint64_t val = 0;
const unsigned char *se = s + length;
for (; s < se && *s >= '0' && *s <= '9'; s++) {
val *= 10;
val += *s - '0';
}
t->lo = val;
t->hi = 0;
}
/* Add 128-bit `s` to 128-bit `t` */
INTERNAL void large_add(large_int *t, const large_int *s) {
t->lo += s->lo;
t->hi += s->hi + (t->lo < s->lo);
}
/* Add 64-bit `s` to 128-bit `t` */
INTERNAL void large_add_u64(large_int *t, uint64_t s) {
t->lo += s;
if (t->lo < s) {
t->hi++;
}
}
INTERNAL void binary_subtract(short int accumulator[], short int input_buffer[]) {
/* 2's compliment subtraction */
/* take input_buffer from accumulator and put answer in accumulator */
int i;
short int sub_buffer[112];
/* Subtract 64-bit `s` from 128-bit `t` */
INTERNAL void large_sub_u64(large_int *t, uint64_t s) {
uint64_t r = t->lo - s;
if (r > t->lo) {
t->hi--;
}
t->lo = r;
}
for (i = 0; i < 112; i++) {
if (input_buffer[i] == 0) {
sub_buffer[i] = 1;
/* Multiply 128-bit `t` by 64-bit `s`
* See Jacob `mult64to128()` and Warren Section 8-2
* Note '0' denotes low 32-bits, '1' high 32-bits
* if p00 == s0 * tlo0
* k00 == carry of p00
* p01 == s0 * tlo1
* k01 == carry of (p01 + k00)
* p10 == s1 * tlo0
* k10 == carry of p10
* p11 == s1 * tlo1 (unmasked, i.e. including unshifted carry if any)
* then t->lo == (p01 + p10 + k00) << 32 + p00
* and t->hi == p11 + k10 + k01 + thi * s
*
* (thi) tlo1 tlo0
* x s1 s0
* -------------------------
* p00
* k01 p01 + k00
* p10
* p11 + k10
*/
INTERNAL void large_mul_u64(large_int *t, uint64_t s) {
uint64_t thi = t->hi;
uint64_t tlo0 = t->lo & MASK32;
uint64_t tlo1 = t->lo >> 32;
uint64_t s0 = s & MASK32;
uint64_t s1 = s >> 32;
uint64_t tmp = s0 * tlo0; /* p00 (unmasked) */
uint64_t p00 = tmp & MASK32;
uint64_t k10;
tmp = (s1 * tlo0) + (tmp >> 32); /* (p10 + k00) (p10 unmasked) */
k10 = tmp >> 32;
tmp = (s0 * tlo1) + (tmp & MASK32); /* (p01 + p10 + k00) (p01 unmasked) */
t->lo = (tmp << 32) + p00; /* (p01 + p10 + k00) << 32 + p00 (note any carry from unmasked p01 shifted out) */
t->hi = (s1 * tlo1) + k10 + (tmp >> 32) + thi * s; /* p11 + k10 + k01 + thi * s */
}
/* Count leading zeroes. See Hickman `r128__clz64()` */
STATIC_UNLESS_ZINT_TEST int clz_u64(uint64_t x) {
uint64_t n = 64, y;
y = x >> 32; if (y) { n -= 32; x = y; }
y = x >> 16; if (y) { n -= 16; x = y; }
y = x >> 8; if (y) { n -= 8; x = y; }
y = x >> 4; if (y) { n -= 4; x = y; }
y = x >> 2; if (y) { n -= 2; x = y; }
y = x >> 1; if (y) { n -= 1; x = y; }
return (int) (n - x);
}
/* Divide 128-bit dividend `t` by 64-bit divisor `v`
* See Jacob `divmod128by128/64()` and Warren Section 92 (divmu64.c.txt)
* Note digits are 32-bit parts */
INTERNAL uint64_t large_div_u64(large_int *t, uint64_t v) {
const uint64_t b = 0x100000000; /* Number base (2**32) */
uint64_t qhi = 0; /* High digit of returned quotient */
uint64_t tnhi, tnlo, tnlo1, tnlo0, vn1, vn0; /* Normalized forms of (parts of) t and v */
uint64_t rnhilo1; /* Remainder after dividing 1st 3 digits of t by v */
uint64_t qhat1, qhat0; /* Estimated quotient digits */
uint64_t rhat; /* Remainder of estimated quotient digit */
uint64_t tmp;
int norm_shift;
/* Deal with single-digit (i.e. 32-bit) divisor here */
if (v < b) {
qhi = t->hi / v;
tmp = ((t->hi - qhi * v) << 32) + (t->lo >> 32); /* k * b + tlo1 */
qhat1 = tmp / v;
tmp = ((tmp - qhat1 * v) << 32) + (t->lo & MASK32); /* k * b + tlo0 */
qhat0 = tmp / v;
t->lo = (qhat1 << 32) | qhat0;
t->hi = qhi;
return tmp - qhat0 * v;
}
/* Main algorithm requires t->hi < v */
if (t->hi >= v) {
qhi = t->hi / v;
t->hi %= v;
}
/* Normalize by shifting v left just enough so that its high-order
* bit is on, and shift t left the same amount. Note don't need extra
* high-end digit for dividend as t->hi < v */
norm_shift = clz_u64(v);
v <<= norm_shift;
vn1 = v >> 32;
vn0 = v & MASK32;
if (norm_shift > 0) {
tnhi = (t->hi << norm_shift) | (t->lo >> (64 - norm_shift));
tnlo = t->lo << norm_shift;
} else {
sub_buffer[i] = 0;
tnhi = t->hi;
tnlo = t->lo;
}
}
binary_add(accumulator, sub_buffer);
sub_buffer[0] = 1;
tnlo1 = tnlo >> 32;
tnlo0 = tnlo & MASK32;
for (i = 1; i < 112; i++) {
sub_buffer[i] = 0;
/* Compute qhat1 estimate */
qhat1 = tnhi / vn1; /* Divide first digit of v into first 2 digits of t */
rhat = tnhi % vn1;
/* Loop until qhat1 one digit and <= (rhat * b + 3rd digit of t) / vn0 */
for (tmp = qhat1 * vn0; qhat1 >= b || tmp > (rhat << 32) + tnlo1; tmp -= vn0) {
--qhat1;
rhat += vn1;
if (rhat >= b) { /* Must check here as (rhat << 32) would overflow */
break; /* qhat1 * vn0 < b * b (since vn0 < b) */
}
binary_add(accumulator, sub_buffer);
}
/* Note qhat1 will be exact as have fully divided by 2-digit divisor
* (can only be too high by 1 (and require "add back" step) if divisor at least 3 digits) */
rnhilo1 = (tnhi << 32) + tnlo1 - (qhat1 * v); /* Note high digit (if any) of both tnhi and (qhat1 * v) shifted out */
/* Compute qhat0 estimate */
qhat0 = rnhilo1 / vn1; /* Divide first digit of v into 2-digit remains of first 3 digits of t */
rhat = rnhilo1 % vn1;
/* Loop until qhat0 one digit and <= (rhat * b + 4th digit of t) / vn0 */
for (tmp = qhat0 * vn0; qhat0 >= b || tmp > (rhat << 32) + tnlo0; tmp -= vn0) {
--qhat0;
rhat += vn1;
if (rhat >= b) {
break;
}
}
/* Similarly qhat0 will be exact */
t->lo = (qhat1 << 32) | qhat0;
t->hi = qhi;
/* Unnormalize remainder */
return ((rnhilo1 << 32) + tnlo0 - (qhat0 * v)) >> norm_shift;
}
INTERNAL void binary_multiply(short int reg[], char data[]) {
/* Multiply the contents of reg[] by a number */
short int temp[112] = {0};
short int accum[112] = {0};
/* Unset a bit (zero-based) */
INTERNAL void large_unset_bit(large_int *t, int bit) {
if (bit < 64) {
t->lo &= ~(((uint64_t) 1) << bit);
} else if (bit < 128) {
t->hi &= ~(((uint64_t) 1) << (bit - 64));
}
}
/* Ouput large_int into an unsigned int array of size `size`, each element containing `bits` bits */
INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, int size, int bits) {
int i, j;
uint64_t mask;
if (bits <= 0) {
bits = 8;
} else if (bits > 32) {
bits = 32;
}
mask = ~(((uint64_t) -1) << bits);
for (i = 0, j = 0; i < size && j < 64; i++, j += bits) {
uint_array[size - 1 - i] = (t->lo >> j) & mask; /* Little-endian order */
}
if (i < size) {
if (j != 64) {
j -= 64;
/* (first j bits of t->hi) << (bits - j) | (last (bits - j) bits of t->lo) */
uint_array[size - i] = ((t->hi & ~((((uint64_t) -1) << j))) << (bits - j)) | (t->lo >> (64 - (bits - j)) & mask);
} else {
j = 0;
}
for (; i < size && j < 64; i++, j += bits) {
uint_array[size - 1 - i] = (t->hi >> j) & mask;
}
if (i < size && j != 128) {
uint_array[size - 1 - i] = t->hi >> (j - bits) & mask;
}
}
}
/* As `large_uint_array()` above, except output to unsigned char array */
INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, int size, int bits) {
int i;
#ifndef _MSC_VER
unsigned int uint_array[size ? size : 1]; /* Avoid run-time warning if size is 0 */
#else
unsigned int *uint_array = _alloca((size ? size : 1) * sizeof(unsigned int));
#endif
binary_load(temp, data, strlen(data));
large_uint_array(t, uint_array, size, bits);
for (i = 0; i < 102; i++) {
if (temp[i] == 1) {
binary_add(accum, reg);
}
shiftup(reg);
}
for (i = 0; i < 112; i++) {
reg[i] = accum[i];
for (i = 0; i < size; i++) {
uchar_array[i] = uint_array[i];
}
}
INTERNAL void shiftdown(short int buffer[]) {
int i;
/* Output formatted large_int to stdout */
INTERNAL void large_print(large_int *t) {
char buf[35]; /* 2 (0x) + 32 (hex) + 1 */
buffer[102] = 0;
buffer[103] = 0;
for (i = 0; i < 102; i++) {
buffer[i] = buffer[i + 1];
}
puts(large_dump(t, buf));
}
INTERNAL void shiftup(short int buffer[]) {
int i;
/* Format large_int into buffer, which should be at least 35 chars in size */
INTERNAL char *large_dump(large_int *t, char *buf) {
unsigned int tlo1 = large_lo(t) >> 32;
unsigned int tlo0 = large_lo(t) & MASK32;
unsigned int thi1 = large_hi(t) >> 32;
unsigned int thi0 = large_hi(t) & MASK32;
for (i = 102; i > 0; i--) {
buffer[i] = buffer[i - 1];
}
buffer[0] = 0;
}
INTERNAL short int islarger(short int accum[], short int reg[]) {
/* Returns 1 if accum[] is larger than reg[], else 0 */
int i, latch, larger;
latch = 0;
i = 103;
larger = 0;
do {
if ((accum[i] == 1) && (reg[i] == 0)) {
latch = 1;
larger = 1;
}
if ((accum[i] == 0) && (reg[i] == 1)) {
latch = 1;
}
i--;
} while ((latch == 0) && (i >= 0));
return larger;
}
INTERNAL void binary_load(short int reg[], char data[], const size_t src_len) {
size_t read;
int i;
short int temp[112] = {0};
for (i = 0; i < 112; i++) {
reg[i] = 0;
}
for (read = 0; read < src_len; read++) {
for (i = 0; i < 112; i++) {
temp[i] = reg[i];
}
for (i = 0; i < 9; i++) {
binary_add(reg, temp);
}
for (i = 0; i < 112; i++) {
temp[i] = 0;
}
for (i = 0; i < 4; i++) {
if (ctoi(data[read]) & (0x01 << i)) temp[i] = 1;
}
binary_add(reg, temp);
if (thi1) {
sprintf(buf, "0x%X%08X%08X%08X", thi1, thi0, tlo1, tlo0);
} else if (thi0) {
sprintf(buf, "0x%X%08X%08X", thi0, tlo1, tlo0);
} else if (tlo1) {
sprintf(buf, "0x%X%08X", tlo1, tlo0);
} else {
sprintf(buf, "0x%X", tlo0);
}
return buf;
}

View File

@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -33,17 +33,45 @@
#ifndef __LARGE_H
#define __LARGE_H
#ifndef _MSC_VER
#include <stdint.h>
#else
#include "ms_stdint.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
INTERNAL void binary_load(short int reg[], char data[], const size_t src_len);
INTERNAL void binary_add(short int accumulator[], short int input_buffer[]);
INTERNAL void binary_subtract(short int accumulator[], short int input_buffer[]);
INTERNAL void shiftdown(short int buffer[]);
INTERNAL void shiftup(short int buffer[]);
INTERNAL short int islarger(short int accum[], short int reg[]);
INTERNAL void binary_multiply(short int reg[], char data[]);
typedef struct { uint64_t lo; uint64_t hi; } large_int;
#define large_lo(s) ((s)->lo)
#define large_hi(s) ((s)->hi)
/* Set 128-bit `t` from 128-bit `s` */
#define large_load(t, s) do { (t)->lo = (s)->lo; (t)->hi = (s)->hi; } while (0)
/* Set 128-bit `t` from 64-bit `s` */
#define large_load_u64(t, s) do { (t)->lo = (s); (t)->hi = 0; } while (0)
INTERNAL void large_load_str_u64(large_int *t, const unsigned char *s, int length);
INTERNAL void large_add(large_int *t, const large_int *s);
INTERNAL void large_add_u64(large_int *t, uint64_t s);
INTERNAL void large_sub_u64(large_int *t, uint64_t s);
INTERNAL void large_mul_u64(large_int *t, uint64_t s);
INTERNAL uint64_t large_div_u64(large_int *t, uint64_t v);
INTERNAL void large_unset_bit(large_int *t, int bit);
INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, int size, int bits);
INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, int size, int bits);
INTERNAL void large_print(large_int *t);
INTERNAL char *large_dump(large_int *t, char *buf);
#ifdef __cplusplus
}

View File

@ -133,11 +133,9 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
char postcode[10];
int postcode_type;
char pattern[10];
short int destination_postcode[112];
short int a[112];
short int b[112];
short int temp[112];
short int cdv[112];
large_int destination_postcode;
large_int b;
large_int cdv;
unsigned char data[26];
int data_top, data_step;
unsigned char check[7];
@ -170,7 +168,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
to_upper((unsigned char*) local_source);
if (symbol->debug) {
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Producing Mailmark %s\n", local_source);
}
@ -279,164 +277,107 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
}
// Convert postcode to internal user field
for (i = 0; i < 112; i++) {
destination_postcode[i] = 0;
a[i] = 0;
b[i] = 0;
}
large_load_u64(&destination_postcode, 0);
if (postcode_type != 7) {
strcpy(pattern, postcode_format[postcode_type - 1]);
binary_load(b, "0", 1);
large_load_u64(&b, 0);
for (i = 0; i < 9; i++) {
switch (pattern[i]) {
case 'F':
binary_multiply(b, "26");
binary_load(temp, "0", 1);
for (j = 0; j < 5; j++) {
if (posn(SET_F, postcode[i]) & (0x01 << j)) temp[j] = 1;
}
binary_add(b, temp);
large_mul_u64(&b, 26);
large_add_u64(&b, posn(SET_F, postcode[i]));
break;
case 'L':
binary_multiply(b, "20");
binary_load(temp, "0", 1);
for (j = 0; j < 5; j++) {
if (posn(SET_L, postcode[i]) & (0x01 << j)) temp[j] = 1;
}
binary_add(b, temp);
large_mul_u64(&b, 20);
large_add_u64(&b, posn(SET_L, postcode[i]));
break;
case 'N':
binary_multiply(b, "10");
binary_load(temp, "0", 1);
for (j = 0; j < 4; j++) {
if (posn(SET_N, postcode[i]) & (0x01 << j)) temp[j] = 1;
}
binary_add(b, temp);
large_mul_u64(&b, 10);
large_add_u64(&b, posn(SET_N, postcode[i]));
break;
// case 'S' ignorred as value is 0
// case 'S' ignored as value is 0
}
}
large_load(&destination_postcode, &b);
// destination_postcode = a + b
binary_load(destination_postcode, "0", 1);
binary_add(destination_postcode, b);
binary_load(a, "1", 1);
large_load_u64(&b, 1);
if (postcode_type == 1) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "5408000000", 10);
binary_add(a, temp);
large_add_u64(&b, 5408000000);
if (postcode_type == 2) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "5408000000", 10);
binary_add(a, temp);
large_add_u64(&b, 5408000000);
if (postcode_type == 3) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "54080000000", 11);
binary_add(a, temp);
large_add_u64(&b, 54080000000);
if (postcode_type == 4) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "140608000000", 12);
binary_add(a, temp);
large_add_u64(&b, 140608000000);
if (postcode_type == 5) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "208000000", 9);
binary_add(a, temp);
large_add_u64(&b, 208000000);
if (postcode_type == 6) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
}
// Conversion from Internal User Fields to Consolidated Data Value
// Set CDV to 0
binary_load(cdv, "0", 1);
large_load_u64(&cdv, 0);
// Add Destination Post Code plus DPS
binary_add(cdv, destination_postcode);
large_add(&cdv, &destination_postcode);
// Multiply by 100,000,000
binary_multiply(cdv, "100000000");
large_mul_u64(&cdv, 100000000);
// Add Item ID
binary_load(temp, "0", 1);
for (i = 0; i < 31; i++) {
if (0x01 & (item_id >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
large_add_u64(&cdv, item_id);
if (length == 22) {
// Barcode C - Multiply by 100
binary_multiply(cdv, "100");
large_mul_u64(&cdv, 100);
} else {
// Barcode L - Multiply by 1,000,000
binary_multiply(cdv, "1000000");
large_mul_u64(&cdv, 1000000);
}
// Add Supply Chain ID
binary_load(temp, "0", 1);
for (i = 0; i < 20; i++) {
if (0x01 & (supply_chain_id >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
large_add_u64(&cdv, supply_chain_id);
// Multiply by 15
binary_multiply(cdv, "15");
large_mul_u64(&cdv, 15);
// Add Class
binary_load(temp, "0", 1);
for (i = 0; i < 4; i++) {
if (0x01 & (mail_class >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
large_add_u64(&cdv, mail_class);
// Multiply by 5
binary_multiply(cdv, "5");
large_mul_u64(&cdv, 5);
// Add Format
binary_load(temp, "0", 1);
for (i = 0; i < 4; i++) {
if (0x01 & (format >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
large_add_u64(&cdv, format);
// Multiply by 4
binary_multiply(cdv, "4");
large_mul_u64(&cdv, 4);
// Add Version ID
binary_load(temp, "0", 1);
for (i = 0; i < 4; i++) {
if (0x01 & (version_id >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
large_add_u64(&cdv, version_id);
if (symbol->debug) {
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("DPC type %d\n", postcode_type);
printf("CDV: ");
for (i = 96; i >= 0; i-= 4) {
j = 0;
j += cdv[i];
j += cdv[i + 1] * 2;
j += cdv[i + 2] * 4;
j += cdv[i + 3] * 8;
printf("%c", itoc(j));
}
printf("\n");
large_print(&cdv);
}
@ -451,49 +392,13 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
}
// Conversion from Consolidated Data Value to Data Numbers
for (i = 0; i < 112; i++) {
b[i] = cdv[i];
}
for (j = data_top; j >= (data_step + 1); j--) {
for (i = 0; i < 112; i++) {
cdv[i] = b[i];
b[i] = 0;
a[i] = 0;
}
a[96] = 1;
for (i = 91; i >= 0; i--) {
b[i] = !islarger(a, cdv);
if (b[i] == 1) {
binary_subtract(cdv, a);
}
shiftdown(a);
}
data[j] = (cdv[4] * 16) + (cdv[3] * 8) + (cdv[2] * 4) +
(cdv[1] * 2) + cdv[0];
data[j] = large_div_u64(&cdv, 32);
}
for (j = data_step; j >= 0; j--) {
for (i = 0; i < 112; i++) {
cdv[i] = b[i];
b[i] = 0;
a[i] = 0;
}
a[95] = 1;
a[94] = 1;
a[93] = 1;
a[92] = 1;
for (i = 91; i >= 0; i--) {
b[i] = !islarger(a, cdv);
if (b[i] == 1) {
binary_subtract(cdv, a);
}
shiftdown(a);
}
data[j] = (cdv[4] * 16) + (cdv[3] * 8) + (cdv[2] * 4) +
(cdv[1] * 2) + cdv[0];
data[j] = large_div_u64(&cdv, 30);
}
// Generation of Reed-Solomon Check Numbers
@ -507,7 +412,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
data[data_top + i] = check[check_count - i];
}
if (symbol->debug) {
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Codewords: ");
for (i = 0; i <= data_top + check_count; i++) {
printf("%d ", (int) data[i]);
@ -565,7 +470,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
bar[(length * 3)] = '\0';
if (symbol->debug) {
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Bar pattern: %s\n", bar);
}

View File

@ -64,8 +64,6 @@
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
@ -162,11 +160,12 @@ static void getRSSwidths(int val, int n, int elements, int maxWidth, int noNarro
/* GS1 DataBar-14 */
INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_len) {
int error_number = 0, i, j, mask;
short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112];
int data_character[4], data_group[4], v_odd[4], v_even[4];
int error_number = 0, i, j;
large_int accum;
uint64_t left_pair, right_pair;
int data_character[4] = {0}, data_group[4] = {0}, v_odd[4], v_even[4];
int data_widths[8][4], checksum, c_left, c_right, total_widths[46], writer;
char latch, temp[32];
char latch;
int separator_row;
separator_row = 0;
@ -192,110 +191,25 @@ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_l
break;
}
for (i = 0; i < 112; i++) {
accum[i] = 0;
x_reg[i] = 0;
y_reg[i] = 0;
}
large_load_str_u64(&accum, source, src_len);
for (i = 0; i < 4; i++) {
data_character[i] = 0;
data_group[i] = 0;
}
binary_load(accum, (char*) source, src_len);
strcpy(temp, "10000000000000");
if (symbol->option_1 == 2) {
/* Add symbol linkage flag */
binary_load(y_reg, temp, strlen(temp));
binary_add(accum, y_reg);
for (i = 0; i < 112; i++) {
y_reg[i] = 0;
}
large_add_u64(&accum, 10000000000000);
}
/* Calculate left and right pair values */
strcpy(temp, "4537077");
binary_load(x_reg, temp, strlen(temp));
for (i = 0; i < 24; i++) {
shiftup(x_reg);
}
for (i = 24; i >= 0; i--) {
y_reg[i] = !islarger(x_reg, accum);
if (y_reg[i] == 1) {
binary_subtract(accum, x_reg);
}
shiftdown(x_reg);
}
for (i = 0; i < 112; i++) {
left_reg[i] = y_reg[i];
right_reg[i] = accum[i];
}
right_pair = large_div_u64(&accum, 4537077);
left_pair = large_lo(&accum);
/* Calculate four data characters */
strcpy(temp, "1597");
binary_load(x_reg, temp, strlen(temp));
for (i = 0; i < 112; i++) {
accum[i] = left_reg[i];
}
for (i = 0; i < 24; i++) {
shiftup(x_reg);
}
data_character[0] = left_pair / 1597;
data_character[1] = left_pair % 1597;
for (i = 24; i >= 0; i--) {
y_reg[i] = !islarger(x_reg, accum);
if (y_reg[i] == 1) {
binary_subtract(accum, x_reg);
}
shiftdown(x_reg);
}
data_character[0] = 0;
data_character[1] = 0;
mask = 0x2000;
for (i = 13; i >= 0; i--) {
if (y_reg[i] == 1) {
data_character[0] += mask;
}
if (accum[i] == 1) {
data_character[1] += mask;
}
mask = mask >> 1;
}
strcpy(temp, "1597");
binary_load(x_reg, temp, strlen(temp));
for (i = 0; i < 112; i++) {
accum[i] = right_reg[i];
}
for (i = 0; i < 24; i++) {
shiftup(x_reg);
}
for (i = 24; i >= 0; i--) {
y_reg[i] = !islarger(x_reg, accum);
if (y_reg[i] == 1) {
binary_subtract(accum, x_reg);
}
shiftdown(x_reg);
}
data_character[2] = 0;
data_character[3] = 0;
mask = 0x2000;
for (i = 13; i >= 0; i--) {
if (y_reg[i] == 1) {
data_character[2] += mask;
}
if (accum[i] == 1) {
data_character[3] += mask;
}
mask = mask >> 1;
}
data_character[2] = right_pair / 1597;
data_character[3] = right_pair % 1597;
/* Calculate odd and even subset values */
@ -736,12 +650,13 @@ INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_l
/* GS1 DataBar Limited */
INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int src_len) {
int error_number = 0, i, mask;
short int accum[112], left_reg[112], right_reg[112], x_reg[112], y_reg[112];
int error_number = 0, i;
large_int accum;
uint64_t left_character, right_character;
int left_group, right_group, left_odd, left_even, right_odd, right_even;
int left_character, right_character, left_widths[14], right_widths[14];
int left_widths[14], right_widths[14];
int checksum, check_elements[14], total_widths[46], writer, j, check_digit, count;
char latch, hrt[15], temp[32];
char latch, hrt[15];
int separator_row;
separator_row = 0;
@ -769,172 +684,60 @@ INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int
symbol->rows += 1;
}
for (i = 0; i < 112; i++) {
accum[i] = 0;
x_reg[i] = 0;
y_reg[i] = 0;
}
large_load_str_u64(&accum, source, src_len);
binary_load(accum, (char*) source, src_len);
if (symbol->option_1 == 2) {
/* Add symbol linkage flag */
strcpy(temp, "2015133531096");
binary_load(y_reg, temp, strlen(temp));
binary_add(accum, y_reg);
for (i = 0; i < 112; i++) {
y_reg[i] = 0;
}
large_add_u64(&accum, 2015133531096);
}
/* Calculate left and right pair values */
strcpy(temp, "2013571");
binary_load(x_reg, temp, strlen(temp));
for (i = 0; i < 24; i++) {
shiftup(x_reg);
}
right_character = large_div_u64(&accum, 2013571);
left_character = large_lo(&accum);
for (i = 24; i >= 0; i--) {
y_reg[i] = !islarger(x_reg, accum);
if (y_reg[i] == 1) {
binary_subtract(accum, x_reg);
}
shiftdown(x_reg);
}
for (i = 0; i < 112; i++) {
left_reg[i] = y_reg[i];
right_reg[i] = accum[i];
}
left_group = 0;
strcpy(temp, "183063");
binary_load(accum, temp, strlen(temp));
if (islarger(left_reg, accum)) {
left_group = 1;
}
strcpy(temp, "820063");
binary_load(accum, temp, strlen(temp));
if (islarger(left_reg, accum)) {
left_group = 2;
}
strcpy(temp, "1000775");
binary_load(accum, temp, strlen(temp));
if (islarger(left_reg, accum)) {
left_group = 3;
}
strcpy(temp, "1491020");
binary_load(accum, temp, strlen(temp));
if (islarger(left_reg, accum)) {
left_group = 4;
}
strcpy(temp, "1979844");
binary_load(accum, temp, strlen(temp));
if (islarger(left_reg, accum)) {
left_group = 5;
}
strcpy(temp, "1996938");
binary_load(accum, temp, strlen(temp));
if (islarger(left_reg, accum)) {
if (left_character >= 1996939) {
left_group = 6;
left_character -= 1996939;
} else if (left_character >= 1979845) {
left_group = 5;
left_character -= 1979845;
} else if (left_character >= 1491021) {
left_group = 4;
left_character -= 1491021;
} else if (left_character >= 1000776) {
left_group = 3;
left_character -= 1000776;
} else if (left_character >= 820064) {
left_group = 2;
left_character -= 820064;
} else if (left_character >= 183064) {
left_group = 1;
left_character -= 183064;
} else {
left_group = 0;
}
right_group = 0;
strcpy(temp, "183063");
binary_load(accum, temp, strlen(temp));
if (islarger(right_reg, accum)) {
right_group = 1;
}
strcpy(temp, "820063");
binary_load(accum, temp, strlen(temp));
if (islarger(right_reg, accum)) {
right_group = 2;
}
strcpy(temp, "1000775");
binary_load(accum, temp, strlen(temp));
if (islarger(right_reg, accum)) {
right_group = 3;
}
strcpy(temp, "1491020");
binary_load(accum, temp, strlen(temp));
if (islarger(right_reg, accum)) {
right_group = 4;
}
strcpy(temp, "1979844");
binary_load(accum, temp, strlen(temp));
if (islarger(right_reg, accum)) {
right_group = 5;
}
strcpy(temp, "1996938");
binary_load(accum, temp, strlen(temp));
if (islarger(right_reg, accum)) {
if (right_character >= 1996939) {
right_group = 6;
}
switch (left_group) {
case 1: strcpy(temp, "183064");
binary_load(accum, temp, strlen(temp));
binary_subtract(left_reg, accum);
break;
case 2: strcpy(temp, "820064");
binary_load(accum, temp, strlen(temp));
binary_subtract(left_reg, accum);
break;
case 3: strcpy(temp, "1000776");
binary_load(accum, temp, strlen(temp));
binary_subtract(left_reg, accum);
break;
case 4: strcpy(temp, "1491021");
binary_load(accum, temp, strlen(temp));
binary_subtract(left_reg, accum);
break;
case 5: strcpy(temp, "1979845");
binary_load(accum, temp, strlen(temp));
binary_subtract(left_reg, accum);
break;
case 6: strcpy(temp, "1996939");
binary_load(accum, temp, strlen(temp));
binary_subtract(left_reg, accum);
break;
}
switch (right_group) {
case 1: strcpy(temp, "183064");
binary_load(accum, temp, strlen(temp));
binary_subtract(right_reg, accum);
break;
case 2: strcpy(temp, "820064");
binary_load(accum, temp, strlen(temp));
binary_subtract(right_reg, accum);
break;
case 3: strcpy(temp, "1000776");
binary_load(accum, temp, strlen(temp));
binary_subtract(right_reg, accum);
break;
case 4: strcpy(temp, "1491021");
binary_load(accum, temp, strlen(temp));
binary_subtract(right_reg, accum);
break;
case 5: strcpy(temp, "1979845");
binary_load(accum, temp, strlen(temp));
binary_subtract(right_reg, accum);
break;
case 6: strcpy(temp, "1996939");
binary_load(accum, temp, strlen(temp));
binary_subtract(right_reg, accum);
break;
}
left_character = 0;
right_character = 0;
mask = 0x800000;
for (i = 23; i >= 0; i--) {
if (left_reg[i] == 1) {
left_character += mask;
}
if (right_reg[i] == 1) {
right_character += mask;
}
mask = mask >> 1;
right_character -= 1996939;
} else if (right_character >= 1979845) {
right_group = 5;
right_character -= 1979845;
} else if (right_character >= 1491021) {
right_group = 4;
right_character -= 1491021;
} else if (right_character >= 1000776) {
right_group = 3;
right_character -= 1000776;
} else if (right_character >= 820064) {
right_group = 2;
right_character -= 820064;
} else if (right_character >= 183064) {
right_group = 1;
right_character -= 183064;
} else {
right_group = 0;
}
left_odd = left_character / t_even_ltd[left_group];
@ -1062,7 +865,7 @@ INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int
/* Handles all data encodation from section 7.2.5 of ISO/IEC 24724 */
static int rss_binary_string(struct zint_symbol *symbol, char source[], char binary_string[]) {
int encoding_method, i, j, read_posn, last_digit, debug = symbol->debug, mode = NUMERIC;
int encoding_method, i, j, read_posn, last_digit, debug = (symbol->debug & ZINT_DEBUG_PRINT), mode = NUMERIC;
int symbol_characters, characters_per_row;
#ifndef _MSC_VER
char general_field[strlen(source) + 1];

View File

@ -1,6 +1,7 @@
# Copyright (C) 2019 - 2020 Robin Stuart <rstuart114@gmail.com>
# Adapted from qrencode/tests/CMakeLists.txt
# Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
# vim: set ts=4 sw=4 et :
cmake_minimum_required(VERSION 3.9)
@ -35,8 +36,7 @@ if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
endif()
endif()
add_library(testcommon
testcommon.c testcommon.h)
add_library(testcommon testcommon.c testcommon.h)
if(PNG_FOUND)
target_link_libraries(testcommon ZINT::ZINT ${PNG_LIBRARIES})
else()
@ -48,7 +48,7 @@ macro(zint_add_test test_name test_command)
add_executable(${test_command} ${test_command}.c)
target_link_libraries(${test_command} testcommon ${ADDITIONAL_LIBS})
add_test(${test_name} ${test_command})
endmacro(zint_add_test)
endmacro()
zint_add_test(2of5, test_2of5)
zint_add_test(auspost, test_auspost)
@ -74,6 +74,7 @@ zint_add_test(gridmtx, test_gridmtx)
zint_add_test(gs1, test_gs1)
zint_add_test(hanxin, test_hanxin)
zint_add_test(imail, test_imail)
zint_add_test(large, test_large)
zint_add_test(library, test_library)
zint_add_test(mailmark, test_mailmark)
zint_add_test(maxicode, test_maxicode)

View File

@ -34,7 +34,7 @@
#include "testcommon.h"
#define TEST_IMAIL_CSV_MAX 300
//#define TEST_IMAIL_CSV_MAX 300
static void test_csv(int index, int debug) {
@ -59,7 +59,7 @@ static void test_csv(int index, int debug) {
lc++;
if (index != -1 && lc != index) continue;
if (index != -1 && lc != index + 1) continue;
#ifdef TEST_IMAIL_CSV_MAX
if (lc > TEST_IMAIL_CSV_MAX && index == -1) {
@ -178,7 +178,7 @@ static void test_input(int index, int debug) {
/* 1*/ { "123456789012345678901234567890123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 2*/ { "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
/* 3*/ { "12345678901234567890", 0, 3, 129 }, // Tracker only, no ZIP
/* 4*/ { "12355678901234567890", 0, 3, 129 }, // Tracker 4th char > 4
/* 4*/ { "15345678901234567890", ZINT_ERROR_INVALID_DATA, -1, -1 }, // Tracker 2nd char > 4
/* 5*/ { "1234567890123456789", ZINT_ERROR_INVALID_DATA, -1, -1 }, // Tracker 20 chars
/* 6*/ { "12345678901234567890-1234", ZINT_ERROR_INVALID_DATA, -1, -1 }, // ZIP wrong len
/* 7*/ { "12345678901234567890-12345", 0, 3, 129 },

883
backend/tests/test_large.c Normal file
View File

@ -0,0 +1,883 @@
/*
libzint - the open source barcode library
Copyright (C) 2020 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.
*/
/* vim: set ts=4 sw=4 et : */
#include "testcommon.h"
#include "../large.h"
#define LI(l, h) { l, h }
int clz_u64(uint64_t x);
static void test_clz_u64(int index, int debug) {
testStart("");
int ret;
struct item {
uint64_t s;
int ret;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { 0x0, 64 },
/* 1*/ { 0x1, 63 },
/* 2*/ { 0x2, 62 },
/* 3*/ { 0x3, 62 },
/* 4*/ { 0x4, 61 },
/* 5*/ { 0x5, 61 },
/* 6*/ { 0x6, 61 },
/* 7*/ { 0x7, 61 },
/* 8*/ { 0x8, 60 },
/* 9*/ { 0x9, 60 },
/* 10*/ { 0xA, 60 },
/* 11*/ { 0xB, 60 },
/* 12*/ { 0xC, 60 },
/* 13*/ { 0xD, 60 },
/* 14*/ { 0xE, 60 },
/* 15*/ { 0xF, 60 },
/* 16*/ { 0x10, 59 },
/* 17*/ { 0x11, 59 },
/* 18*/ { 0x12, 59 },
/* 19*/ { 0x13, 59 },
/* 20*/ { 0x14, 59 },
/* 21*/ { 0x15, 59 },
/* 22*/ { 0x16, 59 },
/* 23*/ { 0x17, 59 },
/* 24*/ { 0x18, 59 },
/* 25*/ { 0x19, 59 },
/* 26*/ { 0x1A, 59 },
/* 27*/ { 0x1B, 59 },
/* 28*/ { 0x1C, 59 },
/* 29*/ { 0x1D, 59 },
/* 30*/ { 0x1E, 59 },
/* 31*/ { 0x1F, 59 },
/* 32*/ { 0x20, 58 },
/* 33*/ { 0x21, 58 },
/* 34*/ { 0x22, 58 },
/* 35*/ { 0x23, 58 },
/* 36*/ { 0x2F, 58 },
/* 37*/ { 0x40, 57 },
/* 38*/ { 0x49, 57 },
/* 39*/ { 0x50, 57 },
/* 40*/ { 0x5F, 57 },
/* 41*/ { 0x60, 57 },
/* 42*/ { 0x7F, 57 },
/* 43*/ { 0x80, 56 },
/* 44*/ { 0x88, 56 },
/* 45*/ { 0xA1, 56 },
/* 46*/ { 0xFF, 56 },
/* 47*/ { 0x100, 55 },
/* 48*/ { 0x165, 55 },
/* 49*/ { 0x1FF, 55 },
/* 50*/ { 0x384, 54 },
/* 51*/ { 0x555, 53 },
/* 52*/ { 0xBCD, 52 },
/* 53*/ { 0x1FFF, 51 },
/* 54*/ { 0x2E06, 50 },
/* 55*/ { 0x7040, 49 },
/* 56*/ { 0x8001, 48 },
/* 57*/ { 0xC0FF, 48 },
/* 58*/ { 0x1C0FF, 47 },
/* 59*/ { 0x2211E, 46 },
/* 60*/ { 0x44220, 45 },
/* 61*/ { 0x50505, 45 },
/* 62*/ { 0x88888, 44 },
/* 63*/ { 0x111111, 43 },
/* 64*/ { 0x222222, 42 },
/* 65*/ { 0x444444, 41 },
/* 66*/ { 0xFF00FF, 40 },
/* 67*/ { 0x10B8392, 39 },
/* 68*/ { 0x2FFFFFF, 38 },
/* 69*/ { 0x4040404, 37 },
/* 70*/ { 0x7777777, 37 },
/* 71*/ { 0xF0F0F0F, 36 },
/* 72*/ { 0x194F0311, 35 },
/* 73*/ { 0x33333333, 34 },
/* 74*/ { 0x55555555, 33 },
/* 75*/ { 0xAAAAAAAA, 32 },
/* 76*/ { 0x100000000, 31 },
/* 77*/ { 0x2FFFFFFFF, 30 },
/* 78*/ { 0x304050607, 30 },
/* 79*/ { 0x707070707, 29 },
/* 80*/ { 0x999999999, 28 },
/* 81*/ { 0xEEEEEEEEE, 28 },
/* 82*/ { 0x1000000001, 27 },
/* 83*/ { 0x2D2D2D2D2D, 26 },
/* 84*/ { 0x68034DAE71, 25 },
/* 85*/ { 0xF462103784, 24 },
/* 86*/ { 0x1CCCCCCCCCC, 23 },
/* 87*/ { 0x2F462103784, 22 },
/* 88*/ { 0x4F4E4D4C4B4, 21 },
/* 89*/ { 0x9FFFFFFFFFF, 20 },
/* 90*/ { 0x100000000000, 19 },
/* 91*/ { 0x369D03178212, 18 },
/* 92*/ { 0x666000666000, 17 },
/* 93*/ { 0xFFFFFFFFFFFF, 16 },
/* 94*/ { 0x123456789ABCD, 15 },
/* 95*/ { 0x3FFFFFFFFFFFF, 14 },
/* 96*/ { 0x429C8174831A0, 13 },
/* 97*/ { 0xBBBBBBBBBBBBB, 12 },
/* 98*/ { 0x11111111111111, 11 },
/* 99*/ { 0x24242424242424, 10 },
/*100*/ { 0x44444444444444, 9 },
/*101*/ { 0x567890ABCDEF01, 9 },
/*102*/ { 0xFFFFFFFFFFFFFF, 8 },
/*103*/ { 0x100000000000100, 7 },
/*104*/ { 0x37F037F047F037F, 6 },
/*105*/ { 0x60123456789ABCD, 5 },
/*106*/ { 0xDDDDDDDDDDDDDDD, 4 },
/*107*/ { 0xFEDCBA987654321, 4 },
/*108*/ { 0xFFFFFFFFFFFFFFF, 4 },
/*109*/ { 0x1000000000000000, 3 },
/*110*/ { 0x1000000000000001, 3 },
/*111*/ { 0x2000000000010000, 2 },
/*112*/ { 0x3100000000000000, 2 },
/*113*/ { 0x4001000000000000, 1 },
/*114*/ { 0x5000000100000000, 1 },
/*115*/ { 0x6000001000000000, 1 },
/*116*/ { 0x7000000001000000, 1 },
/*117*/ { 0x8000100000000000, 0 },
/*118*/ { 0x9000000000001000, 0 },
/*119*/ { 0xA000000000000010, 0 },
/*120*/ { 0xB000000000000000, 0 },
/*121*/ { 0xC010000000000000, 0 },
/*122*/ { 0xD000010000000000, 0 },
/*123*/ { 0xE111111111111111, 0 },
/*124*/ { 0xF000000000000000, 0 },
/*125*/ { 0xFFFFFFFFFFFFFFFF, 0 },
};
int data_size = ARRAY_SIZE(data);
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
ret = clz_u64(data[i].s);
assert_equal(ret, data[i].ret, "i:%d 0x%lX ret %d != %d\n", i, data[i].s, ret, data[i].ret);
}
testFinish();
}
static void test_load(int index, int debug) {
testStart("");
int ret;
struct item {
large_int t;
large_int s;
large_int expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { LI(0, 0), LI(0, 0), LI(0, 0) },
/* 1*/ { LI(1, 1), LI(0, 0), LI(0, 0) },
/* 2*/ { LI(0, 0), LI(1, 2), LI(1, 2) },
/* 3*/ { LI(1, 1), LI(2, 3), LI(2, 3) },
};
int data_size = ARRAY_SIZE(data);
char t_dump[35];
char expected_dump[35];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
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",
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",
i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump));
}
testFinish();
}
static void test_load_str_u64(int index, int debug) {
testStart("");
int ret;
struct item {
large_int t;
const unsigned char *s;
int length;
large_int expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { LI(0, 0), "0", -1, LI(0, 0) },
/* 1*/ { LI(0, 1), "1", -1, LI(1, 0) },
/* 2*/ { LI(1, 1), "4294967296", -1, LI(4294967296, 0) },
/* 3*/ { LI(1, 1), "18446744073709551615", -1, LI(0xFFFFFFFFFFFFFFFF, 0) },
/* 4*/ { LI(1, 1), "18446744073709551616", -1, LI(0, 0) }, // Overflow 18446744073709551616 == 2^64 == 0
/* 5*/ { LI(2, 2), "123", 2, LI(12, 0) }, // Only reads up to length
/* 6*/ { LI(2, 2), "123A1X", -1, LI(123, 0) }, // Only reads decimal
};
int data_size = ARRAY_SIZE(data);
char t_dump[35];
char expected_dump[35];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
large_load_str_u64(&data[i].t, 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",
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",
i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump));
}
testFinish();
}
static void test_add_u64(int index, int debug) {
testStart("");
int ret;
struct item {
large_int t;
uint64_t s;
large_int expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { LI(0, 0), 0, LI(0, 0) },
/* 1*/ { LI(1, 0), 0, LI(1, 0) },
/* 2*/ { LI(0, 1), 0, LI(0, 1) },
/* 3*/ { LI(1, 0), 1, LI(2, 0) },
/* 4*/ { LI(1, 1), 0xFFFFFFFFFFFFFFFF, LI(0, 2) },
/* 5*/ { LI(1, 1), 2, LI(3, 1) },
/* 6*/ { LI(0xFFFFFFFFFFFFFFFF, 1), 1, LI(0, 2) },
/* 7*/ { LI(0xFFFFFFFFFFFFFFFE, 100), 4, LI(2, 101) },
/* 8*/ { LI(0xFFFFFFFFFFFFFF0E, 0xFFFFFE), 0xFF, LI(0xD, 0xFFFFFF) },
/* 9*/ { LI(0xFFFFFFFF00000001, 0xFFFFFFFF), 0xFFFFFFFF, LI(0, 0x100000000) },
/* 10*/ { LI(0x0000000000000001, 0xFFFFFFFFFFFFFFFF), 0xFFFFFFFFFFFFFFFF, LI(0, 0) }, // Overflow
};
int data_size = ARRAY_SIZE(data);
char t_dump[35];
char expected_dump[35];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
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",
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",
i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump));
}
testFinish();
}
static void test_sub_u64(int index, int debug) {
testStart("");
int ret;
struct item {
large_int t;
uint64_t s;
large_int expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { LI(0, 0), 0, LI(0, 0) },
/* 1*/ { LI(1, 0), 0, LI(1, 0) },
/* 2*/ { LI(0, 1), 0, LI(0, 1) },
/* 3*/ { LI(1, 0), 1, LI(0, 0) },
/* 4*/ { LI(0xFFFFFFFFFFFFFFFF, 1), 0xFFFFFFFFFFFFFFFF, LI(0, 1) },
/* 5*/ { LI(0xFFFFFFFFFFFFFFFE, 1), 0xFFFFFFFFFFFFFFFF, LI(0xFFFFFFFFFFFFFFFF, 0) },
/* 6*/ { LI(1, 1), 0xFFFFFFFFFFFFFFFF, LI(2, 0) },
/* 7*/ { LI(1, 1), 0xFFFFFFFFFFFFFFFE, LI(3, 0) },
/* 8*/ { LI(2, 0xFFFFFFFFFFFFFFFF), 0xFFFFFFFFFFFFFFFF, LI(3, 0xFFFFFFFFFFFFFFFE) },
/* 9*/ { LI(2, 0xFFFFFFFFFFFFFFFF), 0xFFFFFFFFFFFFFFFE, LI(4, 0xFFFFFFFFFFFFFFFE) },
/* 10*/ { LI(0, 0), 1, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
};
int data_size = ARRAY_SIZE(data);
char t_dump[35];
char expected_dump[35];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
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",
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",
i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump));
}
testFinish();
}
static void test_mul_u64(int index, int debug) {
testStart("");
int ret;
struct item {
large_int t;
uint64_t s;
large_int expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { LI(0, 0), 0, LI(0, 0) },
/* 1*/ { LI(1, 0), 0, LI(0, 0) },
/* 2*/ { LI(0, 1), 0, LI(0, 0) },
/* 3*/ { LI(1, 0), 1, LI(1, 0) },
/* 4*/ { LI(0, 1), 1, LI(0, 1) },
/* 5*/ { LI(1, 1), 2, LI(2, 2) },
/* 6*/ { LI(3, 0x64), 3, LI(9, 0x12C) },
/* 7*/ { LI(0x5555555555555555, 0x5555555555555555), 3, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 8*/ { LI(432, 518), 4, LI(1728, 2072) },
/* 9*/ { LI(0x4000000000000000, 0), 4, LI(0, 1) },
/* 10*/ { LI(0xFFFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF), 4, LI(0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF) },
/* 11*/ { LI(0x3333333333333333, 0x111), 5, LI(0xFFFFFFFFFFFFFFFF, 0x555) },
/* 12*/ { LI(0x3333333333333334, 0x111), 5, LI(4, 0x556) },
/* 13*/ { LI(0x2222222222222222, 0x2222222222222222), 8, LI(0x1111111111111110, 0x1111111111111111) }, // Overflow
/* 14*/ { LI(432, 518), 10, LI(4320, 5180) },
/* 15*/ { LI(0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCC), 20, LI(0xFFFFFFFFFFFFFFF0, 0xFFFFFFFFFFFFFFFF) },
/* 16*/ { LI(432, 518), 100, LI(43200, 51800) },
/* 17*/ { LI(0x123456789ABCDEF0, 0x123456789ABCDE), 0xE0F, LI(0xEDCBA98765423010, 0xFFEDCBA987653601) },
/* 18*/ { LI(0xFFFFFFFFFFFFFFFF, 1), 2, LI(0xFFFFFFFFFFFFFFFE, 3) },
/* 19*/ { LI(0xFFFFFFFFFFFFFFFF, 1), 10, LI(0xFFFFFFFFFFFFFFF6, 19) },
/* 20*/ { LI(0xFFFFFFFFFFFFFFFF, 1), 0x1234567890ABCDEF, LI(0xEDCBA9876F543211, 0x2468ACF121579BDD) },
/* 21*/ { LI(0xFFFFFFFFFFFFFFFF, 0xCF), 0x123456789ABCDEF, LI(0xFEDCBA9876543211, 0xECA8641FDB97522F) },
/* 22*/ { LI(0xFFFFFFFFFFFFFFFF, 0x123456), 0x123456789AB, LI(0xFFFFFEDCBA987655, 0x14B66E5D4C2C851C) },
/* 23*/ { LI(0xFFFFFFFFFFFFFFFF, 0), 0xFFFFFFFFFFFFFFFF, LI(1, 0xFFFFFFFFFFFFFFFE) },
};
int data_size = ARRAY_SIZE(data);
char t_dump[35];
char expected_dump[35];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
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",
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",
i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump));
}
testFinish();
}
static void test_div_u64(int index, int debug) {
testStart("");
uint64_t r;
struct item {
large_int t;
uint64_t s;
uint64_t expected_r;
large_int expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { LI(0, 0), 1, 0, LI(0, 0) },
/* 1*/ { LI(1, 0), 1, 0, LI(1, 0) },
/* 2*/ { LI(4990000, 0), 509999, 400009, LI(9, 0) },
/* 3*/ { LI(3, 0), 2, 1, LI(1, 0) }, // BEGIN divmnu64.c.txt (first 3 errors)
/* 4*/ { LI(3, 0), 3, 0, LI(1, 0) },
/* 5*/ { LI(3, 0), 4, 3, LI(0, 0) },
/* 6*/ { LI(0, 0), 0xFFFFFFFF, 0, LI(0, 0) },
/* 7*/ { LI(0xFFFFFFFF, 0), 1, 0, LI(0xFFFFFFFF, 0) },
/* 8*/ { LI(0xFFFFFFFF, 0), 0xFFFFFFFF, 0, LI(1, 0) },
/* 9*/ { LI(0xFFFFFFFF, 0), 3, 0, LI(0x55555555, 0) },
/* 10*/ { LI(0xFFFFFFFFFFFFFFFF, 0), 1, 0, LI(0xFFFFFFFFFFFFFFFF, 0) },
/* 11*/ { LI(0xFFFFFFFFFFFFFFFF, 0), 0xFFFFFFFF, 0, LI(0x100000001, 0) },
/* 12*/ { LI(0xFFFFFFFEFFFFFFFF, 0), 0xFFFFFFFF, 0xFFFFFFFE, LI(0xFFFFFFFF, 0) },
/* 13*/ { LI(0x0000123400005678, 0), 0x00009ABC, 0x6BD0, LI(0x1E1DBA76, 0) },
/* 14*/ { LI(0, 0), 0x100000000, 0, LI(0, 0) },
/* 15*/ { LI(0x700000000, 0), 0x300000000, 0x100000000, LI(2, 0) },
/* 16*/ { LI(0x700000005, 0), 0x300000000, 0x100000005, LI(2, 0) },
/* 17*/ { LI(0x600000000, 0), 0x200000000, 0, LI(3, 0) },
/* 18*/ { LI(0x80000000, 0), 0x40000001, 0x3FFFFFFF, LI(1, 0) },
/* 19*/ { LI(0x8000000000000000, 0), 0x40000001, 8, LI(0x1FFFFFFF8, 0) },
/* 20*/ { LI(0x8000000000000000, 0), 0x4000000000000001, 0x3FFFFFFFFFFFFFFF, LI(1, 0) },
/* 21*/ { LI(0x0000BCDE0000789A, 0), 0x0000BCDE0000789A, 0, LI(1, 0) },
/* 22*/ { LI(0x0000BCDE0000789B, 0), 0x0000BCDE0000789A, 1, LI(1, 0) },
/* 23*/ { LI(0x0000BCDE00007899, 0), 0x0000BCDE0000789A, 0x0000BCDE00007899, LI(0, 0) },
/* 24*/ { LI(0x0000FFFF0000FFFF, 0), 0x0000FFFF0000FFFF, 0, LI(1, 0) },
/* 25*/ { LI(0x0000FFFF0000FFFF, 0), 0x100000000, 0x0000FFFF, LI(0x0000FFFF, 0) },
/* 26*/ { LI(0x00004567000089AB, 0x00000123), 0x100000000, 0x000089AB, LI(0x0000012300004567, 0) },
/* 27*/ { LI(0x0000FFFE00000000, 0x00008000), 0x000080000000FFFF, 0x7FFF0000FFFF, LI(0xFFFFFFFF, 0) }, // END divmnu64.c.txt (last 6 96-bit divisor); shows that first qhat0 can = b + 1
/* 28*/ { LI(0, 0x80000000FFFE0000), 0x80000000FFFF0000, 0x1FFFE00000000, LI(0xFFFFFFFFFFFE0000, 0) }, // Shows that first qhat1 can = b + 1
/* 29*/ { LI(0xFFFE000000000000, 0x80000000), 0x80000000FFFF0000, 0x7FFF0000FFFF0000, LI(0xFFFFFFFF, 0) }, // First qhat0 = b + 1
/* 30*/ { LI(0x7FFF800000000000, 0), 0x800000000001, 0x7FFFFFFF0002, LI(0xFFFE, 0) }, // "add back" examples won't trigger as divisor only 2 digits (in 2**32 base)
/* 31*/ { LI(0, 0x7FFF800000000000), 0x800000000001, 0x1FFFE0000, LI(0xFFFFFFFE00020000, 0xFFFE) },
/* 32*/ { LI(0x0000000000000003, 0x80000000), 0x2000000000000001, 0x1FFFFFFC00000004, LI(0x3FFFFFFFF, 0) },
/* 33*/ { LI(0x0000000000000003, 0x00008000), 0x2000000000000001, 0x1FFFFFFFFFFC0004, LI(0x3FFFF, 0) },
/* 34*/ { LI(0x8000000000000003, 0), 0x2000000000000001, 0x2000000000000000, LI(3, 0) },
/* 35*/ { LI(0x0000000000000000, 0x00007FFF00008000), 0x8000000000000001, 0x7FFF0001FFFF0001, LI(0xFFFE0000FFFF, 0) },
/* 36*/ { LI(0xFFFFFFFFFFFFFFFF, 0), 0xFFFFFFFFFFFFFFFF, 0, LI(1, 0) },
/* 37*/ { LI(0, 1), 1, 0, LI(0, 1) },
/* 38*/ { LI(1, 1), 1, 0, LI(1, 1) },
/* 39*/ { LI(1, 1), 2, 1, LI(0x8000000000000000, 0) },
/* 40*/ { LI(2, 1), 2, 0, LI(0x8000000000000001, 0) },
/* 41*/ { LI(3, 1), 3, 1, LI(0x5555555555555556, 0) },
/* 42*/ { LI(0, 1), 3, 1, LI(0x5555555555555555, 0) },
/* 43*/ { LI(1, 1), 3, 2, LI(0x5555555555555555, 0) },
/* 44*/ { LI(0, 7), 3, 1, LI(0x5555555555555555, 2) },
/* 45*/ { LI(5, 7), 3, 0, LI(0x5555555555555557, 2) },
/* 46*/ { LI(0, 10), 3, 1, LI(0x5555555555555555, 3) },
/* 47*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFE), 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFE, LI(0xFFFFFFFF, 0) },
/* 48*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 3, 0, LI(0x5555555555555555, 0x5555555555555555) },
/* 49*/ { LI(0x0000000100000000, 0), 3, 1, LI(0x55555555, 0) },
/* 50*/ { LI(0, 0x0000000100000000), 3, 1, LI(0x5555555555555555, 0x55555555) },
/* 51*/ { LI(0x0000000100000000, 0x0000000100000000), 3, 2, LI(0x55555555AAAAAAAA, 0x55555555) },
/* 52*/ { LI(0x0000000100000001, 0x0000000100000001), 3, 1, LI(0xAAAAAAAB00000000, 0x55555555) },
/* 53*/ { LI(0x7C54A8E022961911, 0x92940F87B13D9529), 0xF09B387392497535, 0x3A5BBDA3D6EBF8D7, LI(0x9BF4CCB73D412892, 0) },
/* 54*/ { LI(0x57BC33D2FAB596C9, 0x63F589EB9FB6C96), 0x90B9A0DB6A5F, 0x43555745A6D4, LI(0x957BE34B1882E2B, 0xB0D) },
/* 55*/ { LI(0x1000000000000000, 0x1000000000000000), 0x10000000, 0, LI(0x100000000, 0x100000000) },
/* 56*/ { LI(0x1000000000000001, 0x1000000000000001), 0x10000000, 1, LI(0x1100000000, 0x100000000) },
/* 57*/ { LI(0x1000000000000001, 0x1000000000000001), 0x10000001, 0x1111, LI(0x110FFFFEEF0, 0xFFFFFFF0) },
/* 58*/ { LI(0x99999999999999BF, 0x9999999999999999), 0x5555555567, 0x3331D64530, LI(0xCC6D6666667A2699, 0x1CCCCCC) },
/* 59*/ { LI(0, 0xFFFFFFFFFFFFFFFF), 0x200000000, 0, LI(0xFFFFFFFF80000000, 0x7FFFFFFF) },
/* 60*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x200000000, 0x1FFFFFFFF, LI(0xFFFFFFFFFFFFFFFF, 0x7FFFFFFF) },
/* 61*/ { LI(0, 0xFFFFFFFFFFFFFFFF), 0x300000000, 0, LI(0x5555555500000000, 0x55555555) },
/* 62*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x300000000, 0xFFFFFFFF, LI(0x5555555555555555, 0x55555555) },
/* 63*/ { LI(0x0000000300000004, 0x0000000100000002), 0x200000003, 0x40000001, LI(0x8000000040000001, 0) },
/* 64*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x2000000000000000, 0x1FFFFFFFFFFFFFFF, LI(0xFFFFFFFFFFFFFFFF, 7) },
/* 65*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x3000000000000000, 0xFFFFFFFFFFFFFFF, LI(0x5555555555555555, 5) },
/* 66*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0xFFFFFFFFFFFFFFFF, 0, LI(1, 1) },
/* 67*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFEFFFFFFFF), 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFEFFFFFFFF, LI(0xFFFFFFFF00000000, 0) },
/* 68*/ { LI(0x00000F70677372AE, 0), 0x453AF5, 0, LI(0x391736, 0) }, // Divisor 0x453AF5 (4537077) used by RSS14
/* 69*/ { LI(0x00000F70677372AF, 0), 0x453AF5, 1, LI(0x391736, 0) },
/* 70*/ { LI(0x00000F70677372B0, 0), 0x453AF5, 2, LI(0x391736, 0) },
/* 71*/ { LI(0x453AF4, 0), 0x453AF5, 0x453AF4, LI(0, 0) },
/* 72*/ { LI(0x453AF5, 0), 0x453AF5, 0, LI(1, 0) },
/* 73*/ { LI(0x453AF6, 0), 0x453AF5, 1, LI(1, 0) },
/* 74*/ { { 0x453AF5 * 10 - 1, 0 }, 0x453AF5, 0x453AF4, LI(9, 0) },
/* 75*/ { LI(0x000003A03166E0CE, 0), 0x1EB983, 0x1EB982, LI(0x1E35C4, 0) }, // Divisor 0x1EB983 (2013571) used by RSS_LTD
/* 76*/ { LI(0x000003A03166E0CF, 0), 0x1EB983, 0, LI(0x1E35C5, 0) },
/* 77*/ { LI(0x000003A03166E0D0, 0), 0x1EB983, 1, LI(0x1E35C5, 0) },
/* 78*/ { LI(0x93BB793904CAFFFF, 0x13F50B74), 32, 0x1F, LI(0xA49DDBC9C82657FF, 0x9FA85B) }, // Divisor 32 used by MAILMARK
/* 79*/ { LI(0x93BB793904CB0000, 0x13F50B74), 32, 0, LI(0xA49DDBC9C8265800, 0x9FA85B) },
/* 80*/ { LI(0x93BB793904CB0001, 0x13F50B74), 32, 1, LI(0xA49DDBC9C8265800, 0x9FA85B) },
/* 81*/ { LI(0x93BB793904CAFFFF, 0x13F50B74), 30, 0x1D, LI(0x8D752EB519C27FFF, 0xAA4D2E) }, // Divisor 30 used by MAILMARK
/* 82*/ { LI(0x93BB793904CB0000, 0x13F50B74), 30, 0, LI(0x8D752EB519C28000, 0xAA4D2E) },
/* 83*/ { LI(0x93BB793904CB0001, 0x13F50B74), 30, 1, LI(0x8D752EB519C28000, 0xAA4D2E) },
/* 84*/ { LI(0x4ABC16A2E5C005FF, 0x16907B2A2), 636, 635, LI(0xD70F9761AA390E7F, 0x9151FD) }, // Divisor 636 used by ONECODE
/* 85*/ { LI(0x4ABC16A2E5C00600, 0x16907B2A2), 636, 0, LI(0xD70F9761AA390E80, 0x9151FD) },
/* 86*/ { LI(0x4ABC16A2E5C00601, 0x16907B2A2), 636, 1, LI(0xD70F9761AA390E80, 0x9151FD) },
/* 87*/ { LI(0x4ABC16A2E5C00734, 0x16907B2A2), 1365, 1364, LI(0xD93B96FDAE65FA60, 0x43B5AC) }, // Divisor 1365 used by ONECODE
/* 88*/ { LI(0x4ABC16A2E5C00735, 0x16907B2A2), 1365, 0, LI(0xD93B96FDAE65FA61, 0x43B5AC) },
/* 89*/ { LI(0x4ABC16A2E5C00736, 0x16907B2A2), 1365, 1, LI(0xD93B96FDAE65FA61, 0x43B5AC) },
};
int data_size = ARRAY_SIZE(data);
char t_dump[35];
char expected_dump[35];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
r = large_div_u64(&data[i].t, data[i].s);
assert_equal(r, data[i].expected_r, "i:%d r %lu (0x%lX) != expected_r %lu (0x%lX)\n", i, r, r, data[i].expected_r, data[i].expected_r);
assert_equal(data[i].t.lo, data[i].expected.lo, "i:%d lo 0x%lX (%s) != expected lo 0x%lX (%s)\n",
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",
i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump));
}
testFinish();
}
static void test_unset_bit(int index, int debug) {
testStart("");
int ret;
struct item {
large_int t;
int s;
large_int expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { LI(0, 0), 0, LI(0, 0) },
/* 1*/ { LI(0, 0xFFFFFFFFFFFFFFFF), 0, LI(0, 0xFFFFFFFFFFFFFFFF) },
/* 2*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0, LI(0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF) },
/* 3*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 1, LI(0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF) },
/* 4*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 2, LI(0xFFFFFFFFFFFFFFFB, 0xFFFFFFFFFFFFFFFF) },
/* 5*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 3, LI(0xFFFFFFFFFFFFFFF7, 0xFFFFFFFFFFFFFFFF) },
/* 6*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 4, LI(0xFFFFFFFFFFFFFFEF, 0xFFFFFFFFFFFFFFFF) },
/* 7*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 5, LI(0xFFFFFFFFFFFFFFDF, 0xFFFFFFFFFFFFFFFF) },
/* 8*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 6, LI(0xFFFFFFFFFFFFFFBF, 0xFFFFFFFFFFFFFFFF) },
/* 9*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 7, LI(0xFFFFFFFFFFFFFF7F, 0xFFFFFFFFFFFFFFFF) },
/* 10*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 8, LI(0xFFFFFFFFFFFFFEFF, 0xFFFFFFFFFFFFFFFF) },
/* 11*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 9, LI(0xFFFFFFFFFFFFFDFF, 0xFFFFFFFFFFFFFFFF) },
/* 12*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 10, LI(0xFFFFFFFFFFFFFBFF, 0xFFFFFFFFFFFFFFFF) },
/* 13*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 11, LI(0xFFFFFFFFFFFFF7FF, 0xFFFFFFFFFFFFFFFF) },
/* 14*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 12, LI(0xFFFFFFFFFFFFEFFF, 0xFFFFFFFFFFFFFFFF) },
/* 15*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 13, LI(0xFFFFFFFFFFFFDFFF, 0xFFFFFFFFFFFFFFFF) },
/* 16*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 14, LI(0xFFFFFFFFFFFFBFFF, 0xFFFFFFFFFFFFFFFF) },
/* 17*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 15, LI(0xFFFFFFFFFFFF7FFF, 0xFFFFFFFFFFFFFFFF) },
/* 18*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 16, LI(0xFFFFFFFFFFFEFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 19*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 17, LI(0xFFFFFFFFFFFDFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 20*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 18, LI(0xFFFFFFFFFFFBFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 21*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 19, LI(0xFFFFFFFFFFF7FFFF, 0xFFFFFFFFFFFFFFFF) },
/* 22*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 20, LI(0xFFFFFFFFFFEFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 23*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 21, LI(0xFFFFFFFFFFDFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 24*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 22, LI(0xFFFFFFFFFFBFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 25*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 23, LI(0xFFFFFFFFFF7FFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 26*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 24, LI(0xFFFFFFFFFEFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 27*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 25, LI(0xFFFFFFFFFDFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 28*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 26, LI(0xFFFFFFFFFBFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 29*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 27, LI(0xFFFFFFFFF7FFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 30*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 28, LI(0xFFFFFFFFEFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 31*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 29, LI(0xFFFFFFFFDFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 32*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 30, LI(0xFFFFFFFFBFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 33*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 31, LI(0xFFFFFFFF7FFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 34*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 32, LI(0xFFFFFFFEFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 35*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 33, LI(0xFFFFFFFDFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 36*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 34, LI(0xFFFFFFFBFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 37*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 35, LI(0xFFFFFFF7FFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 38*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 36, LI(0xFFFFFFEFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 39*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 37, LI(0xFFFFFFDFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 40*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 38, LI(0xFFFFFFBFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 41*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 39, LI(0xFFFFFF7FFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 42*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 40, LI(0xFFFFFEFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 43*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 41, LI(0xFFFFFDFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 44*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 42, LI(0xFFFFFBFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 45*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 43, LI(0xFFFFF7FFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 46*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 44, LI(0xFFFFEFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 47*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 45, LI(0xFFFFDFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 48*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 46, LI(0xFFFFBFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 49*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 47, LI(0xFFFF7FFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 50*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 48, LI(0xFFFEFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 51*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 49, LI(0xFFFDFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 52*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 50, LI(0xFFFBFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 53*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 51, LI(0xFFF7FFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 54*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 52, LI(0xFFEFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 55*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 53, LI(0xFFDFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 56*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 54, LI(0xFFBFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 57*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 55, LI(0xFF7FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 58*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 56, LI(0xFEFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 59*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 57, LI(0xFDFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 60*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 58, LI(0xFBFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 61*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 59, LI(0xF7FFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 62*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 60, LI(0xEFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 63*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 61, LI(0xDFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 64*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 62, LI(0xBFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 65*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 63, LI(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
/* 66*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 64, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE) },
/* 67*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 65, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFD) },
/* 68*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 66, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFB) },
/* 69*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 67, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFF7) },
/* 70*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 68, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFEF) },
/* 71*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 69, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFDF) },
/* 72*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 70, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFBF) },
/* 73*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 71, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFF7F) },
/* 74*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 72, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFEFF) },
/* 75*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 73, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFDFF) },
/* 76*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 74, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFBFF) },
/* 77*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 75, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFF7FF) },
/* 78*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 76, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFEFFF) },
/* 79*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 77, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFDFFF) },
/* 80*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 78, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFBFFF) },
/* 81*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 79, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF7FFF) },
/* 82*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 80, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFEFFFF) },
/* 83*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 81, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFDFFFF) },
/* 84*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 82, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFBFFFF) },
/* 85*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 83, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFF7FFFF) },
/* 86*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 84, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFEFFFFF) },
/* 87*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 85, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFDFFFFF) },
/* 88*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 86, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFBFFFFF) },
/* 89*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 87, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFF7FFFFF) },
/* 90*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 88, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFEFFFFFF) },
/* 91*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 89, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFDFFFFFF) },
/* 92*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 90, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFBFFFFFF) },
/* 93*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 91, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFF7FFFFFF) },
/* 94*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 92, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFEFFFFFFF) },
/* 95*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 93, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFDFFFFFFF) },
/* 96*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 94, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFBFFFFFFF) },
/* 97*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 95, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF7FFFFFFF) },
/* 98*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 96, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFEFFFFFFFF) },
/* 99*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 97, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFDFFFFFFFF) },
/*100*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 98, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFBFFFFFFFF) },
/*101*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 99, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFF7FFFFFFFF) },
/*102*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 100, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFEFFFFFFFFF) },
/*103*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 101, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFDFFFFFFFFF) },
/*104*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 102, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFBFFFFFFFFF) },
/*105*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 103, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFF7FFFFFFFFF) },
/*106*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 104, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFEFFFFFFFFFF) },
/*107*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 105, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFDFFFFFFFFFF) },
/*108*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 106, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFBFFFFFFFFFF) },
/*109*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 107, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFF7FFFFFFFFFF) },
/*110*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 108, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFEFFFFFFFFFFF) },
/*111*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 109, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFDFFFFFFFFFFF) },
/*112*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 110, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFBFFFFFFFFFFF) },
/*113*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 111, LI(0xFFFFFFFFFFFFFFFF, 0xFFFF7FFFFFFFFFFF) },
/*114*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 112, LI(0xFFFFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFFF) },
/*115*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 113, LI(0xFFFFFFFFFFFFFFFF, 0xFFFDFFFFFFFFFFFF) },
/*116*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 114, LI(0xFFFFFFFFFFFFFFFF, 0xFFFBFFFFFFFFFFFF) },
/*117*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 115, LI(0xFFFFFFFFFFFFFFFF, 0xFFF7FFFFFFFFFFFF) },
/*118*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 116, LI(0xFFFFFFFFFFFFFFFF, 0xFFEFFFFFFFFFFFFF) },
/*119*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 117, LI(0xFFFFFFFFFFFFFFFF, 0xFFDFFFFFFFFFFFFF) },
/*120*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 118, LI(0xFFFFFFFFFFFFFFFF, 0xFFBFFFFFFFFFFFFF) },
/*121*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 119, LI(0xFFFFFFFFFFFFFFFF, 0xFF7FFFFFFFFFFFFF) },
/*122*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 120, LI(0xFFFFFFFFFFFFFFFF, 0xFEFFFFFFFFFFFFFF) },
/*123*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 121, LI(0xFFFFFFFFFFFFFFFF, 0xFDFFFFFFFFFFFFFF) },
/*124*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 122, LI(0xFFFFFFFFFFFFFFFF, 0xFBFFFFFFFFFFFFFF) },
/*125*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 123, LI(0xFFFFFFFFFFFFFFFF, 0xF7FFFFFFFFFFFFFF) },
/*126*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 124, LI(0xFFFFFFFFFFFFFFFF, 0xEFFFFFFFFFFFFFFF) },
/*127*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 125, LI(0xFFFFFFFFFFFFFFFF, 0xDFFFFFFFFFFFFFFF) },
/*128*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 126, LI(0xFFFFFFFFFFFFFFFF, 0xBFFFFFFFFFFFFFFF) },
/*129*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 127, LI(0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF) },
/*130*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 128, LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF) },
};
int data_size = ARRAY_SIZE(data);
char t_dump[35];
char expected_dump[35];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
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",
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",
i, data[i].t.hi, large_dump(&data[i].t, t_dump), data[i].expected.hi, large_dump(&data[i].expected, expected_dump));
}
testFinish();
}
static void test_uint_array(int index, int debug) {
testStart("");
int ret;
struct item {
large_int t;
int size;
int bits;
unsigned int expected[128];
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { LI(0, 0), 0, 0, { 0 } },
/* 1*/ { LI(1, 1), 16, 0, { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 } },
/* 2*/ { LI(1, 1), 15, 0, { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 } },
/* 3*/ { LI(0x1122334455667788, 0x99AABBCCDDEEFF01), 16, 0, { 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 } },
/* 4*/ { LI(0x1122334455667788, 0x99AABBCCDDEEFF01), 13, 0, { 0xCC, 0xDD, 0xEE, 0xFF, 0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 } },
/* 5*/ { LI(0x1122334455667788, 0x99AABBCCDDEEFF01), 6, 0, { 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 } },
/* 6*/ { LI(1, 1), 128, 1, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
/* 7*/ { LI(1, 1), 64, 2, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
/* 8*/ { LI(1, 1), 43, 3, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
/* 9*/ { LI(1, 1), 32, 4, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, } },
/* 10*/ { LI(1, 1), 26, 5, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
/* 11*/ { LI(0xAAAAAAAAAAAAAAAA, 0), 13, 5, { 0xA, 0x15, 0xA, 0x15, 0xA, 0x15, 0xA, 0x15, 0xA, 0x15, 0xA, 0x15, 0xA } },
/* 12*/ { LI(0x5555555555555555, 0), 13, 5, { 0x5, 0xA, 0x15, 0xA, 0x15, 0xA, 0x15, 0xA, 0x15, 0xA, 0x15, 0xA, 0x15 } },
/* 13*/ { LI(0x1122334455667788, 0x99AABBCCDDEEFF01), 26, 5, { 0x4, 0x19, 0x15, 0xA, 0x1D, 0x1C, 0x19, 0x17, 0xF, 0xE, 0x1F, 0x1C, 0x0, 0x11, 0x2, 0x8, 0x11, 0x13, 0x8, 0x11, 0xA, 0x16, 0xC, 0x1D, 0x1C, 0x8 } },
/* 14*/ { LI(1, 1), 22, 6, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
/* 15*/ { LI(1, 1), 19, 7, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1 } },
/* 16*/ { LI(1, 1), 15, 9, { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1 } },
/* 17*/ { LI(1, 1), 13, 10, { 0, 0, 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 1 } },
/* 18*/ { LI(1, 1), 12, 11, { 0, 0, 0, 0, 0, 0, 0x200, 0, 0, 0, 0, 1 } },
/* 19*/ { LI(1, 1), 11, 12, { 0, 0, 0, 0, 0, 0x10, 0, 0, 0, 0, 1 } },
/* 20*/ { LI(1, 1), 10, 13, { 0, 0, 0, 0, 0, 0x1000, 0, 0, 0, 1 } },
/* 21*/ { LI(1, 1), 10, 14, { 0, 0, 0, 0, 0, 0x100, 0, 0, 0, 1 } },
/* 22*/ { LI(1, 1), 9, 15, { 0, 0, 0, 0, 0x10, 0, 0, 0, 1 } },
/* 23*/ { LI(1, 1), 8, 16, { 0, 0, 0, 1, 0, 0, 0, 1 } },
/* 24*/ { LI(1, 1), 8, 17, { 0, 0, 0, 0, 0x2000, 0, 0, 1 } },
/* 25*/ { LI(1, 1), 8, 18, { 0, 0, 0, 0, 0x400, 0, 0, 1 } },
/* 26*/ { LI(1, 1), 7, 19, { 0, 0, 0, 0x80, 0, 0, 1 } },
/* 27*/ { LI(1, 1), 5, 31, { 0, 0, 4, 0, 1 } },
/* 28*/ { LI(1, 1), 4, 32, { 0, 1, 0, 1 } },
/* 29*/ { LI(1, 1), 4, 33, { 0, 1, 0, 1 } }, // Bits > 32 ignored and treated as 32
};
int data_size = ARRAY_SIZE(data);
char t_dump[35];
char uint_dump[128 * 3];
char uint_expected_dump[128 * 3];
char uchar_dump[128 * 3];
char uchar_expected_dump[128 * 3];
unsigned int uint_array[128];
unsigned char uchar_array[128];
unsigned char uchar_expected_array[128];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
memset(uint_array, 0, sizeof(uint_array));
large_uint_array(&data[i].t, uint_array, data[i].size, data[i].bits);
assert_zero(memcmp(uint_array, data[i].expected, data[i].size * sizeof(unsigned int)), "i:%d %s uint memcmp != 0\n actual: %s\nexpected: %s\n",
i, large_dump(&data[i].t, t_dump), testUtilUIntArrayDump(uint_array, data[i].size, uint_dump, sizeof(uint_dump)),
testUtilUIntArrayDump(data[i].expected, data[i].size, uint_expected_dump, sizeof(uint_expected_dump)));
if (data[i].bits <= 8) {
memset(uchar_array, 0, sizeof(uchar_array));
for (int j = 0; j < data[i].size; j++) {
uchar_expected_array[j] = data[i].expected[j];
}
large_uchar_array(&data[i].t, uchar_array, data[i].size, data[i].bits);
assert_zero(memcmp(uchar_array, uchar_expected_array, data[i].size), "i:%d %s uchar memcmp != 0\n actual: %s\nexpected: %s\n",
i, large_dump(&data[i].t, t_dump), testUtilUCharArrayDump(uchar_array, data[i].size, uchar_dump, sizeof(uchar_dump)),
testUtilUCharArrayDump(uchar_expected_array, data[i].size, uchar_expected_dump, sizeof(uchar_expected_dump)));
}
}
testFinish();
}
static void test_dump(int index, int debug) {
testStart("");
int ret;
struct item {
large_int t;
char *expected;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { LI(0, 0), "0x0" },
/* 1*/ { LI(1, 0), "0x1" },
/* 2*/ { LI(0x12, 0), "0x12" },
/* 3*/ { LI(0x123, 0), "0x123" },
/* 4*/ { LI(0x1234, 0), "0x1234" },
/* 5*/ { LI(0x12345, 0), "0x12345" },
/* 6*/ { LI(0x123456, 0), "0x123456" },
/* 7*/ { LI(0x1234567, 0), "0x1234567" },
/* 8*/ { LI(0x12345678, 0), "0x12345678" },
/* 9*/ { LI(0x123456789, 0), "0x123456789" },
/* 10*/ { LI(0x1234567890, 0), "0x1234567890" },
/* 11*/ { LI(0x12345678901, 0), "0x12345678901" },
/* 12*/ { LI(0x123456789012, 0), "0x123456789012" },
/* 13*/ { LI(0x1234567890123, 0), "0x1234567890123" },
/* 14*/ { LI(0x12345678901234, 0), "0x12345678901234" },
/* 15*/ { LI(0x123456789012345, 0), "0x123456789012345" },
/* 16*/ { LI(0x1234567890123456, 0), "0x1234567890123456" },
/* 17*/ { LI(0x1234567890123456, 1), "0x11234567890123456" },
/* 18*/ { LI(0x1234567890123456, 0x12), "0x121234567890123456" },
/* 19*/ { LI(0x1234567890123456, 0x123), "0x1231234567890123456" },
/* 20*/ { LI(0x1234567890123456, 0x1234), "0x12341234567890123456" },
/* 21*/ { LI(0x1234567890123456, 0x12345), "0x123451234567890123456" },
/* 22*/ { LI(0x1234567890123456, 0x123456), "0x1234561234567890123456" },
/* 23*/ { LI(0x1234567890123456, 0x1234567), "0x12345671234567890123456" },
/* 24*/ { LI(0x1234567890123456, 0x12345678), "0x123456781234567890123456" },
/* 25*/ { LI(0x1234567890123456, 0x123456789), "0x1234567891234567890123456" },
/* 26*/ { LI(0x1234567890123456, 0x1234567890), "0x12345678901234567890123456" },
/* 27*/ { LI(0x1234567890123456, 0x12345678901), "0x123456789011234567890123456" },
/* 28*/ { LI(0x1234567890123456, 0x123456789012), "0x1234567890121234567890123456" },
/* 29*/ { LI(0x1234567890123456, 0x1234567890123), "0x12345678901231234567890123456" },
/* 30*/ { LI(0x1234567890123456, 0x12345678901234), "0x123456789012341234567890123456" },
/* 31*/ { LI(0x1234567890123456, 0x123456789012345), "0x1234567890123451234567890123456" },
/* 32*/ { LI(0x1234567890123456, 0x1234567890123456), "0x12345678901234561234567890123456" },
/* 33*/ { LI(0, 1), "0x10000000000000000" },
/* 34*/ { LI(1, 1), "0x10000000000000001" },
/* 35*/ { LI(0, 0xFFFFFFFF), "0xFFFFFFFF0000000000000000" },
/* 36*/ { LI(0, 0xFFFFFFF000000000), "0xFFFFFFF0000000000000000000000000" },
/* 37*/ { LI(0, 0xFFFFFFFFFFFFFFFF), "0xFFFFFFFFFFFFFFFF0000000000000000" },
/* 38*/ { LI(0xFFFFFFFF, 0xFFFFFFFF), "0xFFFFFFFF00000000FFFFFFFF" },
/* 39*/ { LI(0xFFFFFFFF, 0xFFFFFFFF00000000), "0xFFFFFFFF0000000000000000FFFFFFFF" },
/* 40*/ { LI(0xFFFFFFFF, 0xFFFFFFFFFFFFFFFF), "0xFFFFFFFFFFFFFFFF00000000FFFFFFFF" },
/* 41*/ { LI(0xFFFFFFFF00000000, 0xFFFFFFFF), "0xFFFFFFFFFFFFFFFF00000000" },
/* 42*/ { LI(0xFFFFFFFF00000000, 0xFFFFFFFF00000000), "0xFFFFFFFF00000000FFFFFFFF00000000" },
/* 43*/ { LI(0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF), "0xFFFFFFFFFFFFFFFFFFFFFFFF00000000" },
/* 44*/ { LI(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" },
};
int data_size = ARRAY_SIZE(data);
char dump[35];
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
memset(dump, 0, sizeof(dump));
large_dump(&data[i].t, dump);
assert_zero(strcmp(dump, data[i].expected), "i:%d { %lX, %lX } strcmp(%s, %s) != 0\n",
i, (unsigned long) data[i].t.lo, (unsigned long) data[i].t.hi, dump, data[i].expected);
}
testFinish();
}
int main(int argc, char *argv[]) {
testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
{ "test_clz_u64", test_clz_u64, 1, 0, 1 },
{ "test_load", test_load, 1, 0, 1 },
{ "test_load_str_u64", test_load_str_u64, 1, 0, 1 },
{ "test_add_u64", test_add_u64, 1, 0, 1 },
{ "test_sub_u64", test_sub_u64, 1, 0, 1 },
{ "test_mul_u64", test_mul_u64, 1, 0, 1 },
{ "test_div_u64", test_div_u64, 1, 0, 1 },
{ "test_unset_bit", test_unset_bit, 1, 0, 1 },
{ "test_uint_array", test_uint_array, 1, 0, 1 },
{ "test_dump", test_dump, 1, 0, 1 },
};
testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
testReport();
return 0;
}

View File

@ -53,10 +53,50 @@ static void test_input(int index, int debug) {
/* 7*/ { "01F0000000000AA000AA0A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // 3rd char class 0-9A-E only
/* 8*/ { "0100A00000000AA000AA0A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // 4-5th chars chain id 2 digits
/* 9*/ { "010000000000AAA000AA0A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // 6-13th chars item id 8 digits
/* 10*/ { "010000000000 AA000AA0A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // Remaining chars post code, TODO: test various types
/* 11*/ { "01000000000000000AA000AA0A", 0, 3, 155, }, // Length 26, Mailmark L (6 digit chain id)
/* 12*/ { "010A0000000000000AA000AA0A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // 4-9th chars chain id 6 digits
/* 13*/ { "010A000000000000AAA000AA0A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // Post code
/* 10*/ { "0100000000000 A000AA0A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // Remaining chars post code
/* 11*/ { "0100000000000C1I2JQ3N ", 0, 3, 131, }, // F N F N L L N L S
/* 12*/ { "010000000000091I2JQ3N ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N F N L L N L S bad 1st F
/* 13*/ { "0100000000000CAI2JQ3N ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N F N L L N L S bad 1st N
/* 14*/ { "0100000000000C1I2IQ3N ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N F N L L N L S bad 1st L
/* 15*/ { "0100000000000C1I2IQ3NA", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N F N L L N L S bad S
/* 16*/ { "0100000000000KM12JQ3N ", 0, 3, 131, }, // F F N N L L N L S
/* 17*/ { "0100000000000K 12JQ3N ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N N L L N L S bad 2nd F (non-numeric otherwise matches last pattern)
/* 18*/ { "0100000000000KM1AJQ3N ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N N L L N L S bad 2nd N
/* 19*/ { "0100000000000KM12JO3N ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N N L L N L S bad 2nd L
/* 20*/ { "0100000000000KM12JQ3NA", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N N L L N L S bad S
/* 21*/ { "0100000000000OV123JQ4U", 0, 3, 131, }, // F F N N N L L N L
/* 22*/ { "01000000000009V123JQ4U", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N N N L L N L bad 1st F
/* 23*/ { "0100000000000OV12AJQ4U", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N N N L L N L bad 3rd N
/* 24*/ { "0100000000000OV123JQ4V", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N N N L L N L bad 3rd L
/* 25*/ { "0100000000000CI1K3JQ4U", 0, 3, 131, }, // F F N F N L L N L
/* 26*/ { "0100000000000CI1 3JQ4U", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N F N L L N L bad 3rd F (non-numeric otherwise matches pattern above)
/* 27*/ { "0100000000000CIAK3JQ4U", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N F N L L N L bad 1st N
/* 28*/ { "0100000000000CI1K3CQ4U", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N F N L L N L bad 1st L
/* 29*/ { "0100000000000C12JQ3U ", 0, 3, 131, }, // F N N L L N L S S
/* 30*/ { "0100000000000912JQ3U ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N L L N L S S bad F
/* 31*/ { "0100000000000C1AJQ3U ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N L L N L S S bad 2nd N
/* 32*/ { "0100000000000C12JO3U ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N L L N L S S bad 2nd L
/* 33*/ { "0100000000000C12JQ3UA ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N L L N L S S bad 1st S
/* 34*/ { "0100000000000C123JQ4U ", 0, 3, 131, }, // F N N N L L N L S
/* 35*/ { "01000000000009123JQ4U ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N N L L N L S bad F
/* 36*/ { "0100000000000C12AJQ4U ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N N L L N L S bad 3rd N
/* 37*/ { "0100000000000C123JQ4V ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N N L L N L S bad 3rd L
/* 38*/ { "0100000000000C123JQ4U1", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N N L L N L S bad S
/* 39*/ { "01000000000000000AA000AA0A", 0, 3, 155, }, // Length 26, Mailmark L (6 digit chain id)
/* 40*/ { "010A0000000000000AA000AA0A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // 4-9th chars chain id 6 digits
/* 41*/ { "010A0000000000000 A000AA0A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // Post code
/* 42*/ { "01000000000000000C1I2JQ3N ", 0, 3, 155, }, // F N F N L L N L S
/* 43*/ { "01000000000000000C1 2JQ3N ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N F N L L N L S bad 2nd F
/* 44*/ { "01000000000000000KM12JQ3N ", 0, 3, 155, }, // F F N N L L N L S
/* 45*/ { "01000000000000000KM12JQAN ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N N L L N L S bad 3rd N
/* 46*/ { "01000000000000000OV123JQ4U", 0, 3, 155, }, // F F N N N L L N L
/* 47*/ { "01000000000000000OV123IQ4U", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N N N L L N L bad 1st L
/* 48*/ { "01000000000000000CI1K3JQ4U", 0, 3, 155, }, // F F N F N L L N L
/* 49*/ { "010000000000000009I1K3JQ4U", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F F N F N L L N L bad 1st F
/* 50*/ { "01000000000000000C12JQ3U ", 0, 3, 155, }, // F N N L L N L S S
/* 51*/ { "01000000000000000C12JQ3U A", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N L L N L S S bad 2nd S
/* 52*/ { "01000000000000000C123JQ4U ", 0, 3, 155, }, // F N N N L L N L S
/* 53*/ { "01000000000000000C 23JQ4U ", ZINT_ERROR_INVALID_DATA, -1, -1 }, // F N N N L L N L S bad 1st N (non-alpha otherwise matches 2nd pattern)
};
int data_size = ARRAY_SIZE(data);
@ -83,6 +123,8 @@ static void test_input(int index, int debug) {
testFinish();
}
// Royal Mail Mailmark barcode C encoding and decoding (Sep 2015) RMMBCED
// https://www.royalmail.com/sites/default/files/Mailmark-4-state-barcode-C-encoding-and-decoding-instructions-Sept-2015.pdf
// Royal Mail Mailmark barcode L encoding and decoding (Sep 2015) RMMBLED
// https://www.royalmail.com/sites/default/files/Mailmark-4-state-barcode-L-encoding-and-decoding-instructions-Sept-2015.pdf
static void test_encode_vector(int index, int debug) {
@ -98,14 +140,28 @@ static void test_encode_vector(int index, int debug) {
int ret_vector;
unsigned char *expected_daft;
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<"))
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { "0100000000000AA000AA0A", 0, 100, 30, 0, "TFATTADAAATAFAFADFTAFATDTTDTTAAFTTFFTTDFTTFFTTAFADFDFAAFTDDFDADDAA" },
/* 1*/ { "0100000000009JA500AA0A", 0, 100, 30, 0, "TAFTTDADATTFDTFDFDFDTAATADADTTTATTFTDDDDTATDATDFTFFATAFFAFADAFFTDT" },
/* 2*/ { "1100000000000XY11 ", 0, 100, 30, 0, "TTDTTATTDTAATTDTAATTDTAATTDTTDDAATAADDATAATDDFAFTDDTAADDDTAAFDFAFF" },
/* 3*/ { "21B2254800659JW5O9QA6Y", 0, 100, 30, 0, "DAATATTTADTAATTFADDDDTTFTFDDDDFFDFDAFTADDTFFTDDATADTTFATTDAFDTFDDA" },
/* 4*/ { "11000000000000000XY11 ", 0, 100, 30, 0, "TTDTTATDDTTATTDTAATTDTAATDDTTATTDTTDATFTAATDDTAATDDTATATFAADDAATAATDDTAADFTFTA" }, // Example from RMMBLED
/* 5*/ { "41038422416563762EF61AH8T", 0, 100, 30, 0, "DTTFATTDDTATTTATFTDFFFTFDFDAFTTTADTTFDTFDDDTDFDDFTFAADTFDTDTDTFAATAFDDTAATTDTT" }, // Example from RMMBLED
/* 0*/ { "1100000000000XY11 ", 0, 100, 30, 0, "TTDTTATTDTAATTDTAATTDTAATTDTTDDAATAADDATAATDDFAFTDDTAADDDTAAFDFAFF" }, // Example 1 from RMMBCED
/* 1*/ { "21B2254800659JW5O9QA6Y", 0, 100, 30, 0, "DAATATTTADTAATTFADDDDTTFTFDDDDFFDFDAFTADDTFFTDDATADTTFATTDAFDTFDDA" }, // Example 2 from RMMBCED
/* 2*/ { "11000000000000000XY11 ", 0, 100, 30, 0, "TTDTTATDDTTATTDTAATTDTAATDDTTATTDTTDATFTAATDDTAATDDTATATFAADDAATAATDDTAADFTFTA" }, // Example 1 from RMMBLED
/* 3*/ { "41038422416563762EF61AH8T", 0, 100, 30, 0, "DTTFATTDDTATTTATFTDFFFTFDFDAFTTTADTTFDTFDDDTDFDDFTFAADTFDTDTDTFAATAFDDTAATTDTT" }, // Example 2 from RMMBLED
/* 4*/ { "0100000000000AA000AA0A", 0, 100, 30, 0, "TFATTADAAATAFAFADFTAFATDTTDTTAAFTTFFTTDFTTFFTTAFADFDFAAFTDDFDADDAA" },
/* 5*/ { "0100000000009JA500AA0A", 0, 100, 30, 0, "TAFTTDADATTFDTFDFDFDTAATADADTTTATTFTDDDDTATDATDFTFFATAFFAFADAFFTDT" },
/* 6*/ { "1234567890123C1I2JQ3N ", 0, 100, 30, 0, "TTDTDFTFDTAAFFDATAATFDDTATTTFDFTDTTFDFTTTFAAFFTDTADDATDDDTFFATFFAF" }, // F N F N L L N L S
/* 7*/ { "2345678901234KM12JQ3N ", 0, 100, 30, 0, "TDTFAFADDATATATTAAFAFTFTDADFDTDAAADFFDTTDDTDDFATDDTFDATFDFTFFFDFTA" }, // F F N N L L N L S
/* 8*/ { "34A6789012345OV123JQ4U", 0, 100, 30, 0, "TDTTATADDATDADADATTAFATDAADAFTTTAAFDATFAFDDFDATFDTADDTFFAAFDDTTAAD" }, // F F N N N L L N L
/* 9*/ { "44E9999999999CI1K3JQ4U", 0, 100, 30, 0, "DADTFDATFAFAFFAADTDFTTAAFFAFFDFATFTFDDAAFDFDDFAFDTDTDDATTDATTAFDAD" }, // F F N F N L L N L
/* 10*/ { "0418070504030C12JQ3U ", 0, 100, 30, 0, "FTAFFDAFTDDFTDTAFAADDDTADFTFAFFFATAAATFTDDDATFATFTTFTFFATADTDAAFTA" }, // F N N L L N L S S
/* 11*/ { "02D7543219876C123JQ4U ", 0, 100, 30, 0, "AFTFAFATFDDFFDTTDDFAFDFDAFFTFAAFTTDATDFATATFTDFTFTTTFFTTATDATFDFTA" }, // F N N N L L N L S
/* 12*/ { "01000000000000000AA000AA0A", 0, 100, 30, 0, "FDTTATTDDFFDATFAFDDTFFDDAATTTATTDTTADADDFDFTFAFAADTADDFDFTDTFTAFDDATDAFDFFATDT" },
/* 13*/ { "01000000000000009JA500AA0A", 0, 100, 30, 0, "FDTDAADTDAAADDDAFADDDFDDAFAADDAADTTAAFFDDTFTTDDTDFDTTDDTTFFDTDTFAADTAFAAFFDFDF" },
/* 14*/ { "01000000000000000C1I2JQ3N ", 0, 100, 30, 0, "TDTTDFTDDFDFFDTTAAATFFAADAFTTATTDTTAATFATDTTFAAFDFDAFTDADFTDFDFTFFFDADAFDDAATT" }, // F N F N L L N L S
/* 15*/ { "01777777777777777KM12JQ3N ", 0, 100, 30, 0, "AFFADATDDTATDFFAFAAADDTATFFDADDDADDAFFAFDDTADTTFDFATAFDDAAFFTTAFADTAAFTTDTFFTA" }, // F F N N L L N L S
/* 16*/ { "33C55555555555555OV123JQ4U", 0, 100, 30, 0, "FDTTFDDTDFFAAAADDFFDTFTFDDTADAAADATTFAFTTFDATTDDTDAFTAFTDDTTADDFFTAFDTDDTDTTAF" }, // F F N N N L L N L
/* 17*/ { "42944444444444444CI1K3JQ4U", 0, 100, 30, 0, "FTDDTTTTFAFFTATFTTFTDTFTFAADADTAFDADDTFDFDAFDFTTAFATFDFDTTFATFDFDAAAFTFTDFFTAF" }, // F F N F N L L N L
/* 18*/ { "31833333333333333C12JQ3U ", 0, 100, 30, 0, "DTTAFFDATATFAADAFDFATFFTFFTTTADTTTDTAAATDDTFFDDFTAADTTDTFFFDAFTFAADFDDAFDFTAFF" }, // F N N L L N L S S
/* 19*/ { "22799999999999999C123JQ4U ", 0, 100, 30, 0, "DDATTDDATATTTAFDTAADATDDFFTFFDFFDTFAADDFAADFDFFTFFTFFDFDFTATATFDDFTFFFTFFTDDTF" }, // F N N N L L N L S
};
int data_size = sizeof(data) / sizeof(struct item);
@ -124,7 +180,7 @@ static void test_encode_vector(int index, int debug) {
int length = strlen(data[i].data);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret_encode, symbol->errtxt);
assert_equal(symbol->rows, 3, "i:%d symbol->rows %d != 3\n", i, symbol->rows);
@ -133,7 +189,7 @@ static void test_encode_vector(int index, int debug) {
assert_zero(strcmp(actual_daft, data[i].expected_daft), "i:%d\n actual %s\nexpected %s\n", i, actual_daft, data[i].expected_daft);
ret = ZBarcode_Buffer_Vector(symbol, 0);
assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", i, ret, data[i].ret_vector);
assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d (%s)\n", i, ret, data[i].ret_vector, symbol->errtxt);
ZBarcode_Delete(symbol);
}

View File

@ -56,13 +56,75 @@ static void test_binary_div_modulo_divisor(int index, int generate, int debug) {
/* 4*/ { BARCODE_RSS14, "0000000001596", 0, 100, 30, 0, 1, 96, "010101001000000001001111100000010111111100101010111101111101010101111100000111011111111011010101" },
/* 5*/ { BARCODE_RSS14, "0000000001597", 0, 100, 30, 0, 1, 96, "010101001000000001011111000000010111111100101010101010110000000101111100000111011111110111010101" },
/* 6*/ { BARCODE_RSS14, "0000000001598", 0, 100, 30, 0, 1, 96, "010101001000000001011111000000010111111100101010101011010000000101111000000011011111110111010101" },
/* 7*/ { BARCODE_RSS_LTD, "1234567890123", 0, 100, 30, 0, 1, 74, "01001100111100101000100111010110101011001001010010101001010000011100011101" },
/* 8*/ { BARCODE_RSS_LTD, "0000002013570", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110100101101011001010111111110111111010101010101" },
/* 9*/ { BARCODE_RSS_LTD, "0000002013571", 0, 100, 30, 0, 1, 74, "01010101010100000011000000110101011010100011010101010101000000100000011101" },
/*10*/ { BARCODE_RSS_LTD, "0000002013572", 0, 100, 30, 0, 1, 74, "01010101010100000011000000110101010010111001010101010101000000110000001101" },
/* 7*/ { BARCODE_RSS14, "0000000000000", 0, 100, 30, 0, 1, 96, "010101001000000001000111111110010111111100101010101010110000000101111111110111011111111011010101" },
/* 8*/ { BARCODE_RSS14, "0000000257117", 0, 100, 30, 0, 1, 96, "010101001000000001001111100000010111111100101010101010110000000101111110000011000111111011010101" },
/* 9*/ { BARCODE_RSS14, "0000000536592", 0, 100, 30, 0, 1, 96, "010101001000000001000111000000010111111100101010101010110000000101100000000111011101100011110101" },
/* 10*/ { BARCODE_RSS14, "0000001644132", 0, 100, 30, 0, 1, 96, "010101001000000001001111100000010111111100101010100100001111010101111100000111000001101111010101" },
/* 11*/ { BARCODE_RSS14, "0000002421052", 0, 100, 30, 0, 1, 96, "010101001000000001011111000000010111111100101010101010110000000101111100000111011100010001101101" },
/* 12*/ { BARCODE_RSS14, "0000003217955", 0, 100, 30, 0, 1, 96, "010101001000000001000111000000010111111100101010101010110000000101111111000001000000111001010101" },
/* 13*/ { BARCODE_RSS14, "0000004792584", 0, 100, 30, 0, 1, 96, "010101001000000001000111110000010111111101001010111011111101010101111111110111010110101111111101" },
/* 14*/ { BARCODE_RSS14, "0000006062184", 0, 100, 30, 0, 1, 96, "010101001000000001000111111110010111111101001010110111111101010101111111110111001010011011111101" },
/* 15*/ { BARCODE_RSS14, "0000007734882", 0, 100, 30, 0, 1, 96, "010101001000000001000111111110010111111101001010110111000010010101111111000111001010001100111101" },
/* 16*/ { BARCODE_RSS14, "0000008845782", 0, 100, 30, 0, 1, 96, "010101001000000001011111000000010111111101001010111101111101010101111111000001000010101000011101" },
/* 17*/ { BARCODE_RSS14, "0000009329661", 0, 100, 30, 0, 1, 96, "010101001000000001001111111000010111111101010010111011111101010101111000000011010110101111111101" },
/* 18*/ { BARCODE_RSS14, "0000009607386", 0, 100, 30, 0, 1, 96, "010101001000000001011111000000010111111101010010100111001011110101111111110111011100011011110101" },
/* 19*/ { BARCODE_RSS14, "0000010718286", 0, 100, 30, 0, 1, 96, "010101001000000001000111110000010111111101010010100100001111010101111100000111000001101111010101" },
/* 20*/ { BARCODE_RSS14, "0000011607006", 0, 100, 30, 0, 1, 96, "010101001000000001000111111110010111111101010010101101000100000101111000000011010011100001101101" },
/* 21*/ { BARCODE_RSS14, "0004360130997", 0, 100, 30, 0, 1, 96, "010101001000000001000100000000010110010010011110101010110000000101111000000011011111111011010101" },
/* 22*/ { BARCODE_RSS14, "0004360386504", 0, 100, 30, 0, 1, 96, "010101001000000001000111000000010110010010011110111011111101010101111111100011010110101111111101" },
/* 23*/ { BARCODE_RSS14, "0009142746747", 0, 100, 30, 0, 1, 96, "010101000100000001000111111110010100111110001010101010110000000101111111000111011101100011110101" },
/* 24*/ { BARCODE_RSS14, "0012319818547", 0, 100, 30, 0, 1, 96, "010101000100000001000100000000010110001100101000101010110000000101111111000111001100011110010101" },
/* 25*/ { BARCODE_RSS14, "0013775011335", 0, 100, 30, 0, 1, 96, "010101000100000001000100000000010101001100000110101010110000000101111100000111011111010011100101" },
/* 26*/ { BARCODE_RSS14, "0018894538190", 0, 100, 30, 0, 1, 96, "010101000010000001000100000000010110100100111100101010110000000101111111110001010001100011110101" },
/* 27*/ { BARCODE_RSS14, "0021059247735", 0, 100, 30, 0, 1, 96, "010101000010000001000100000000010101000011001100101010110000000101111111100011010110111000001101" },
/* 28*/ { BARCODE_RSS14, "0024094346235", 0, 100, 30, 0, 1, 96, "010101000001000001000100000000010111010000111010101010110000000101100000000111000110011001101101" },
/* 29*/ { BARCODE_RSS14, "1995000595035", 0, 100, 30, 0, 1, 96, "010100011011000001001110000000010111010111010000101010110000000101111000000011000110011001101101" },
/* 30*/ { BARCODE_RSS14, "9999999999999", 0, 100, 30, 0, 1, 96, "010010111011100001000111111110010111101101001110100011111101010101111111000001000111110101011101" },
/* 31*/ { BARCODE_RSS14_CC, "0000000000000", 0, 100, 30, 0, 5, 100, "0000010010111011100001001110000000010111101101001110110001010111110101111111110001000111110101011101" },
/* 32*/ { BARCODE_RSS14_CC, "0000729476171", 0, 100, 30, 0, 5, 100, "0000010010111011100001011100000000010111100110100010101010110000000101111111100011011111111011010101" },
/* 33*/ { BARCODE_RSS14_CC, "0004359674363", 0, 100, 30, 0, 5, 100, "0000010010111011100001011100000000010101110010000100101010110000000101111000000011011101100011110101" },
/* 34*/ { BARCODE_RSS14_CC, "0009142871421", 0, 100, 30, 0, 5, 100, "0000010010111101000011000111111110010100010111110010101010110000000101111111000111001100011110010101" },
/* 35*/ { BARCODE_RSS14_CC, "0012319591881", 0, 100, 30, 0, 5, 100, "0000010010111101000011000100000000010101000111010000101010110000000101111111000111011100010001101101" },
/* 36*/ { BARCODE_RSS14_CC, "6975446373038", 0, 100, 30, 0, 5, 100, "0000010111001110010111001111111000010101000111010000101010110000000101111100000111011111111011010101" },
/* 37*/ { BARCODE_RSS14_CC, "9999999999999", 0, 100, 30, 0, 5, 100, "0000010110101111011111001111111000010110111100100010100110111001110101111111110001001100110001110101" },
/* 38*/ { BARCODE_RSS_LTD, "1234567890123", 0, 100, 30, 0, 1, 74, "01001100111100101000100111010110101011001001010010101001010000011100011101" },
/* 39*/ { BARCODE_RSS_LTD, "0000002013570", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110100101101011001010111111110111111010101010101" },
/* 40*/ { BARCODE_RSS_LTD, "0000002013571", 0, 100, 30, 0, 1, 74, "01010101010100000011000000110101011010100011010101010101000000100000011101" },
/* 41*/ { BARCODE_RSS_LTD, "0000002013572", 0, 100, 30, 0, 1, 74, "01010101010100000011000000110101010010111001010101010101000000110000001101" },
/* 42*/ { BARCODE_RSS_LTD, "0000000917879", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110100110101010011010100110111011111010110011101" },
/* 43*/ { BARCODE_RSS_LTD, "0000000000000", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110101110101001001010101010101000000100000011101" },
/* 44*/ { BARCODE_RSS_LTD, "0000000183063", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110110101010010011010000001110000001010101010101" },
/* 45*/ { BARCODE_RSS_LTD, "0000000183064", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110010101010111001010101010101000111100000111101" },
/* 46*/ { BARCODE_RSS_LTD, "0000000820063", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110010101010011011010000011110001111010101010101" },
/* 47*/ { BARCODE_RSS_LTD, "0000000820064", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110110101101001001010101010101011111100011111101" },
/* 48*/ { BARCODE_RSS_LTD, "0000001000775", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110010110101011001010001111110111111010101010101" },
/* 49*/ { BARCODE_RSS_LTD, "0000001000776", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110101110101010001010101010101000001100000111101" },
/* 50*/ { BARCODE_RSS_LTD, "0000001491020", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110010101010110011010000011110000011010101010101" },
/* 51*/ { BARCODE_RSS_LTD, "0000001491021", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110101001010110011010101010101001111100001111101" },
/* 52*/ { BARCODE_RSS_LTD, "0000001979844", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110101010100011011010000111110011111010101010101" },
/* 53*/ { BARCODE_RSS_LTD, "0000001979845", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110101110100101001010101010101000000100000000101" },
/* 54*/ { BARCODE_RSS_LTD, "0000001996938", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110101101010001011010000000010000001010101010101" },
/* 55*/ { BARCODE_RSS_LTD, "0000001996939", 0, 100, 30, 0, 1, 74, "01010101010100000010000001110110110101010001010101010101011111101111111101" },
/* 56*/ { BARCODE_RSS_LTD, "0000012013571", 0, 100, 30, 0, 1, 74, "01010101010111000000100000010101010010100111010001110111100101001101101101" },
/* 57*/ { BARCODE_RSS_LTD, "0368610347973", 0, 100, 30, 0, 1, 74, "01000000111000000101010101010010101011101001010101010101000000100000011101" },
/* 58*/ { BARCODE_RSS_LTD, "0368612361544", 0, 100, 30, 0, 1, 74, "01010101010100011110000011110101001101010011010101010101000000100000011101" },
/* 59*/ { BARCODE_RSS_LTD, "1651255074973", 0, 100, 30, 0, 1, 74, "01000001111000111101010101010101101001010011010101010101000000100000011101" },
/* 60*/ { BARCODE_RSS_LTD, "1651257088544", 0, 100, 30, 0, 1, 74, "01010101010101111110001111110101101001101001010101010101000000100000011101" },
/* 61*/ { BARCODE_RSS_LTD, "1999999999999", 0, 100, 30, 0, 1, 74, "01001111001101101011011111010101011010110001010100001011100011010111100101" },
/* 62*/ { BARCODE_RSS_LTD_CC, "0000000000000", 0, 100, 30, 0, 6, 74, "01010101010100000110000011110100101011010011010101010101000000100000011101" },
/* 63*/ { BARCODE_RSS_LTD_CC, "0000002013571", 0, 100, 30, 0, 6, 74, "01010101010100000111000001110101101010001011010101010101000000100000011101" },
/* 64*/ { BARCODE_RSS_LTD_CC, "0987141101324", 0, 100, 30, 0, 6, 74, "01000001111000001101010101010110101010100011010101010101000000100000011101" },
/* 65*/ { BARCODE_RSS_LTD_CC, "0987143114895", 0, 100, 30, 0, 6, 74, "01010101010100111110000111110101110101010001010101010101000000100000011101" },
/* 66*/ { BARCODE_RSS_LTD_CC, "1971422931828", 0, 100, 30, 0, 6, 74, "01000011111001111101010101010100101010100111010101010101000000100000011101" },
/* 67*/ { BARCODE_RSS_LTD_CC, "1971424945399", 0, 100, 30, 0, 6, 74, "01010101010100000010000000010110101010010011010101010101000000100000011101" },
/* 68*/ { BARCODE_RSS_LTD_CC, "1999999999999", 0, 100, 30, 0, 6, 74, "01000010000001010101000001010110101101001001010100001011100011010111100101" },
/* 69*/ { BARCODE_RSS_LTD, "1651257071912", 0, 100, 30, 0, 1, 74, "01000001111000111101010101010101110101001001010101010101011111101111111101" },
/* 70*/ { BARCODE_RSS_LTD_CC, "0987144605916", 0, 100, 30, 0, 6, 74, "01010101010100111110000111110110101101001001010101010101001111100001111101" },
};
int data_size = sizeof(data) / sizeof(struct item);
char *text;
for (int i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
@ -73,22 +135,28 @@ static void test_binary_div_modulo_divisor(int index, int generate, int debug) {
symbol->symbology = data[i].symbology;
symbol->debug |= debug;
int length = strlen(data[i].data);
if (symbol->symbology == BARCODE_RSS14_CC || symbol->symbology == BARCODE_RSS_LTD_CC) {
text = "[20]01";
strcpy(symbol->primary, data[i].data);
} else {
text = data[i].data;
}
int length = strlen(text);
ret = ZBarcode_Encode(symbol, data[i].data, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d\n", i, ret, data[i].ret_encode);
ret = ZBarcode_Encode(symbol, text, length);
assert_equal(ret, data[i].ret_encode, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret_encode, symbol->errtxt);
if (generate) {
printf(" /*%2d*/ { %s, \"%s\", %d, %.0f, %.0f, %d, %d, %d, ",
printf(" /*%3d*/ { %s, \"%s\", %d, %.0f, %.0f, %d, %d, %d, ",
i, testUtilBarcodeName(data[i].symbology), data[i].data, ret, data[i].w, data[i].h, data[i].ret_vector, symbol->rows, symbol->width);
testUtilModulesDump(symbol, "", " },\n");
testUtilModulesDumpRow(symbol, symbol->rows - 1, "", " },\n");
} else {
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
int width, row;
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
int width;
ret = testUtilModulesCmpRow(symbol, symbol->rows - 1, data[i].expected, &width);
assert_zero(ret, "i:%d testUtilModulesCmpRow ret %d != 0 width %d row %d\n", i, ret, width, symbol->rows - 1);
ret = ZBarcode_Buffer_Vector(symbol, 0);
assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", i, ret, data[i].ret_vector);

View File

@ -873,39 +873,29 @@ int testUtilVectorCmp(const struct zint_vector *a, const struct zint_vector *b)
return 0;
}
void testUtilLargeDump(const char *name, const short int reg[]) {
unsigned words[4];
words[0] = words[1] = words[2] = words[3] = 0;
int w = 0;
for (int i = 0; i < 112; i += 32 ) {
for (int j = 0; j < 32 && i + j < 112; j++) {
if (reg[i + j]) {
words[w] += 1 << j;
void testUtilModulesDump(const struct zint_symbol *symbol, char *prefix, char *postfix) {
int r;
for (r = 0; r < symbol->rows; r++) {
testUtilModulesDumpRow(symbol, r, prefix, postfix);
}
}
w++;
}
printf("%4x 0x%08x%08x%08x %s", words[3], words[2], words[1], words[0], name);
}
void testUtilModulesDump(const struct zint_symbol *symbol, char *prefix, char *postfix) {
int r, w;
for (r = 0; r < symbol->rows; r++) {
void testUtilModulesDumpRow(const struct zint_symbol *symbol, int row, char *prefix, char *postfix) {
int w;
if (*prefix) {
fputs(prefix, stdout);
}
putchar('"');
for (w = 0; w < symbol->width; w++) {
putchar(module_is_set(symbol, r, w) + '0');
putchar(module_is_set(symbol, row, w) + '0');
}
putchar('"');
if (*postfix) {
fputs(postfix, stdout);
}
}
}
int testUtilModulesCmp(const struct zint_symbol *symbol, const char *expected, int *row, int *width) {
int testUtilModulesCmp(const struct zint_symbol *symbol, const char *expected, int *width, int *row) {
const char *e = expected;
const char *ep = expected + strlen(expected);
int r, w = 0;
@ -924,6 +914,21 @@ int testUtilModulesCmp(const struct zint_symbol *symbol, const char *expected, i
return e != ep || r != symbol->rows || w != symbol->width ? 1 /*fail*/ : 0 /*success*/;
}
int testUtilModulesCmpRow(const struct zint_symbol *symbol, int row, const char *expected, int *width) {
const char *e = expected;
const char *ep = expected + strlen(expected);
int w;
for (w = 0; w < symbol->width && e < ep; w++) {
if (module_is_set(symbol, row, w) + '0' != *e) {
*width = w;
return 1 /*fail*/;
}
e++;
}
*width = w;
return e != ep || w != symbol->width ? 1 /*fail*/ : 0 /*success*/;
}
int testUtilModulesDumpHex(const struct zint_symbol *symbol, char dump[], int dump_size) {
int i, r;
char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
@ -962,6 +967,32 @@ int testUtilModulesDumpHex(const struct zint_symbol *symbol, char dump[], int du
return d - dump;
}
char *testUtilUIntArrayDump(unsigned int *array, int size, char *dump, int dump_size) {
int i, cnt_len = 0;
for (i = 0; i < size; i++) {
cnt_len += sprintf(dump + cnt_len, "%X ", array[i]);
if (cnt_len + 19 > dump_size) {
break;
}
}
dump[cnt_len ? cnt_len - 1 : 0] = '\0';
return dump;
}
char *testUtilUCharArrayDump(unsigned char *array, int size, char *dump, int dump_size) {
int i, cnt_len = 0;
for (i = 0; i < size; i++) {
cnt_len += sprintf(dump + cnt_len, "%X ", array[i]);
if (cnt_len + 3 > dump_size) {
break;
}
}
dump[cnt_len ? cnt_len - 1 : 0] = '\0';
return dump;
}
void testUtilBitmapPrint(const struct zint_symbol *symbol) {
static char colour[] = { '0', 'C', 'B', 'M', 'R', 'Y', 'G', '1' };
int row, column, i, j;

View File

@ -84,10 +84,13 @@ void testUtilStrCpyRepeat(char *buffer, char *repeat, int size);
int testUtilSymbolCmp(const struct zint_symbol *a, const struct zint_symbol *b);
struct zint_vector *testUtilVectorCpy(const struct zint_vector *in);
int testUtilVectorCmp(const struct zint_vector *a, const struct zint_vector *b);
void testUtilLargeDump(const char *name, const short reg[]);
void testUtilModulesDump(const struct zint_symbol *symbol, char *prefix, char *postfix);
int testUtilModulesCmp(const struct zint_symbol *symbol, const char *expected, int *row, int *width);
void testUtilModulesDump(const struct zint_symbol *symbol, char *prefix, char *postfix); // TODO: should be called Print not Dump
void testUtilModulesDumpRow(const struct zint_symbol *symbol, int row, char *prefix, char *postfix); // TODO: should be called Print not Dump
int testUtilModulesCmp(const struct zint_symbol *symbol, const char *expected, int *width, int *row);
int testUtilModulesCmpRow(const struct zint_symbol *symbol, int row, const char *expected, int *width);
int testUtilModulesDumpHex(const struct zint_symbol *symbol, char dump[], int dump_size);
char *testUtilUIntArrayDump(unsigned int *array, int size, char *dump, int dump_size);
char *testUtilUCharArrayDump(unsigned char *array, int size, char *dump, int dump_size);
void testUtilBitmapPrint(const struct zint_symbol *symbol);
int testUtilExists(char *filename);
int testUtilCmpPngs(char *file1, char *file2);