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_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 *const  err_pos,
size_t *const  err_len 
)

Used to validate that an AI component is an ISO 3166 "num-3" 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 "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, 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 if the data is not a num-3 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_ISO3166_LOOKUP
84#define GS1_LINTER_ISO3166_LOOKUP(cc) GS1_LINTER_CUSTOM_ISO3166_LOOKUP(cc)
85#else
86
87 /*
88 * Set of ISO 3166 num-3 country codes
89 *
90 * MAINTENANCE NOTE:
91 *
92 * Updates to the ISO 3166 num-3 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 iso3166[][4] = {
98 "004", "008", "010", "012", "016", "020", "024", "028", "031", "032", "036", "040", "044", "048",
99 "050", "051", "052", "056", "060", "064", "068", "070", "072", "074", "076", "084", "086", "090", "092", "096",
100 "100", "104", "108", "112", "116", "120", "124", "132", "136", "140", "144", "148",
101 "152", "156", "158", "162", "166", "170", "174", "175", "178", "180", "184", "188", "191", "192", "196",
102 "203", "204", "208", "212", "214", "218", "222", "226", "231", "232", "233", "234", "238", "239", "242", "246", "248",
103 "250", "254", "258", "260", "262", "266", "268", "270", "275", "276", "288", "292", "296",
104 "300", "304", "308", "312", "316", "320", "324", "328", "332", "334", "336", "340", "344", "348",
105 "352", "356", "360", "364", "368", "372", "376", "380", "384", "388", "392", "398",
106 "400", "404", "408", "410", "414", "417", "418", "422", "426", "428", "430", "434", "438", "440", "442", "446",
107 "450", "454", "458", "462", "466", "470", "474", "478", "480", "484", "492", "496", "498", "499",
108 "500", "504", "508", "512", "516", "520", "524", "528", "531", "533", "534", "535", "540", "548",
109 "554", "558", "562", "566", "570", "574", "578", "580", "581", "583", "584", "585", "586", "591", "598",
110 "600", "604", "608", "612", "616", "620", "624", "626", "630", "634", "638", "642", "643", "646",
111 "652", "654", "659", "660", "662", "663", "666", "670", "674", "678", "682", "686", "688", "690", "694",
112 "702", "703", "704", "705", "706", "710", "716", "724", "728", "729", "732", "740", "744", "748",
113 "752", "756", "760", "762", "764", "768", "772", "776", "780", "784", "788", "792", "795", "796", "798",
114 "800", "804", "807", "818", "826", "831", "832", "833", "834", "840",
115 "850", "854", "858", "860", "862", "876", "882", "887", "894",
116 };
117
118 /*
119 * Binary search over the above list.
120 *
121 */
122/// \cond
123#define GS1_LINTER_ISO3166_LOOKUP(cc) do { \
124 size_t s = 0; \
125 size_t e = sizeof(iso3166) / sizeof(iso3166[0]); \
126 while (s < e) { \
127 const size_t m = s + (e - s) / 2; \
128 const int cmp = strcmp(iso3166[m], cc); \
129 if (cmp < 0) \
130 s = m + 1; \
131 else if (cmp > 0) \
132 e = m; \
133 else { \
134 valid = 1; \
135 break; \
136 } \
137 } \
138} while (0)
139/// \endcond
140
141#endif
142
143 int valid = 0;
144
145 assert(data);
146
147 /*
148 * Ensure that the data is in the list.
149 *
150 */
151 GS1_LINTER_ISO3166_LOOKUP(data);
152 if (valid)
153 return GS1_LINTER_OK;
154
155 /*
156 * If not valid then indicate an error.
157 *
158 */
159 if (err_pos) *err_pos = 0;
160 if (err_len) *err_len = strlen(data);
162
163}
@ GS1_LINTER_NOT_ISO3166
A valid ISO 3166 three-digit country code is required.
Definition gs1syntaxdictionary.h:86
@ GS1_LINTER_OK
No issues were detected by the linter.
Definition gs1syntaxdictionary.h:66