GS1 Barcode Syntax Tests reference
A reference to the AI component "linter" routines referred to by the GS1 Barcode Syntax Dictionary. Copyright (c) 2022-2024 GS1 AISBL.
lint_iso3166.c File Reference

Purpose

The iso3166 linter ensures that the data represents a valid ISO 3166 "num-3" country code.

Remarks
The three-digit country codes are defined by ISO 3166-1: Codes for the representation of names of countries and their subdivisions - Part 1: Country code as the "num-3" codes.

Functional Description

◆ gs1_lint_iso3166()

GS1_SYNTAX_DICTIONARY_API gs1_lint_err_t gs1_lint_iso3166 ( const char *const  data,
size_t  data_len,
size_t *const  err_pos,
size_t *const  err_len 
)

Used to validate that an AI component is an ISO 3166 "num-3" country code.

Note
To enable this linter to hook into an alternative ISO 3166 "num-3" lookup function (provided by the user) the GS1_LINTER_CUSTOM_ISO3166_LOOKUP_H macro may be set to the name of a header file to be included that defines a custom GS1_LINTER_CUSTOM_ISO3166_LOOKUP macro.
If provided, the GS1_LINTER_CUSTOM_ISO3166_LOOKUP macro shall invoke whatever functionality is available in the user-provided lookup function using the first and second arguments, then using the result must assign to third (output) argument as follows:
  • valid: Set to 1 if the lookup was successful. Otherwise 0.
Parameters
[in]dataPointer to the data to be linted. Must not be NULL.
[in]data_lenLength of the data to be linted.
[in]data_lenLength of the data parameter.
[out]err_posTo facilitate error highlighting, the start position of the bad data is written to this pointer, if not NULL.
[out]err_lenThe length of the bad data is written to this pointer, if not NULL.
Returns
GS1_LINTER_OK if okay.
GS1_LINTER_NOT_ISO3166 if the data is not a num-3 country code.
78{
79
80 /*
81 * Allow for a custom replacement of the lookup code to be provided.
82 *
83 */
84#ifdef GS1_LINTER_CUSTOM_ISO3166_LOOKUP
85#define GS1_LINTER_ISO3166_LOOKUP(cc, cc_len, valid) GS1_LINTER_CUSTOM_ISO3166_LOOKUP(cc, cc_len, valid)
86#else
87
88 /*
89 * Set of ISO 3166 num-3 country codes
90 *
91 * MAINTENANCE NOTE:
92 *
93 * Updates to the ISO 3166 num-3 country code list are provided here:
94 *
95 * https://isotc.iso.org/livelink/livelink?func=ll&objId=16944257&objAction=browse&viewType=1
96 *
97 */
98 static const uint64_t iso3166[] = {
99#if __STDC_VERSION__ >= 202311L
100 0b0000100010101000100010001000100110001000100010001011100010001000, // 000-063: 004 008 010 012 016 020 024 028 031-032 036 040 044 048 050-052 056 060
101 0b1000101010101000000010100010100010001000100010001000100010001000, // 064-127: 064 068 070 072 074 076 084 086 090 092 096 100 104 108 112 116 120 124
102 0b0000100010001000100010001000101000100010001000110010100010001001, // 128-191: 132 136 140 144 148 152 156 158 162 166 170 174 175 178 180 184 188 191
103 0b1000100000011000100010100010001000100001111000110010001010100010, // 192-255: 192 196 203-204 208 212 214 218 222 226 231-234 238-239 242 246 248 250 254
104 0b0010101000101010000110000000000010001000100010001000100010001000, // 256-319: 258 260 262 266 268 270 275 276 288 292 296 300 304 308 312 316
105 0b1000100010001010100010001000100010001000100010001000100010001000, // 320-383: 320 324 328 332 334 336 340 344 348 352 356 360 364 368 372 376 380
106 0b1000100010000010100010001010001001100010001010100010001010100010, // 384-447: 384 388 392 398 400 404 408 410 414 417-418 422 426 428 430 434 438 440 442 446
107 0b0010001000100010001000100010001010001000000010001011100010001000, // 448-511: 450 454 458 462 466 470 474 478 480 484 492 496 498-500 504 508
108 0b1000100010001000100101110000100000001000001000100010001000100010, // 512-575: 512 516 520 524 528 531 533-535 540 548 554 558 562 566 570 574
109 0b0010110111100001000000101000100010001000100010001010001000100010, // 576-639: 578 580 581 583 584 585 586 591 598 600 604 608 612 616 620 624 626 630 634 638
110 0b0011001000001010000110110010001000100010001000101010001000000011, // 640-703: 642 643 646 652 654 659 660 662 663 666 670 674 678 682 686 688 690 694 702 703
111 0b1110001000001000000010001100100000001000100010001000100010101000, // 704-767: 704 705 706 710 716 724 728 729 732 740 744 748 752 756 760 762 764
112 0b1000100010001000100010001001101010001001000000000010000000100001, // 768-831: 768 772 776 780 784 788 792 795 796 798 800 804 807 818 826 831
113 0b1110000010000000001000100010101000000000000010000010000100000010, // 832-895: 832 833 834 840 850 854 858 860 862 876 882 887 894
114 0b0000000000000000000000000000000000000000000000000000000000000000, // 896-959:
115 0b0000000000000000000000000000000000000000000000000000000000000000, // 960-999:
116#else
117 /*
118 * Fallback for compilers lacking binary literal support.
119 *
120 * Generated from the above data with:
121 *
122 * for (size_t i = 0; i < sizeof(iso3166) / sizeof(iso3166[0]); i++) { printf("0x%016lx, ", iso3166[i]); };
123 *
124 */
125 0x08a888898888b888, 0x8aa80a2888888888, 0x0888888a22232889, 0x88188a2221e322a2,
126 0x2a2a180088888888, 0x888a888888888888, 0x888288a2622a22a2, 0x222222228808b888,
127 0x8888970808222222, 0x2de102888888a222, 0x320a1b222222a203, 0xe20808c8088888a8,
128 0x8888889a89002021, 0xe080222a00082102, 0x0000000000000000, 0x0000000000000000,
129#endif
130 };
131
132/// \cond
133#define GS1_LINTER_ISO3166_LOOKUP(cc, cc_len, valid) do { \
134 valid = 0; \
135 if (cc_len == 3 && isdigit(cc[0]) && isdigit(cc[1]) && isdigit(cc[2])) { \
136 int v = (cc[0] - '0') * 100 + (cc[1] - '0') * 10 + cc[2] - '0'; \
137 GS1_LINTER_BITFIELD_LOOKUP(v, iso3166, valid); \
138 } \
139} while (0)
140/// \endcond
141
142#endif
143
144 int valid;
145
146 assert(data);
147
148
149 /*
150 * Ensure that the data is in the list.
151 *
152 */
153 GS1_LINTER_ISO3166_LOOKUP(data, data_len, valid);
154 if (GS1_LINTER_LIKELY(valid))
156
157 /*
158 * If not valid then indicate an error.
159 *
160 */
163 0,
164 data_len
165 );
166
167}
#define GS1_LINTER_RETURN_ERROR(error, position, length)
Return from a linter indicating that a problem was detected with the given data.
Definition gs1syntaxdictionary-utils.h:103
#define GS1_LINTER_RETURN_OK
Return from a linter indicating that no problem was detected with the given data.
Definition gs1syntaxdictionary-utils.h:88
#define GS1_LINTER_LIKELY(x)
Implementation may provide hint to the compiler that the expression is likely to be true.
Definition gs1syntaxdictionary-utils.h:63
@ GS1_LINTER_NOT_ISO3166
A valid ISO 3166 three-digit country code is required.
Definition gs1syntaxdictionary.h:97