GS1 Syntax Dictionary: Linter reference
A reference to the AI component linter routines referred to by the GS1 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
The default lookup function provided by this linter is a binary search over a static list this is maintained in this file.
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.
77{
78
79 /*
80 * Allow for a custom replacement of the lookup code to be provided.
81 *
82 */
83#ifdef GS1_LINTER_CUSTOM_ISO3166ALPHA2_LOOKUP
84#define GS1_LINTER_ISO3166ALPHA2_LOOKUP(cc) GS1_LINTER_CUSTOM_ISO3166ALPHA2_LOOKUP(cc)
85#else
86
87 /*
88 * Set of ISO 3166 alpha-2 country codes
89 *
90 * MAINTENANCE NOTE:
91 *
92 * Updates to the ISO 3166 alpha-2 country code list are provided here:
93 *
94 * https://isotc.iso.org/livelink/livelink?func=ll&objId=16944257&objAction=browse&viewType=1
95 *
96 */
97 static const char iso3166alpha2[][3] = {
98 "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ",
99 "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ",
100 "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW", "CX", "CY", "CZ",
101 "DE", "DJ", "DK", "DM", "DO", "DZ",
102 "EC", "EE", "EG", "EH", "ER", "ES", "ET",
103 "FI", "FJ", "FK", "FM", "FO", "FR",
104 "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY",
105 "HK", "HM", "HN", "HR", "HT", "HU",
106 "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP",
107 "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ",
108 "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY",
109 "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ",
110 "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ",
111 "OM",
112 "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY",
113 "QA",
114 "RE", "RO", "RS", "RU", "RW",
115 "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ",
116 "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ",
117 "UA", "UG", "UM", "US", "UY", "UZ",
118 "VA", "VC", "VE", "VG", "VI", "VN", "VU",
119 "WF", "WS",
120 "YE", "YT",
121 "ZA", "ZM", "ZW",
122 };
123
124 /*
125 * Binary search over the above list.
126 *
127 */
128/// \cond
129#define GS1_LINTER_ISO3166ALPHA2_LOOKUP(cc) do { \
130 size_t s = 0; \
131 size_t e = sizeof(iso3166alpha2) / sizeof(iso3166alpha2[0]); \
132 while (s < e) { \
133 const size_t m = s + (e - s) / 2; \
134 const int cmp = strcmp(iso3166alpha2[m], cc); \
135 if (cmp < 0) \
136 s = m + 1; \
137 else if (cmp > 0) \
138 e = m; \
139 else { \
140 valid = 1; \
141 break; \
142 } \
143 } \
144} while (0)
145/// \endcond
146
147#endif
148
149 int valid = 0;
150
151 assert(data);
152
153 /*
154 * Ensure that the data is in the list.
155 *
156 */
157 GS1_LINTER_ISO3166ALPHA2_LOOKUP(data);
158 if (valid)
159 return GS1_LINTER_OK;
160
161 /*
162 * If not valid then indicate an error.
163 *
164 */
165 if (err_pos) *err_pos = 0;
166 if (err_len) *err_len = strlen(data);
168
169}
@ GS1_LINTER_OK
No issues were detected by the linter.
Definition gs1syntaxdictionary.h:66
@ GS1_LINTER_NOT_ISO3166_ALPHA2
A valid ISO 3166 two-character country code is required.
Definition gs1syntaxdictionary.h:88