GS1 Syntax Dictionary: Linter reference
A reference to the AI component linter routines referred to by the GS1 Syntax Dictionary.
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