mirror of
https://git.code.sf.net/p/zint/code
synced 2025-05-18 17:25:09 -04:00
gs1_verify: validate AIs from BWIPP gs1-format-spec.txt
This commit is contained in:
parent
0b80592f87
commit
f9300cb37e
28 changed files with 5887 additions and 1275 deletions
409
backend/tools/gen_gs1_lint.php
Normal file
409
backend/tools/gen_gs1_lint.php
Normal file
|
@ -0,0 +1,409 @@
|
|||
<?php
|
||||
/* Generate GS1 verify include "backend/gs1_lint.h" for "backend/gs1.c" */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2021 <rstuart114@gmail.com>
|
||||
*/
|
||||
/* To create "backend/gs1_lint.h" (from project directory):
|
||||
*
|
||||
* php backend/tools/gen_gs1_lint.php > backend/gs1_lint.h
|
||||
*
|
||||
* or to use local copy of "gs1-format_spec.txt":
|
||||
*
|
||||
* php backend/tools/gen_gs1_lint.php -f <local-path>/gs1-format-spec.txt backend/gs1_lint.h
|
||||
*
|
||||
*/
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
||||
$basename = basename(__FILE__);
|
||||
$dirname = dirname(__FILE__);
|
||||
$dirdirname = basename(dirname($dirname)) . '/' . basename($dirname);
|
||||
|
||||
$opts = getopt('c:f:h:l:t:');
|
||||
|
||||
$print_copyright = isset($opts['c']) ? (bool) $opts['c'] : true;
|
||||
$file = isset($opts['f']) ? $opts['f'] :
|
||||
'https://raw.githubusercontent.com/bwipp/postscriptbarcode/master/contrib/development/gs1-format-spec.txt';
|
||||
$print_h_guard = isset($opts['h']) ? (bool) $opts['h'] : true;
|
||||
$use_length_only = isset($opts['l']) ? (bool) $opts['l'] : true;
|
||||
$tab = isset($opts['t']) ? $opts['t'] : ' ';
|
||||
|
||||
if (($get = file_get_contents($file)) === false) {
|
||||
exit("$basename: ERROR: Could not read file \"$file\"" . PHP_EOL);
|
||||
}
|
||||
|
||||
$lines = explode("\n", $get);
|
||||
|
||||
$spec_ais = $spec_parts = $spec_funcs = array();
|
||||
$batches = array_fill(0, 100, array());
|
||||
|
||||
// Parse the lines into AIs and specs
|
||||
$line_no = 0;
|
||||
foreach ($lines as $line) {
|
||||
$line_no++;
|
||||
if ($line === '' || $line[0] === '#') {
|
||||
continue;
|
||||
}
|
||||
if (!preg_match('/^([0-9]+(?:-[0-9]+)?) +([NXC][0-9.][ NXC0-9.,a-z]*)$/', $line, $matches)) {
|
||||
exit("$basename: ERROR: Could not parse line $line_no" . PHP_EOL);
|
||||
}
|
||||
$ai = $matches[1];
|
||||
$spec = trim($matches[2]);
|
||||
|
||||
if (isset($spec_ais[$spec])) {
|
||||
$ais = $spec_ais[$spec];
|
||||
} else {
|
||||
$ais = array();
|
||||
}
|
||||
|
||||
if (($hyphen = strpos($ai, '-')) !== false) {
|
||||
$ai_s = (int) substr($ai, 0, $hyphen);
|
||||
$ai_e = (int) substr($ai, $hyphen + 1);
|
||||
$ais[] = array($ai_s, $ai_e);
|
||||
|
||||
$batch_s_idx = (int) ($ai_s / 100);
|
||||
$batch_e_idx = (int) ($ai_e / 100);
|
||||
if ($batch_s_idx !== $batch_e_idx) {
|
||||
if (!in_array($spec, $batches[$batch_s_idx])) {
|
||||
$batches[$batch_s_idx][] = $spec;
|
||||
}
|
||||
if (!in_array($spec, $batches[$batch_e_idx])) {
|
||||
$batches[$batch_e_idx][] = $spec;
|
||||
}
|
||||
} else {
|
||||
if (!in_array($spec, $batches[$batch_s_idx])) {
|
||||
$batches[$batch_s_idx][] = $spec;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ai = (int) $ai;
|
||||
$ais[] = $ai;
|
||||
$batch_idx = (int) ($ai / 100);
|
||||
if (!in_array($spec, $batches[$batch_idx])) {
|
||||
$batches[$batch_idx][] = $spec;
|
||||
}
|
||||
}
|
||||
|
||||
$spec_ais[$spec] = $ais;
|
||||
|
||||
$spec_parts[$spec] = array();
|
||||
$parts = explode(' ', $spec);
|
||||
foreach ($parts as $part) {
|
||||
$checkers = explode(',', $part);
|
||||
$validator = array_shift($checkers);
|
||||
if (!preg_match('/^([NXC])([0-9]+)?(\.\.[0-9|]+)?$/', $validator, $matches)) {
|
||||
exit("$basename: ERROR: Could not parse validator \"$validator\" line $line_no" . PHP_EOL);
|
||||
}
|
||||
if (count($matches) === 3) {
|
||||
$min = $max = (int) $matches[2];
|
||||
} else {
|
||||
$min = $matches[2] === '' ? 1 : (int) $matches[2];
|
||||
$max = (int) substr($matches[3], 2);
|
||||
}
|
||||
if ($matches[1] === 'N') {
|
||||
$validator = "numeric";
|
||||
} elseif ($matches[1] === 'X') {
|
||||
$validator = "cset82";
|
||||
} else {
|
||||
$validator = "cset39";
|
||||
}
|
||||
$spec_parts[$spec][] = array($min, $max, $validator, $checkers);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate total min/maxs and convert the AIs into ranges
|
||||
|
||||
foreach ($spec_ais as $spec => $ais) {
|
||||
// Total min/maxs
|
||||
$total_min = $total_max = 0;
|
||||
foreach ($spec_parts[$spec] as list($min, $max)) {
|
||||
$total_min += $min;
|
||||
$total_max += $max;
|
||||
}
|
||||
|
||||
// Sort the AIs
|
||||
$sort_ais = array();
|
||||
foreach ($ais as $ai) {
|
||||
if (is_array($ai)) {
|
||||
$sort_ais[] = $ai[0];
|
||||
} else {
|
||||
$sort_ais[] = $ai;
|
||||
}
|
||||
}
|
||||
array_multisort($sort_ais, $ais);
|
||||
|
||||
// Consolidate contiguous AIs into ranges
|
||||
$tmp_ais = array();
|
||||
foreach ($ais as $ai) {
|
||||
$cnt = count($tmp_ais);
|
||||
if ($cnt === 0) {
|
||||
$tmp_ais[] = $ai;
|
||||
} else {
|
||||
$prev_ai = $tmp_ais[$cnt - 1];
|
||||
if (is_array($prev_ai)) {
|
||||
$prev_s = $prev_ai[0];
|
||||
$prev_e = $prev_ai[1];
|
||||
} else {
|
||||
$prev_e = $prev_s = $prev_ai;
|
||||
}
|
||||
if (is_array($ai)) {
|
||||
$this_s = $ai[0];
|
||||
$this_e = $ai[0];
|
||||
} else {
|
||||
$this_s = $this_e = $ai;
|
||||
}
|
||||
if ($this_s === $prev_e + 1) {
|
||||
$tmp_ais[$cnt - 1] = array($prev_s, $this_e);
|
||||
} else {
|
||||
$tmp_ais[] = $ai;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unconsolidate ranges of 1 into separate entries
|
||||
$ais = array();
|
||||
foreach ($tmp_ais as $ai) {
|
||||
if (is_array($ai) && $ai[1] === $ai[0] + 1) {
|
||||
$ais[] = $ai[0];
|
||||
$ais[] = $ai[1];
|
||||
} else {
|
||||
$ais[] = $ai;
|
||||
}
|
||||
}
|
||||
|
||||
$spec_ais[$spec] = array($total_min, $total_max, $ais);
|
||||
}
|
||||
|
||||
// Print output
|
||||
|
||||
print <<<EOD
|
||||
/*
|
||||
* GS1 AI checker generated by "$dirdirname/$basename" from
|
||||
* $file
|
||||
*/
|
||||
|
||||
EOD;
|
||||
|
||||
if ($print_copyright) {
|
||||
print <<<'EOD'
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
|
||||
EOD;
|
||||
}
|
||||
|
||||
if ($print_h_guard) {
|
||||
print <<<'EOD'
|
||||
#ifndef GS1_LINT_H
|
||||
#define GS1_LINT_H
|
||||
|
||||
|
||||
EOD;
|
||||
}
|
||||
|
||||
// Print the spec validator/checkers functions
|
||||
|
||||
foreach ($spec_parts as $spec => $spec_part) {
|
||||
$spec_funcs[$spec] = $spec_func = str_replace(array(' ', '.', ','), '_', strtolower($spec));
|
||||
print <<<EOD
|
||||
/* $spec */
|
||||
static int $spec_func(const unsigned char *data, const int data_len,
|
||||
$tab$tab{$tab}int *p_err_no, int *p_err_posn, char err_msg[50]) {
|
||||
{$tab}return
|
||||
EOD;
|
||||
|
||||
list($total_min, $total_max) = $spec_ais[$spec];
|
||||
if ($total_min === $total_max) {
|
||||
print "data_len == $total_max";
|
||||
} else {
|
||||
print "data_len >= $total_min && data_len <= $total_max";
|
||||
}
|
||||
|
||||
if ($use_length_only) {
|
||||
// Call checkers checking for length only first
|
||||
$length_only_arg = ", 1 /*length_only*/";
|
||||
$offset = 0;
|
||||
foreach ($spec_part as list($min, $max, $validator, $checkers)) {
|
||||
foreach ($checkers as $checker) {
|
||||
print <<<EOD
|
||||
|
||||
$tab$tab{$tab}&& $checker(data, data_len, $offset, $min, $max, p_err_no, p_err_posn, err_msg$length_only_arg)
|
||||
EOD;
|
||||
}
|
||||
|
||||
$offset += $max;
|
||||
}
|
||||
}
|
||||
|
||||
// Validator and full checkers
|
||||
$length_only_arg = $use_length_only ? ", 0" : "";
|
||||
$offset = 0;
|
||||
foreach ($spec_part as list($min, $max, $validator, $checkers)) {
|
||||
print <<<EOD
|
||||
|
||||
$tab$tab{$tab}&& $validator(data, data_len, $offset, $min, $max, p_err_no, p_err_posn, err_msg)
|
||||
EOD;
|
||||
|
||||
foreach ($checkers as $checker) {
|
||||
print <<<EOD
|
||||
|
||||
$tab$tab{$tab}&& $checker(data, data_len, $offset, $min, $max, p_err_no, p_err_posn, err_msg$length_only_arg)
|
||||
EOD;
|
||||
}
|
||||
|
||||
$offset += $max;
|
||||
}
|
||||
print ";\n}\n\n";
|
||||
}
|
||||
|
||||
// Print main routine
|
||||
|
||||
print <<<EOD
|
||||
/* Entry point. Returns 1 on success, 0 on failure: `*p_err_no` set to 1 if unknown AI, 2 if bad data length */
|
||||
static int gs1_lint(const int ai, const unsigned char *data, const int data_len, int *p_err_no, int *p_err_posn,
|
||||
$tab$tab{$tab}char err_msg[50]) {
|
||||
|
||||
$tab/* Assume data length failure */
|
||||
$tab*p_err_no = 2;
|
||||
|
||||
EOD;
|
||||
|
||||
// Split AIs into batches of 100 to lessen the number of comparisons
|
||||
|
||||
$not_first_batch = false;
|
||||
$last_batch_e = -1;
|
||||
foreach ($batches as $batch => $batch_specs) {
|
||||
if (empty($batch_specs)) {
|
||||
continue;
|
||||
}
|
||||
$batch_s = $batch * 100;
|
||||
$batch_e = $batch_s + 100;
|
||||
if ($not_first_batch) {
|
||||
print "\n$tab} else if (ai < $batch_e) {\n\n";
|
||||
} else {
|
||||
print "\n{$tab}if (ai < $batch_e) {\n\n";
|
||||
$not_first_batch = true;
|
||||
}
|
||||
foreach ($batch_specs as $spec) {
|
||||
$total_min = $spec_ais[$spec][0];
|
||||
$total_max = $spec_ais[$spec][1];
|
||||
$ais = $spec_ais[$spec][2];
|
||||
|
||||
$str = "$tab{$tab}if (";
|
||||
print $str;
|
||||
$width = strlen($str);
|
||||
|
||||
// Count the applicable AIs
|
||||
$ais_cnt = 0;
|
||||
foreach ($ais as $ai) {
|
||||
if (is_array($ai)) {
|
||||
if ($ai[1] < $batch_s || $ai[0] >= $batch_e) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ($ai < $batch_s || $ai >= $batch_e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$ais_cnt++;
|
||||
}
|
||||
|
||||
// Output
|
||||
$not_first_ai = false;
|
||||
foreach ($ais as $ai) {
|
||||
if (is_array($ai)) {
|
||||
if ($ai[1] < $batch_s || $ai[0] >= $batch_e) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ($ai < $batch_s || $ai >= $batch_e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$str = '';
|
||||
if ($not_first_ai) {
|
||||
$str .= " || ";
|
||||
} else {
|
||||
$not_first_ai = true;
|
||||
}
|
||||
if (is_array($ai)) {
|
||||
if ($ai[0] === $last_batch_e) { // Don't need 1st element of range if excluded by previous batch
|
||||
$str .= "ai <= " . $ai[1];
|
||||
} else if ($ai[1] + 1 == $batch_e) { // Don't need 2nd element of range if excluded by this batch
|
||||
$str .= "ai >= " . $ai[0];
|
||||
} else {
|
||||
if ($ais_cnt > 1) {
|
||||
$str .= "(ai >= " . $ai[0] . " && ai <= " . $ai[1] . ")";
|
||||
} else {
|
||||
$str .= "ai >= " . $ai[0] . " && ai <= " . $ai[1];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$str .= "ai == " . $ai;
|
||||
}
|
||||
if ($width + strlen($str) > 118) {
|
||||
print "\n";
|
||||
$str2 = "$tab$tab$tab ";
|
||||
print $str2;
|
||||
$width = strlen($str2);
|
||||
}
|
||||
print $str;
|
||||
$width += strlen($str);
|
||||
}
|
||||
$spec_func = $spec_funcs[$spec];
|
||||
print <<<EOD
|
||||
) {
|
||||
$tab$tab{$tab}return $spec_func(data, data_len, p_err_no, p_err_posn, err_msg);
|
||||
$tab$tab}
|
||||
|
||||
EOD;
|
||||
}
|
||||
$last_batch_e = $batch_e;
|
||||
}
|
||||
|
||||
print <<<EOD
|
||||
$tab}
|
||||
|
||||
{$tab}/* Unknown AI */
|
||||
{$tab}*p_err_no = 1;
|
||||
{$tab}return 0;
|
||||
}
|
||||
|
||||
EOD;
|
||||
|
||||
if ($print_h_guard) {
|
||||
print <<<'EOD'
|
||||
|
||||
#endif /* GS1_LINT_H */
|
||||
|
||||
EOD;
|
||||
}
|
225
backend/tools/gen_iso3166_h.php
Normal file
225
backend/tools/gen_iso3166_h.php
Normal file
|
@ -0,0 +1,225 @@
|
|||
<?php
|
||||
/* Generate ISO 3166 include "backend/iso3166.h" for "backend/gs1.c" */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2021 <rstuart114@gmail.com>
|
||||
*/
|
||||
/* To create "backend/iso3166.h" (from project directory):
|
||||
*
|
||||
* php backend/tools/gen_iso3166_h.php > backend/iso3166.h
|
||||
*/
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
||||
$basename = basename(__FILE__);
|
||||
$dirname = dirname(__FILE__);
|
||||
$dirdirname = basename(dirname($dirname)) . '/' . basename($dirname);
|
||||
|
||||
$opts = getopt('c:h:t:');
|
||||
|
||||
$print_copyright = isset($opts['c']) ? (bool) $opts['c'] : true;
|
||||
$print_h_guard = isset($opts['h']) ? (bool) $opts['h'] : true;
|
||||
$tab = isset($opts['t']) ? $opts['t'] : ' ';
|
||||
|
||||
$numeric = array(
|
||||
/*AFG*/ 4, /*ALB*/ 8, /*ATA*/ 10, /*DZA*/ 12, /*ASM*/ 16, /*AND*/ 20, /*AGO*/ 24, /*ATG*/ 28, /*AZE*/ 31, /*ARG*/ 32,
|
||||
/*AUS*/ 36, /*AUT*/ 40, /*BHS*/ 44, /*BHR*/ 48, /*BGD*/ 50, /*ARM*/ 51, /*BRB*/ 52, /*BEL*/ 56, /*BMU*/ 60, /*BTN*/ 64,
|
||||
/*BOL*/ 68, /*BIH*/ 70, /*BWA*/ 72, /*BVT*/ 74, /*BRA*/ 76, /*BLZ*/ 84, /*IOT*/ 86, /*SLB*/ 90, /*VGB*/ 92, /*BRN*/ 96,
|
||||
/*BGR*/ 100, /*MMR*/ 104, /*BDI*/ 108, /*BLR*/ 112, /*KHM*/ 116, /*CMR*/ 120, /*CAN*/ 124, /*CPV*/ 132, /*CYM*/ 136, /*CAF*/ 140,
|
||||
/*LKA*/ 144, /*TCD*/ 148, /*CHL*/ 152, /*CHN*/ 156, /*TWN*/ 158, /*CXR*/ 162, /*CCK*/ 166, /*COL*/ 170, /*COM*/ 174, /*MYT*/ 175,
|
||||
/*COG*/ 178, /*COD*/ 180, /*COK*/ 184, /*CRI*/ 188, /*HRV*/ 191, /*CUB*/ 192, /*CYP*/ 196, /*CZE*/ 203, /*BEN*/ 204, /*DNK*/ 208,
|
||||
/*DMA*/ 212, /*DOM*/ 214, /*ECU*/ 218, /*SLV*/ 222, /*GNQ*/ 226, /*ETH*/ 231, /*ERI*/ 232, /*EST*/ 233, /*FRO*/ 234, /*FLK*/ 238,
|
||||
/*SGS*/ 239, /*FJI*/ 242, /*FIN*/ 246, /*ALA*/ 248, /*FRA*/ 250, /*GUF*/ 254, /*PYF*/ 258, /*ATF*/ 260, /*DJI*/ 262, /*GAB*/ 266,
|
||||
/*GEO*/ 268, /*GMB*/ 270, /*PSE*/ 275, /*DEU*/ 276, /*GHA*/ 288, /*GIB*/ 292, /*KIR*/ 296, /*GRC*/ 300, /*GRL*/ 304, /*GRD*/ 308,
|
||||
/*GLP*/ 312, /*GUM*/ 316, /*GTM*/ 320, /*GIN*/ 324, /*GUY*/ 328, /*HTI*/ 332, /*HMD*/ 334, /*VAT*/ 336, /*HND*/ 340, /*HKG*/ 344,
|
||||
/*HUN*/ 348, /*ISL*/ 352, /*IND*/ 356, /*IDN*/ 360, /*IRN*/ 364, /*IRQ*/ 368, /*IRL*/ 372, /*ISR*/ 376, /*ITA*/ 380, /*CIV*/ 384,
|
||||
/*JAM*/ 388, /*JPN*/ 392, /*KAZ*/ 398, /*JOR*/ 400, /*KEN*/ 404, /*PRK*/ 408, /*KOR*/ 410, /*KWT*/ 414, /*KGZ*/ 417, /*LAO*/ 418,
|
||||
/*LBN*/ 422, /*LSO*/ 426, /*LVA*/ 428, /*LBR*/ 430, /*LBY*/ 434, /*LIE*/ 438, /*LTU*/ 440, /*LUX*/ 442, /*MAC*/ 446, /*MDG*/ 450,
|
||||
/*MWI*/ 454, /*MYS*/ 458, /*MDV*/ 462, /*MLI*/ 466, /*MLT*/ 470, /*MTQ*/ 474, /*MRT*/ 478, /*MUS*/ 480, /*MEX*/ 484, /*MCO*/ 492,
|
||||
/*MNG*/ 496, /*MDA*/ 498, /*MNE*/ 499, /*MSR*/ 500, /*MAR*/ 504, /*MOZ*/ 508, /*OMN*/ 512, /*NAM*/ 516, /*NRU*/ 520, /*NPL*/ 524,
|
||||
/*NLD*/ 528, /*CUW*/ 531, /*ABW*/ 533, /*SXM*/ 534, /*BES*/ 535, /*NCL*/ 540, /*VUT*/ 548, /*NZL*/ 554, /*NIC*/ 558, /*NER*/ 562,
|
||||
/*NGA*/ 566, /*NIU*/ 570, /*NFK*/ 574, /*NOR*/ 578, /*MNP*/ 580, /*UMI*/ 581, /*FSM*/ 583, /*MHL*/ 584, /*PLW*/ 585, /*PAK*/ 586,
|
||||
/*PAN*/ 591, /*PNG*/ 598, /*PRY*/ 600, /*PER*/ 604, /*PHL*/ 608, /*PCN*/ 612, /*POL*/ 616, /*PRT*/ 620, /*GNB*/ 624, /*TLS*/ 626,
|
||||
/*PRI*/ 630, /*QAT*/ 634, /*REU*/ 638, /*ROU*/ 642, /*RUS*/ 643, /*RWA*/ 646, /*BLM*/ 652, /*SHN*/ 654, /*KNA*/ 659, /*AIA*/ 660,
|
||||
/*LCA*/ 662, /*MAF*/ 663, /*SPM*/ 666, /*VCT*/ 670, /*SMR*/ 674, /*STP*/ 678, /*SAU*/ 682, /*SEN*/ 686, /*SRB*/ 688, /*SYC*/ 690,
|
||||
/*SLE*/ 694, /*SGP*/ 702, /*SVK*/ 703, /*VNM*/ 704, /*SVN*/ 705, /*SOM*/ 706, /*ZAF*/ 710, /*ZWE*/ 716, /*ESP*/ 724, /*SSD*/ 728,
|
||||
/*SDN*/ 729, /*ESH*/ 732, /*SUR*/ 740, /*SJM*/ 744, /*SWZ*/ 748, /*SWE*/ 752, /*CHE*/ 756, /*SYR*/ 760, /*TJK*/ 762, /*THA*/ 764,
|
||||
/*TGO*/ 768, /*TKL*/ 772, /*TON*/ 776, /*TTO*/ 780, /*ARE*/ 784, /*TUN*/ 788, /*TUR*/ 792, /*TKM*/ 795, /*TCA*/ 796, /*TUV*/ 798,
|
||||
/*UGA*/ 800, /*UKR*/ 804, /*MKD*/ 807, /*EGY*/ 818, /*GBR*/ 826, /*GGY*/ 831, /*JEY*/ 832, /*IMN*/ 833, /*TZA*/ 834, /*USA*/ 840,
|
||||
/*VIR*/ 850, /*BFA*/ 854, /*URY*/ 858, /*UZB*/ 860, /*VEN*/ 862, /*WLF*/ 876, /*WSM*/ 882, /*YEM*/ 887, /*ZMB*/ 894,
|
||||
);
|
||||
|
||||
$numeric_tab = array();
|
||||
$val = 0;
|
||||
$byte = 0;
|
||||
$max = $numeric[count($numeric) - 1];
|
||||
for ($i = 0; $i <= $max; $i++) {
|
||||
if ($i && $i % 8 == 0) {
|
||||
$numeric_tab[$byte++] = $val;
|
||||
$val = 0;
|
||||
}
|
||||
if (in_array($i, $numeric)) {
|
||||
$val |= 1 << ($i & 0x7);
|
||||
}
|
||||
}
|
||||
$numeric_tab[$byte++] = $val;
|
||||
$numeric_cnt = count($numeric_tab);
|
||||
|
||||
$alpha2 = array(
|
||||
"AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR",
|
||||
"AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE",
|
||||
"BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ",
|
||||
"BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD",
|
||||
"CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR",
|
||||
"CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM",
|
||||
"DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI",
|
||||
"FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF",
|
||||
"GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS",
|
||||
"GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU",
|
||||
"ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT",
|
||||
"JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN",
|
||||
"KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK",
|
||||
"LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME",
|
||||
"MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ",
|
||||
"MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA",
|
||||
"NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU",
|
||||
"NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM",
|
||||
"PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS",
|
||||
"RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI",
|
||||
"SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV",
|
||||
"SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK",
|
||||
"TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA",
|
||||
"UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI",
|
||||
"VN", "VU", "WF", "WS", "YE", "YT", "ZA", "ZM", "ZW",
|
||||
);
|
||||
|
||||
$alpha2_tab = array();
|
||||
$val = 0;
|
||||
$byte = 0;
|
||||
for ($i = 0; $i < 26; $i++) {
|
||||
for ($j = 0; $j < 26; $j++) {
|
||||
$ij = $i * 26 + $j;
|
||||
if ($ij && $ij % 8 == 0) {
|
||||
$alpha2_tab[$byte++] = $val;
|
||||
$val = 0;
|
||||
}
|
||||
$cc = chr(65 + $i) . chr(65 + $j);
|
||||
if (in_array($cc, $alpha2)) {
|
||||
$val |= 1 << ($ij & 0x7);
|
||||
}
|
||||
}
|
||||
}
|
||||
$alpha2_tab[$byte++] = $val;
|
||||
$alpha2_cnt = count($alpha2_tab);
|
||||
|
||||
print <<<EOD
|
||||
/*
|
||||
* ISO 3166 country codes generated by "$dirdirname/$basename"
|
||||
*/
|
||||
|
||||
EOD;
|
||||
|
||||
if ($print_copyright) {
|
||||
print <<<'EOD'
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
|
||||
EOD;
|
||||
}
|
||||
|
||||
if ($print_h_guard) {
|
||||
print <<<'EOD'
|
||||
#ifndef ISO3166_H
|
||||
#define ISO3166_H
|
||||
|
||||
EOD;
|
||||
}
|
||||
|
||||
print <<<EOD
|
||||
|
||||
/* Whether ISO 3166-1 numeric */
|
||||
static int iso3166_numeric(int cc) {
|
||||
{$tab}static const unsigned char codes[$numeric_cnt] = {
|
||||
EOD;
|
||||
|
||||
for ($i = 0; $i < $numeric_cnt; $i++) {
|
||||
if ($i % 8 == 0) {
|
||||
print "\n$tab$tab";
|
||||
} else {
|
||||
print " ";
|
||||
}
|
||||
printf("0x%02X,", $numeric_tab[$i]);
|
||||
}
|
||||
print <<<EOD
|
||||
|
||||
{$tab}};
|
||||
{$tab}int b = cc >> 3;
|
||||
|
||||
{$tab}if (b < 0 || b >= $numeric_cnt) {
|
||||
{$tab}{$tab}return 0;
|
||||
{$tab}}
|
||||
{$tab}return codes[b] & (1 << (cc & 0x7)) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Whether ISO 3166-1 alpha2 */
|
||||
static int iso3166_alpha2(const char *cc) {
|
||||
{$tab}static const unsigned char codes[$alpha2_cnt] = {
|
||||
EOD;
|
||||
|
||||
for ($i = 0; $i < $alpha2_cnt; $i++) {
|
||||
if ($i % 8 == 0) {
|
||||
print "\n$tab$tab";
|
||||
} else {
|
||||
print " ";
|
||||
}
|
||||
printf("0x%02X,", $alpha2_tab[$i]);
|
||||
}
|
||||
print <<<EOD
|
||||
|
||||
{$tab}};
|
||||
{$tab}int cc_int;
|
||||
|
||||
{$tab}if (cc[0] < 'A' || cc[0] > 'Z' || cc[1] < 'A' || cc[1] > 'Z') {
|
||||
{$tab}{$tab}return 0;
|
||||
{$tab}}
|
||||
{$tab}cc_int = (cc[0] - 'A') * 26 + (cc[1] - 'A');
|
||||
|
||||
{$tab}return codes[cc_int >> 3] & (1 << (cc_int & 0x7)) ? 1 : 0;
|
||||
}
|
||||
|
||||
EOD;
|
||||
|
||||
if ($print_h_guard) {
|
||||
print <<<'EOD'
|
||||
|
||||
#endif /* ISO3166_H */
|
||||
|
||||
EOD;
|
||||
}
|
145
backend/tools/gen_iso4217_h.php
Normal file
145
backend/tools/gen_iso4217_h.php
Normal file
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
/* Generate ISO 4217 include "backend/iso4217.h" for "backend/gs1.c" */
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2021 <rstuart114@gmail.com>
|
||||
*/
|
||||
/* To create "backend/iso4217.h" (from project directory):
|
||||
*
|
||||
* php backend/tools/gen_iso4217_h.php > backend/iso4217.h
|
||||
*/
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
||||
$basename = basename(__FILE__);
|
||||
$dirname = dirname(__FILE__);
|
||||
$dirdirname = basename(dirname($dirname)) . '/' . basename($dirname);
|
||||
|
||||
$opts = getopt('c:h:t:');
|
||||
|
||||
$print_copyright = isset($opts['c']) ? (bool) $opts['c'] : true;
|
||||
$print_h_guard = isset($opts['h']) ? (bool) $opts['h'] : true;
|
||||
$tab = isset($opts['t']) ? $opts['t'] : ' ';
|
||||
|
||||
$numeric = array(
|
||||
/*ALL*/ 8, /*DZD*/ 12, /*ARS*/ 32, /*AUD*/ 36, /*BSD*/ 44, /*BHD*/ 48, /*BDT*/ 50, /*AMD*/ 51, /*BBD*/ 52, /*BMD*/ 60,
|
||||
/*BTN*/ 64, /*BOB*/ 68, /*BWP*/ 72, /*BZD*/ 84, /*SBD*/ 90, /*BND*/ 96, /*MMK*/ 104, /*BIF*/ 108, /*KHR*/ 116, /*CAD*/ 124,
|
||||
/*CVE*/ 132, /*KYD*/ 136, /*LKR*/ 144, /*CLP*/ 152, /*CNY*/ 156, /*COP*/ 170, /*KMF*/ 174, /*CRC*/ 188, /*HRK*/ 191, /*CUP*/ 192,
|
||||
/*CZK*/ 203, /*DKK*/ 208, /*DOP*/ 214, /*SVC*/ 222, /*ETB*/ 230, /*ERN*/ 232, /*FKP*/ 238, /*FJD*/ 242, /*DJF*/ 262, /*GMD*/ 270,
|
||||
/*GIP*/ 292, /*GTQ*/ 320, /*GNF*/ 324, /*GYD*/ 328, /*HTG*/ 332, /*HNL*/ 340, /*HKD*/ 344, /*HUF*/ 348, /*ISK*/ 352, /*INR*/ 356,
|
||||
/*IDR*/ 360, /*IRR*/ 364, /*IQD*/ 368, /*ILS*/ 376, /*JMD*/ 388, /*JPY*/ 392, /*KZT*/ 398, /*JOD*/ 400, /*KES*/ 404, /*KPW*/ 408,
|
||||
/*KRW*/ 410, /*KWD*/ 414, /*KGS*/ 417, /*LAK*/ 418, /*LBP*/ 422, /*LSL*/ 426, /*LRD*/ 430, /*LYD*/ 434, /*MOP*/ 446, /*MWK*/ 454,
|
||||
/*MYR*/ 458, /*MVR*/ 462, /*MUR*/ 480, /*MXN*/ 484, /*MNT*/ 496, /*MDL*/ 498, /*MAD*/ 504, /*OMR*/ 512, /*NAD*/ 516, /*NPR*/ 524,
|
||||
/*ANG*/ 532, /*AWG*/ 533, /*VUV*/ 548, /*NZD*/ 554, /*NIO*/ 558, /*NGN*/ 566, /*NOK*/ 578, /*PKR*/ 586, /*PAB*/ 590, /*PGK*/ 598,
|
||||
/*PYG*/ 600, /*PEN*/ 604, /*PHP*/ 608, /*QAR*/ 634, /*RUB*/ 643, /*RWF*/ 646, /*SHP*/ 654, /*SAR*/ 682, /*SCR*/ 690, /*SLL*/ 694,
|
||||
/*SGD*/ 702, /*VND*/ 704, /*SOS*/ 706, /*ZAR*/ 710, /*SSP*/ 728, /*SZL*/ 748, /*SEK*/ 752, /*CHF*/ 756, /*SYP*/ 760, /*THB*/ 764,
|
||||
/*TOP*/ 776, /*TTD*/ 780, /*AED*/ 784, /*TND*/ 788, /*UGX*/ 800, /*MKD*/ 807, /*EGP*/ 818, /*GBP*/ 826, /*TZS*/ 834, /*USD*/ 840,
|
||||
/*UYU*/ 858, /*UZS*/ 860, /*WST*/ 882, /*YER*/ 886, /*TWD*/ 901, /*UYW*/ 927, /*VES*/ 928, /*MRU*/ 929, /*STN*/ 930, /*CUC*/ 931,
|
||||
/*ZWL*/ 932, /*BYN*/ 933, /*TMT*/ 934, /*GHS*/ 936, /*SDG*/ 938, /*UYI*/ 940, /*RSD*/ 941, /*MZN*/ 943, /*AZN*/ 944, /*RON*/ 946,
|
||||
/*CHE*/ 947, /*CHW*/ 948, /*TRY*/ 949, /*XAF*/ 950, /*XCD*/ 951, /*XOF*/ 952, /*XPF*/ 953, /*XBA*/ 955, /*XBB*/ 956, /*XBC*/ 957,
|
||||
/*XBD*/ 958, /*XAU*/ 959, /*XDR*/ 960, /*XAG*/ 961, /*XPT*/ 962, /*XTS*/ 963, /*XPD*/ 964, /*XUA*/ 965, /*ZMW*/ 967, /*SRD*/ 968,
|
||||
/*MGA*/ 969, /*COU*/ 970, /*AFN*/ 971, /*TJS*/ 972, /*AOA*/ 973, /*BGN*/ 975, /*CDF*/ 976, /*BAM*/ 977, /*EUR*/ 978, /*MXV*/ 979,
|
||||
/*UAH*/ 980, /*GEL*/ 981, /*BOV*/ 984, /*PLN*/ 985, /*BRL*/ 986, /*CLF*/ 990, /*XSU*/ 994, /*USN*/ 997, /*XXX*/ 999,
|
||||
);
|
||||
|
||||
$numeric_tab = array();
|
||||
$val = 0;
|
||||
$byte = 0;
|
||||
$max = $numeric[count($numeric) - 1];
|
||||
for ($i = 0; $i <= $max; $i++) {
|
||||
if ($i && $i % 8 == 0) {
|
||||
$numeric_tab[$byte++] = $val;
|
||||
$val = 0;
|
||||
}
|
||||
if (in_array($i, $numeric)) {
|
||||
$val |= 1 << ($i & 0x7);
|
||||
}
|
||||
}
|
||||
$numeric_tab[$byte++] = $val;
|
||||
$numeric_cnt = count($numeric_tab);
|
||||
|
||||
print <<<EOD
|
||||
/*
|
||||
* ISO 4217 currency codes generated by "$dirdirname/$basename"
|
||||
*/
|
||||
|
||||
EOD;
|
||||
|
||||
if ($print_copyright) {
|
||||
print <<<'EOD'
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
|
||||
EOD;
|
||||
}
|
||||
|
||||
if ($print_h_guard) {
|
||||
print <<<'EOD'
|
||||
#ifndef ISO4217_H
|
||||
#define ISO4217_H
|
||||
|
||||
EOD;
|
||||
}
|
||||
|
||||
print <<<EOD
|
||||
|
||||
/* Whether ISO 4217-1 numeric */
|
||||
static int iso4217_numeric(int cc) {
|
||||
{$tab}static const unsigned char codes[$numeric_cnt] = {
|
||||
EOD;
|
||||
|
||||
for ($i = 0; $i < $numeric_cnt; $i++) {
|
||||
if ($i % 8 == 0) {
|
||||
print "\n$tab$tab";
|
||||
} else {
|
||||
print " ";
|
||||
}
|
||||
printf("0x%02X,", $numeric_tab[$i]);
|
||||
}
|
||||
print <<<EOD
|
||||
|
||||
{$tab}};
|
||||
{$tab}int b = cc >> 3;
|
||||
|
||||
{$tab}if (b < 0 || b >= $numeric_cnt) {
|
||||
{$tab}{$tab}return 0;
|
||||
{$tab}}
|
||||
{$tab}return codes[b] & (1 << (cc & 0x7)) ? 1 : 0;
|
||||
}
|
||||
|
||||
EOD;
|
||||
|
||||
if ($print_h_guard) {
|
||||
print <<<'EOD'
|
||||
|
||||
#endif /* ISO4217_H */
|
||||
|
||||
EOD;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue