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_iso3166alpha2.c File Reference

Purpose

The iso3166alpha2 linter ensures that the data represents an ISO 3166 "alpha-2" country code.

Remarks
The two-character 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 "alpha-2" codes.

Functional Description

◆ gs1_lint_iso3166alpha2()

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

Used to validate that an AI component is an ISO 3166 "alpha-2" country code.

Note
To enable this linter to hook into an alternative ISO 3166 "alpha-2" lookup function (provided by the user) the GS1_LINTER_CUSTOM_ISO3166ALPHA2_LOOKUP_H macro may be set to the name of a header file to be included that defines a custom GS1_LINTER_CUSTOM_ISO3166ALPHA2_LOOKUP macro.
If provided, the GS1_LINTER_CUSTOM_ISO3166ALPHA2_LOOKUP macro shall invoke whatever functionality is available in the user-provided lookup function, then using the result must assign to a locally-scoped variable as follows:
  • valid: Set to 1 if the lookup was successful. Otherwise 0.
Parameters
[in]dataPointer to the null-terminated data to be linted. Must not be NULL.
[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_ALPHA2 if the data is not a alpha-2 country code.
76{
77
78 /*
79 * Allow for a custom replacement of the lookup code to be provided.
80 *
81 */
82#ifdef GS1_LINTER_CUSTOM_ISO3166ALPHA2_LOOKUP
83#define GS1_LINTER_ISO3166ALPHA2_LOOKUP(cc) GS1_LINTER_CUSTOM_ISO3166ALPHA2_LOOKUP(cc)
84#else
85
86 /*
87 * Set of ISO 3166 alpha-2 country codes
88 *
89 * MAINTENANCE NOTE:
90 *
91 * Updates to the ISO 3166 alpha-2 country code list are provided here:
92 *
93 * https://isotc.iso.org/livelink/livelink?func=ll&objId=16944257&objAction=browse&viewType=1
94 *
95 */
96 static const uint64_t iso3166alpha2[] = {
97#if __STDC_VERSION__ >= 202311L
98 0b0001111010011010111110110111011111110111101111011011101101111011, // AA-CL: AD-AG AI AL-AM AO AQ-AU AW-AX AZ-BB BD-BJ BL-BO BQ-BT BV-BW BY-CA CC-CD CF-CH CI CK-CL
99 0b1110010011111100001000011010100000000001001010110000000001110000, // CM-EX: CM-CO CR CU-CZ DE DJ DK DM DO DZ EC EE EG-EH ER-ET
100 0b0000000000111010100100000000110111111001110111111010100000000000, // EY-HJ: FI-FJ FK FM FO FR GA-GB GD-GI GL-GN GP-GU GW GY
101 0b1011000101100000000110000001111011110000000000100000001011000000, // HK-JV: HK HM-HN HR HT-HU ID-IE IL-IO IQ-IT JE JM JO-JP
102 0b0000000010111000110101000010111110000010100000011111001010111111, // JW-MH: KE KG-KI KM-KN KP KR KW KY-KZ LA-LC LI LK LR-LV LY MA MC-MH
103 0b0011111111111111111010111010010011010010000100000000000010000000, // MI-OT: MK-NA NC NE-NG NI NL NO-NP NR NU NZ OM
104 0b0000001000111100111100011100101010000000000000000000000000000010, // OU-RF: PA PE-PH PK-PN PR-PT PW PY QA RE
105 0b0000000010001010100011111011111111100111010111001101110111111001, // RG-TR: RO RS RU RW SA-SE SG-SO SR-ST SV SX-SZ TC-TD TF-TH TJ-TO TR
106 0b0101100110000010000010000010000011101010101000010000001000000000, // TS-WD: TT TV-TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU
107 0b0100000000000010000000000000000000000000000000000000100000000000, // WE-YP: WF WS YE
108 0b0001000000100000000000100000000010000000000000000000000000000000, // YQ-ZZ: YT ZA ZM ZW
109#else
110 /*
111 * Fallback for compilers lacking binary literal support.
112 *
113 * Generated from the above data with:
114 *
115 * for (size_t i = 0; i < sizeof(iso3166alpha2) / sizeof(iso3166alpha2[0]); i++) { printf("%lx ", iso3166alpha2[i]); };
116 *
117 */
118 0x1e9afb77f7bdbb7b, 0xe4fc21a8012b0070, 0x003a900df9dfa800, 0xb160181ef00202c0,
119 0x00b8d42f8281f2bf, 0x3fffeba4d2100080, 0x023cf1ca80000002, 0x008a8fbfe75cddf9,
120 0x59820820eaa10200, 0x4002000000000800, 0x1020020080000000
121#endif
122 };
123
124/// \cond
125#define GS1_LINTER_ISO3166ALPHA2_LOOKUP(cc) do { \
126 if (strlen(cc) == 2 && cc[0] >= 'A' && cc[0] <= 'Z' && cc[1] >= 'A' && cc[1] <= 'Z') { \
127 int v = (cc[0] - 'A') * 26 + cc[1] - 'A'; \
128 GS1_LINTER_BITFIELD_LOOKUP(v, iso3166alpha2); \
129 } \
130} while (0)
131/// \endcond
132
133#endif
134
135 int valid = 0;
136
137 assert(data);
138
139 /*
140 * Ensure that the data is in the list.
141 *
142 */
143 GS1_LINTER_ISO3166ALPHA2_LOOKUP(data);
144 if (valid)
146
147 /*
148 * If not valid then indicate an error.
149 *
150 */
153 0,
154 strlen(data)
155 );
156
157}
#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:77
#define GS1_LINTER_RETURN_OK
Return from a linter indicating that no problem was detected with the given data.
Definition gs1syntaxdictionary-utils.h:62
@ GS1_LINTER_NOT_ISO3166_ALPHA2
A valid ISO 3166 two-character country code is required.
Definition gs1syntaxdictionary.h:99