libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
icao2cc.c
1/*
2 * CDDL HEADER START
3 *
4 * This file and its contents are supplied under the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may only use this file in accordance with the terms of version
7 * 1.0 of the CDDL.
8 *
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.illumos.org/license/CDDL.
12 *
13 * CDDL HEADER END
14*/
15/*
16 * Copyright 2023 Saso Kiselkov. All rights reserved.
17 */
18
19#include <stdarg.h>
20#include <stdio.h>
21#include <string.h>
22
23#include "acfutils/assert.h"
24#include "acfutils/icao2cc.h"
25#include "acfutils/helpers.h"
26
27typedef struct {
28 const char *icao;
29 const char *cc;
30 const char *lang;
31} icao2cc_t;
32
33/*
34 * Although we'd love to have this table be uniquely keyed by ICAO code,
35 * unfortunately not every place has its own unique ICAO prefix. However,
36 * they're usually small enough that we don't need to worry too much.
37 * Not all ICAO codes are strictly prefix-based. So to avoid matching a
38 * more general (shorter) code before a more specific (longer) one, we lay
39 * this table out to place more specific codes ahead of the more general
40 * ones.
41 */
42static icao2cc_t icao2cc_table[] = {
43 /*
44 * We place some individual airport entries at the start of the table
45 * to guarantee they get picked up by the scanner ahead of all the
46 * more generic ones.
47 */
48 { .icao = "CYAD", .cc = "CA", .lang = "fr" },
49 { .icao = "CYAH", .cc = "CA", .lang = "fr" },
50 { .icao = "CYAS", .cc = "CA", .lang = "fr" },
51 { .icao = "CYBC", .cc = "CA", .lang = "fr" },
52 { .icao = "CYBG", .cc = "CA", .lang = "fr" },
53 { .icao = "CYBX", .cc = "CA", .lang = "fr" },
54 { .icao = "CYDO", .cc = "CA", .lang = "fr" },
55 { .icao = "CYEY", .cc = "CA", .lang = "fr" },
56 { .icao = "CYFE", .cc = "CA", .lang = "fr" },
57 { .icao = "CYFJ", .cc = "CA", .lang = "fr" },
58 { .icao = "CYFJ", .cc = "CA", .lang = "fr" },
59 { .icao = "CYGL", .cc = "CA", .lang = "fr" },
60 { .icao = "CYGP", .cc = "CA", .lang = "fr" },
61 { .icao = "CYGR", .cc = "CA", .lang = "fr" },
62 { .icao = "CYGV", .cc = "CA", .lang = "fr" },
63 { .icao = "CYGW", .cc = "CA", .lang = "fr" },
64 { .icao = "CYHA", .cc = "CA", .lang = "fr" },
65 { .icao = "CYHH", .cc = "CA", .lang = "fr" },
66 { .icao = "CYHR", .cc = "CA", .lang = "fr" },
67 { .icao = "CYHU", .cc = "CA", .lang = "fr" },
68 { .icao = "CYIF", .cc = "CA", .lang = "fr" },
69 { .icao = "CYIK", .cc = "CA", .lang = "fr" },
70 { .icao = "CYJN", .cc = "CA", .lang = "fr" },
71 { .icao = "CYKG", .cc = "CA", .lang = "fr" },
72 { .icao = "CYKL", .cc = "CA", .lang = "fr" },
73 { .icao = "CYKO", .cc = "CA", .lang = "fr" },
74 { .icao = "CYKQ", .cc = "CA", .lang = "fr" },
75 { .icao = "CYLA", .cc = "CA", .lang = "fr" },
76 { .icao = "CYLQ", .cc = "CA", .lang = "fr" },
77 { .icao = "CYLU", .cc = "CA", .lang = "fr" },
78 { .icao = "CYME", .cc = "CA", .lang = "fr" },
79 { .icao = "CYML", .cc = "CA", .lang = "fr" },
80 { .icao = "CYMT", .cc = "CA", .lang = "fr" },
81 { .icao = "CYMU", .cc = "CA", .lang = "fr" },
82 { .icao = "CYMW", .cc = "CA", .lang = "fr" },
83 { .icao = "CYMX", .cc = "CA", .lang = "fr" },
84 { .icao = "CYNA", .cc = "CA", .lang = "fr" },
85 { .icao = "CYNC", .cc = "CA", .lang = "fr" },
86 { .icao = "CYND", .cc = "CA", .lang = "fr" },
87 { .icao = "CYNM", .cc = "CA", .lang = "fr" },
88 { .icao = "CYOY", .cc = "CA", .lang = "fr" },
89 { .icao = "CYPH", .cc = "CA", .lang = "fr" },
90 { .icao = "CYPN", .cc = "CA", .lang = "fr" },
91 { .icao = "CYPP", .cc = "CA", .lang = "fr" },
92 { .icao = "CYPX", .cc = "CA", .lang = "fr" },
93 { .icao = "CYQB", .cc = "CA", .lang = "fr" },
94 { .icao = "CYQB", .cc = "CA", .lang = "fr" },
95 { .icao = "CYRC", .cc = "CA", .lang = "fr" },
96 { .icao = "CYRI", .cc = "CA", .lang = "fr" },
97 { .icao = "CYRJ", .cc = "CA", .lang = "fr" },
98 { .icao = "CYRQ", .cc = "CA", .lang = "fr" },
99 { .icao = "CYSC", .cc = "CA", .lang = "fr" },
100 { .icao = "CYSG", .cc = "CA", .lang = "fr" },
101 { .icao = "CYSZ", .cc = "CA", .lang = "fr" },
102 { .icao = "CYTF", .cc = "CA", .lang = "fr" },
103 { .icao = "CYTQ", .cc = "CA", .lang = "fr" },
104 { .icao = "CYUL", .cc = "CA", .lang = "fr" },
105 { .icao = "CYUY", .cc = "CA", .lang = "fr" },
106 { .icao = "CYVB", .cc = "CA", .lang = "fr" },
107 { .icao = "CYVO", .cc = "CA", .lang = "fr" },
108 { .icao = "CYVP", .cc = "CA", .lang = "fr" },
109 { .icao = "CYXK", .cc = "CA", .lang = "fr" },
110 { .icao = "CYYY", .cc = "CA", .lang = "fr" },
111 { .icao = "CYZG", .cc = "CA", .lang = "fr" },
112 { .icao = "CYZV", .cc = "CA", .lang = "fr" },
113 { .icao = "CZBM", .cc = "CA", .lang = "fr" },
114 { .icao = "CZEM", .cc = "CA", .lang = "fr" },
115 { .icao = "ETAD", .cc = "US", .lang = "en" },
116 { .icao = "ETAR", .cc = "US", .lang = "en" },
117 { .icao = "ETNG", .cc = "US", .lang = "en" },
118 { .icao = "ETOU", .cc = "US", .lang = "en" },
119 { .icao = "LIDT", .cc = "IT", .lang = "de" },
120 { .icao = "LIPB", .cc = "IT", .lang = "de" },
121 { .icao = "LIVD", .cc = "IT", .lang = "de" },
122 { .icao = "LSGC", .cc = "CH", .lang = "fr" },
123 { .icao = "LSGE", .cc = "CH", .lang = "fr" },
124 { .icao = "LSGG", .cc = "CH", .lang = "fr" },
125 { .icao = "LSGL", .cc = "CH", .lang = "fr" },
126 { .icao = "LSGS", .cc = "CH", .lang = "fr" },
127 { .icao = "LSMP", .cc = "CH", .lang = "fr" },
128 { .icao = "LSZA", .cc = "CH", .lang = "it" },
129 { .icao = "LSZL", .cc = "CH", .lang = "it" },
130 { .icao = "LSZQ", .cc = "CH", .lang = "fr" },
131
132 /*
133 * The more generic entries come after the airport-specific ones.
134 */
135 { .icao = "AG", .cc = "SB", .lang = "XX" }, /* Solomon Islands */
136 { .icao = "AN", .cc = "NR", .lang = "XX" }, /* Nauru */
137 { .icao = "AY", .cc = "PG", .lang = "XX" }, /* Papua New Guinea */
138 { .icao = "BG", .cc = "GL", .lang = "kl" }, /* Greenland */
139 { .icao = "BI", .cc = "IS", .lang = "is" }, /* Iceland */
140 { .icao = "BK", .cc = "XK", .lang = "sq" }, /* Kosovo */
141 { .icao = "C", .cc = "CA", .lang = "en" }, /* Canada */
142 { .icao = "DA", .cc = "DZ", .lang = "ar" }, /* Algeria */
143 { .icao = "DB", .cc = "BJ", .lang = "fr" }, /* Benin */
144 { .icao = "DF", .cc = "BF", .lang = "fr" }, /* Burkina Faso */
145 { .icao = "DG", .cc = "GH", .lang = "en" }, /* Ghana */
146 { .icao = "DI", .cc = "CI", .lang = "fr" }, /* Ivory Coast */
147 { .icao = "DN", .cc = "NG", .lang = "en" }, /* Nigeria */
148 { .icao = "DR", .cc = "NE", .lang = "XX" }, /* Niger */
149 { .icao = "DT", .cc = "TN", .lang = "ar" }, /* Tunisia */
150 { .icao = "DX", .cc = "TG", .lang = "XX" }, /* Togo */
151 { .icao = "EB", .cc = "BE", .lang = "fr" }, /* Belgium */
152 { .icao = "ED", .cc = "DE", .lang = "de" }, /* Germany */
153 { .icao = "EE", .cc = "EE", .lang = "et" }, /* Estonia */
154 { .icao = "EF", .cc = "FI", .lang = "fi" }, /* Finland */
155 { .icao = "EG", .cc = "GB", .lang = "en" }, /* United Kingdom */
156 { .icao = "EG", .cc = "GS", .lang = "XX" }, /* South Georgia and the */
157 /* South Sandwich Islands */
158 { .icao = "EH", .cc = "NL", .lang = "nl" }, /* Netherlands */
159 { .icao = "EI", .cc = "IE", .lang = "en" }, /* Ireland */
160 { .icao = "EK", .cc = "DK", .lang = "da" }, /* Denmark */
161 { .icao = "EL", .cc = "LU", .lang = "de" }, /* Luxembourg */
162 { .icao = "EN", .cc = "NO", .lang = "nn" }, /* Norway */
163 { .icao = "EP", .cc = "PL", .lang = "pl" }, /* Poland */
164 { .icao = "ES", .cc = "SE", .lang = "sv" }, /* Sweden */
165 { .icao = "ET", .cc = "DE", .lang = "de" }, /* Germany */
166 { .icao = "EV", .cc = "LV", .lang = "lv" }, /* Latvia */
167 { .icao = "EY", .cc = "LT", .lang = "lt" }, /* Lithuania */
168 { .icao = "FA", .cc = "ZA", .lang = "en" }, /* South Africa */
169 { .icao = "FB", .cc = "BW", .lang = "en" }, /* Botswana */
170 { .icao = "FC", .cc = "CG", .lang = "fr" }, /* Republic of the Congo */
171 { .icao = "FD", .cc = "SZ", .lang = "en" }, /* Swaziland */
172 { .icao = "FE", .cc = "CF", .lang = "fr" }, /* Central African Republic */
173 { .icao = "FG", .cc = "GQ", .lang = "pt" }, /* Equatorial Guinea */
174 { .icao = "FH", .cc = "SH", .lang = "en" }, /* Saint Helena Ascension */
175 /* and Tristan da Cunha */
176 { .icao = "FI", .cc = "MU", .lang = "XX" }, /* Mauritius */
177 { .icao = "FJ", .cc = "IO", .lang = "en" }, /* British Indian Ocean */
178 /* Territory */
179 { .icao = "FK", .cc = "CM", .lang = "fr" }, /* Cameroon */
180 { .icao = "FL", .cc = "ZM", .lang = "XX" }, /* Zambia */
181 { .icao = "FMC", .cc = "KM", .lang = "XX" },/* Comoros */
182 { .icao = "FME", .cc = "RE", .lang = "XX" },/* Réunion */
183 { .icao = "FMM", .cc = "MG", .lang = "fr" },/* Madagascar */
184 { .icao = "FMN", .cc = "MG", .lang = "fr" },/* Madagascar */
185 { .icao = "FMS", .cc = "MG", .lang = "fr" },/* Madagascar */
186 { .icao = "FM", .cc = "YT", .lang = "XX" }, /* Mayotte */
187 { .icao = "FN", .cc = "AO", .lang = "pt" }, /* Angola */
188 { .icao = "FO", .cc = "GA", .lang = "XX" }, /* Gabon */
189 { .icao = "FP", .cc = "ST", .lang = "pt" }, /* São Tomé and Príncipe */
190 { .icao = "FQ", .cc = "MZ", .lang = "pt" }, /* Mozambique */
191 { .icao = "FS", .cc = "SC", .lang = "XX" }, /* Seychelles */
192 { .icao = "FT", .cc = "TD", .lang = "XX" }, /* Chad */
193 { .icao = "FV", .cc = "ZW", .lang = "en" }, /* Zimbabwe */
194 { .icao = "FW", .cc = "MW", .lang = "XX" }, /* Malawi */
195 { .icao = "FX", .cc = "LS", .lang = "XX" }, /* Lesotho */
196 { .icao = "FY", .cc = "NA", .lang = "XX" }, /* Namibia */
197 { .icao = "FZ", .cc = "CD", .lang = "XX" }, /* Democratic Republic of */
198 /* the Congo */
199 { .icao = "GA", .cc = "ML", .lang = "XX" }, /* Mali */
200 { .icao = "GB", .cc = "GM", .lang = "XX" }, /* Gambia */
201 { .icao = "GC", .cc = "ES", .lang = "es" }, /* Spain */
202 { .icao = "GE", .cc = "ES", .lang = "es" }, /* Spain */
203 { .icao = "GF", .cc = "SL", .lang = "XX" }, /* Sierra Leone */
204 { .icao = "GG", .cc = "GW", .lang = "pt" }, /* Guinea-Bissau */
205 { .icao = "GL", .cc = "LR", .lang = "XX" }, /* Liberia */
206 { .icao = "GM", .cc = "MA", .lang = "ar" }, /* Morocco */
207 { .icao = "GO", .cc = "SN", .lang = "fr" }, /* Senegal */
208 { .icao = "GQ", .cc = "MR", .lang = "XX" }, /* Mauritania */
209 { .icao = "GS", .cc = "EH", .lang = "XX" }, /* Western Sahara */
210 { .icao = "GU", .cc = "GN", .lang = "XX" }, /* Guinea */
211 { .icao = "GV", .cc = "CV", .lang = "pt" }, /* Cape Verde */
212 { .icao = "HA", .cc = "ET", .lang = "XX" }, /* Ethiopia */
213 { .icao = "HB", .cc = "BI", .lang = "XX" }, /* Burundi */
214 { .icao = "HC", .cc = "SO", .lang = "XX" }, /* Somalia */
215 { .icao = "HD", .cc = "DJ", .lang = "XX" }, /* Djibouti */
216 { .icao = "HE", .cc = "EG", .lang = "ar" }, /* Egypt */
217 { .icao = "HH", .cc = "ER", .lang = "XX" }, /* Eritrea */
218 { .icao = "HK", .cc = "KE", .lang = "sw" }, /* Kenya */
219 { .icao = "HL", .cc = "LY", .lang = "ar" }, /* Libya */
220 { .icao = "HR", .cc = "RW", .lang = "XX" }, /* Rwanda */
221 { .icao = "HS", .cc = "SD", .lang = "XX" }, /* Sudan */
222 { .icao = "HS", .cc = "SS", .lang = "XX" }, /* South Sudan */
223 { .icao = "HT", .cc = "TZ", .lang = "XX" }, /* Tanzania */
224 { .icao = "HU", .cc = "UG", .lang = "XX" }, /* Uganda */
225 { .icao = "K", .cc = "US", .lang = "en" }, /* United States */
226 { .icao = "LA", .cc = "AL", .lang = "sq" }, /* Albania */
227 { .icao = "LB", .cc = "BG", .lang = "bg" }, /* Bulgaria */
228 { .icao = "LC", .cc = "CY", .lang = "XX" }, /* Cyprus */
229 { .icao = "LD", .cc = "HR", .lang = "hr" }, /* Croatia */
230 { .icao = "LE", .cc = "ES", .lang = "es" }, /* Spain */
231 { .icao = "LF", .cc = "FR", .lang = "fr" }, /* France */
232 { .icao = "LF", .cc = "PM", .lang = "fr" }, /* Saint Pierre and Miquelon */
233 { .icao = "LG", .cc = "GR", .lang = "el" }, /* Greece */
234 { .icao = "LH", .cc = "HU", .lang = "hu" }, /* Hungary */
235 { .icao = "LI", .cc = "IT", .lang = "it" }, /* Italy */
236 { .icao = "LJ", .cc = "SI", .lang = "sl" }, /* Slovenia */
237 { .icao = "LK", .cc = "CZ", .lang = "cs" }, /* Czech Republic */
238 { .icao = "LL", .cc = "IL", .lang = "he" }, /* Israel */
239 { .icao = "LM", .cc = "MT", .lang = "mt" }, /* Malta */
240 { .icao = "LN", .cc = "MC", .lang = "fr" }, /* Monaco */
241 { .icao = "LO", .cc = "AT", .lang = "de" }, /* Austria */
242 { .icao = "LP", .cc = "PT", .lang = "pt" }, /* Portugal */
243 { .icao = "LQ", .cc = "BA", .lang = "bs" }, /* Bosnia and Herzegovina */
244 { .icao = "LR", .cc = "RO", .lang = "ro" }, /* Romania */
245 { .icao = "LS", .cc = "CH", .lang = "de" }, /* Switzerland */
246 { .icao = "LT", .cc = "TR", .lang = "tr" }, /* Turkey */
247 { .icao = "LU", .cc = "MD", .lang = "ro" }, /* Moldova */
248 { .icao = "LV", .cc = "PS", .lang = "ar" }, /* Palestine */
249 { .icao = "LW", .cc = "MK", .lang = "mk" }, /* Macedonia */
250 { .icao = "LX", .cc = "GI", .lang = "en" }, /* Gibraltar */
251 { .icao = "LY", .cc = "ME", .lang = "sr" }, /* Montenegro */
252 { .icao = "LY", .cc = "RS", .lang = "sr" }, /* Serbia */
253 { .icao = "LZ", .cc = "SK", .lang = "sk" }, /* Slovakia */
254 { .icao = "MB", .cc = "TC", .lang = "en" }, /* Turks and Caicos Islands */
255 { .icao = "MD", .cc = "DO", .lang = "es" }, /* Dominican Republic */
256 { .icao = "MG", .cc = "GT", .lang = "es" }, /* Guatemala */
257 { .icao = "MH", .cc = "HN", .lang = "es" }, /* Honduras */
258 { .icao = "MI", .cc = "VI", .lang = "en" }, /* United States */
259 /* Virgin Islands */
260 { .icao = "MK", .cc = "JM", .lang = "en" }, /* Jamaica */
261 { .icao = "MM", .cc = "MX", .lang = "es" }, /* Mexico */
262 { .icao = "MN", .cc = "NI", .lang = "es" }, /* Nicaragua */
263 { .icao = "MP", .cc = "PA", .lang = "es" }, /* Panama */
264 { .icao = "MR", .cc = "CR", .lang = "es" }, /* Costa Rica */
265 { .icao = "MS", .cc = "SV", .lang = "es" }, /* El Salvador */
266 { .icao = "MT", .cc = "HT", .lang = "fr" }, /* Haiti */
267 { .icao = "MU", .cc = "CU", .lang = "es" }, /* Cuba */
268 { .icao = "MW", .cc = "KY", .lang = "en" }, /* Cayman Islands */
269 { .icao = "MY", .cc = "BS", .lang = "en" }, /* Bahamas */
270 { .icao = "MZ", .cc = "BZ", .lang = "en" }, /* Belize */
271 { .icao = "NC", .cc = "CK", .lang = "en" }, /* Cook Islands */
272 { .icao = "NE", .cc = "CL", .lang = "es" }, /* Chile */
273 { .icao = "NFT", .cc = "TO", .lang = "XX" },/* Tonga */
274 { .icao = "NF", .cc = "FJ", .lang = "XX" }, /* Fiji */
275 { .icao = "NGF", .cc = "TV", .lang = "XX" },/* Tuvalu */
276 { .icao = "NG", .cc = "KI", .lang = "XX" }, /* Kiribati */
277 { .icao = "NI", .cc = "NU", .lang = "XX" }, /* Niue */
278 { .icao = "NL", .cc = "WF", .lang = "XX" }, /* Wallis and Futuna */
279 { .icao = "NS", .cc = "AS", .lang = "en" }, /* American Samoa */
280 { .icao = "NS", .cc = "WS", .lang = "XX" }, /* Samoa */
281 { .icao = "NT", .cc = "PF", .lang = "fr" }, /* French Polynesia */
282 { .icao = "NV", .cc = "VU", .lang = "XX" }, /* Vanuatu */
283 { .icao = "NW", .cc = "NC", .lang = "XX" }, /* New Caledonia */
284 { .icao = "NZ", .cc = "NZ", .lang = "en" }, /* New Zealand */
285 { .icao = "OA", .cc = "AF", .lang = "ps" }, /* Afghanistan */
286 { .icao = "OB", .cc = "BH", .lang = "ar" }, /* Bahrain */
287 { .icao = "OE", .cc = "SA", .lang = "ar" }, /* Saudi Arabia */
288 { .icao = "OI", .cc = "IR", .lang = "fa" }, /* Iran */
289 { .icao = "OJ", .cc = "JO", .lang = "ar" }, /* Jordan */
290 { .icao = "OJ", .cc = "PS", .lang = "ar" }, /* Palestine */
291 { .icao = "OK", .cc = "KW", .lang = "ar" }, /* Kuwait */
292 { .icao = "OL", .cc = "LB", .lang = "ar" }, /* Lebanon */
293 { .icao = "OM", .cc = "AE", .lang = "ar" }, /* United Arab Emirates */
294 { .icao = "OO", .cc = "OM", .lang = "ar" }, /* Oman */
295 { .icao = "OP", .cc = "PK", .lang = "ur" }, /* Pakistan */
296 { .icao = "OR", .cc = "IQ", .lang = "ar" }, /* Iraq */
297 { .icao = "OS", .cc = "SY", .lang = "syr" },/* Syria */
298 { .icao = "OT", .cc = "QA", .lang = "ar" }, /* Qatar */
299 { .icao = "OY", .cc = "YE", .lang = "ar" }, /* Yemen */
300 { .icao = "PA", .cc = "US", .lang = "en" }, /* United States */
301 { .icao = "PB", .cc = "US", .lang = "en" }, /* United States */
302 { .icao = "PF", .cc = "US", .lang = "en" }, /* United States */
303 { .icao = "PG", .cc = "GU", .lang = "en" }, /* Guam */
304 { .icao = "PG", .cc = "MP", .lang = "en" }, /* Northern Mariana Islands */
305 { .icao = "PH", .cc = "US", .lang = "en" }, /* United States */
306 { .icao = "PJ", .cc = "US", .lang = "en" }, /* United States */
307 { .icao = "PK", .cc = "MH", .lang = "en" }, /* Marshall Islands */
308 { .icao = "PL", .cc = "NZ", .lang = "en" }, /* New Zealand */
309 { .icao = "PL", .cc = "US", .lang = "en" }, /* United States */
310 { .icao = "PM", .cc = "US", .lang = "en" }, /* United States */
311 { .icao = "PO", .cc = "US", .lang = "en" }, /* United States */
312 { .icao = "PP", .cc = "US", .lang = "en" }, /* United States */
313 { .icao = "PT", .cc = "FM", .lang = "XX" }, /* Federated States of */
314 /* Micronesia */
315 { .icao = "PT", .cc = "PW", .lang = "XX" }, /* Palau */
316 { .icao = "PW", .cc = "US", .lang = "en" }, /* United States */
317 { .icao = "RC", .cc = "TW", .lang = "zh" }, /* Taiwan */
318 { .icao = "RJ", .cc = "JP", .lang = "ja" }, /* Japan */
319 { .icao = "RK", .cc = "KR", .lang = "ko" }, /* South Korea */
320 { .icao = "RO", .cc = "JP", .lang = "ja" }, /* Japan */
321 { .icao = "RP", .cc = "PH", .lang = "en" }, /* Philippines */
322 { .icao = "SA", .cc = "AR", .lang = "es" }, /* Argentina */
323 { .icao = "SB", .cc = "BR", .lang = "pt" }, /* Brazil */
324 { .icao = "SC", .cc = "CL", .lang = "es" }, /* Chile */
325 { .icao = "SD", .cc = "BR", .lang = "pt" }, /* Brazil */
326 { .icao = "SE", .cc = "EC", .lang = "es" }, /* Ecuador */
327 { .icao = "SF", .cc = "FK", .lang = "en" }, /* Falkland Islands */
328 { .icao = "SG", .cc = "PY", .lang = "es" }, /* Paraguay */
329 { .icao = "SK", .cc = "CO", .lang = "es" }, /* Colombia */
330 { .icao = "SL", .cc = "BO", .lang = "es" }, /* Bolivia */
331 { .icao = "SM", .cc = "SR", .lang = "XX" }, /* Suriname */
332 { .icao = "SN", .cc = "BR", .lang = "pt" }, /* Brazil */
333 { .icao = "SO", .cc = "GF", .lang = "fr" }, /* French Guiana */
334 { .icao = "SP", .cc = "PE", .lang = "es" }, /* Peru */
335 { .icao = "SS", .cc = "BR", .lang = "pt" }, /* Brazil */
336 { .icao = "SU", .cc = "UY", .lang = "es" }, /* Uruguay */
337 { .icao = "SV", .cc = "VE", .lang = "es" }, /* Venezuela */
338 { .icao = "SW", .cc = "BR", .lang = "pt" }, /* Brazil */
339 { .icao = "SY", .cc = "GY", .lang = "XX" }, /* Guyana */
340 { .icao = "TA", .cc = "AG", .lang = "XX" }, /* Antigua and Barbuda */
341 { .icao = "TB", .cc = "BB", .lang = "XX" }, /* Barbados */
342 { .icao = "TD", .cc = "DM", .lang = "XX" }, /* Dominica */
343 { .icao = "TF", .cc = "BL", .lang = "fr" }, /* Saint Barthélemy */
344 { .icao = "TF", .cc = "GP", .lang = "fr" }, /* Guadeloupe */
345 { .icao = "TF", .cc = "MF", .lang = "fr" }, /* Saint Martin */
346 { .icao = "TF", .cc = "MQ", .lang = "fr" }, /* Martinique */
347 { .icao = "TG", .cc = "GD", .lang = "en" }, /* Grenada */
348 { .icao = "TI", .cc = "VI", .lang = "en" }, /* United States */
349 /* Virgin Islands */
350 { .icao = "TJ", .cc = "PR", .lang = "es" }, /* Puerto Rico */
351 { .icao = "TK", .cc = "KN", .lang = "en" }, /* Saint Kitts and Nevis */
352 { .icao = "TL", .cc = "LC", .lang = "en" }, /* Saint Lucia */
353 { .icao = "TN", .cc = "AW", .lang = "nl" }, /* Aruba */
354 { .icao = "TN", .cc = "BQ", .lang = "nl" }, /* Caribbean Netherlands */
355 { .icao = "TN", .cc = "CW", .lang = "nl" }, /* Curaçao */
356 { .icao = "TN", .cc = "SX", .lang = "nl" }, /* Sint Maarten */
357 { .icao = "TQ", .cc = "AI", .lang = "XX" }, /* Anguilla */
358 { .icao = "TR", .cc = "MS", .lang = "XX" }, /* Montserrat */
359 { .icao = "TT", .cc = "TT", .lang = "en" }, /* Trinidad and Tobago */
360 { .icao = "TU", .cc = "VG", .lang = "en" }, /* British Virgin Islands */
361 { .icao = "TV", .cc = "VC", .lang = "XX" }, /* Saint Vincent and */
362 /* the Grenadines */
363 { .icao = "TX", .cc = "BM", .lang = "XX" }, /* Bermuda */
364 { .icao = "UA", .cc = "KZ", .lang = "ky" }, /* Kazakhstan */
365 { .icao = "UB", .cc = "AZ", .lang = "XX" }, /* Azerbaijan */
366 { .icao = "UC", .cc = "KG", .lang = "XX" }, /* Kyrgyzstan */
367 { .icao = "UD", .cc = "AM", .lang = "XX" }, /* Armenia */
368 { .icao = "UE", .cc = "RU", .lang = "ru" }, /* Russia */
369 { .icao = "UG", .cc = "GE", .lang = "ka" }, /* Georgia */
370 { .icao = "UH", .cc = "RU", .lang = "ru" }, /* Russia */
371 { .icao = "UI", .cc = "RU", .lang = "ru" }, /* Russia */
372 { .icao = "UK", .cc = "UA", .lang = "uk" }, /* Ukraine */
373 { .icao = "UL", .cc = "RU", .lang = "ru" }, /* Russia */
374 { .icao = "UM", .cc = "BY", .lang = "ru" }, /* Belarus */
375 { .icao = "UN", .cc = "RU", .lang = "ru" }, /* Russia */
376 { .icao = "UO", .cc = "RU", .lang = "ru" }, /* Russia */
377 { .icao = "UR", .cc = "RU", .lang = "ru" }, /* Russia */
378 { .icao = "US", .cc = "RU", .lang = "ru" }, /* Russia */
379 { .icao = "UT", .cc = "TJ", .lang = "tg" }, /* Tajikistan */
380 { .icao = "UT", .cc = "TM", .lang = "XX" }, /* Turkmenistan */
381 { .icao = "UT", .cc = "UZ", .lang = "uz" }, /* Uzbekistan */
382 { .icao = "UU", .cc = "RU", .lang = "ru" }, /* Russia */
383 { .icao = "UW", .cc = "RU", .lang = "ru" }, /* Russia */
384 { .icao = "VA", .cc = "IN", .lang = "hi" }, /* India */
385 { .icao = "VB", .cc = "MM", .lang = "XX" }, /* Myanmar */
386 { .icao = "VC", .cc = "LK", .lang = "XX" }, /* Sri Lanka */
387 { .icao = "VD", .cc = "KH", .lang = "XX" }, /* Cambodia */
388 { .icao = "VE", .cc = "IN", .lang = "hi" }, /* India */
389 { .icao = "VG", .cc = "BD", .lang = "XX" }, /* Bangladesh */
390 { .icao = "VH", .cc = "HK", .lang = "zh" }, /* Hong Kong */
391 { .icao = "VI", .cc = "IN", .lang = "hi" }, /* India */
392 { .icao = "VL", .cc = "LA", .lang = "XX" }, /* Laos */
393 { .icao = "VM", .cc = "MO", .lang = "zh" }, /* Macau */
394 { .icao = "VN", .cc = "NP", .lang = "XX" }, /* Nepal */
395 { .icao = "VO", .cc = "IN", .lang = "hi" }, /* India */
396 { .icao = "VQ", .cc = "BT", .lang = "XX" }, /* Bhutan */
397 { .icao = "VR", .cc = "MV", .lang = "div" },/* Maldives */
398 { .icao = "VT", .cc = "TH", .lang = "th" }, /* Thailand */
399 { .icao = "VV", .cc = "VN", .lang = "vi" }, /* Vietnam */
400 { .icao = "VY", .cc = "MM", .lang = "XX" }, /* Myanmar */
401 { .icao = "WA", .cc = "ID", .lang = "id" }, /* Indonesia */
402 { .icao = "WB", .cc = "BN", .lang = "ms" }, /* Brunei */
403 { .icao = "WB", .cc = "MY", .lang = "ms" }, /* Malaysia */
404 { .icao = "WI", .cc = "ID", .lang = "id" }, /* Indonesia */
405 { .icao = "WM", .cc = "MY", .lang = "ms" }, /* Malaysia */
406 { .icao = "WP", .cc = "TL", .lang = "pt" }, /* Timor-Leste */
407 { .icao = "WS", .cc = "SG", .lang = "zh" }, /* Singapore */
408 { .icao = "YP", .cc = "CX", .lang = "XX" }, /* Christmas Island */
409 { .icao = "Y", .cc = "AU", .lang = "en" }, /* Australia */
410 { .icao = "ZB", .cc = "CN", .lang = "zh" }, /* China */
411 { .icao = "ZG", .cc = "CN", .lang = "zh" }, /* China */
412 { .icao = "ZH", .cc = "CN", .lang = "zh" }, /* China */
413 { .icao = "ZJ", .cc = "CN", .lang = "zh" }, /* China */
414 { .icao = "ZK", .cc = "KP", .lang = "ko" }, /* North Korea */
415 { .icao = "ZL", .cc = "CN", .lang = "zh" }, /* China */
416 { .icao = "ZM", .cc = "MN", .lang = "mn" }, /* Mongolia */
417 { .icao = "ZP", .cc = "CN", .lang = "zh" }, /* China */
418 { .icao = "ZS", .cc = "CN", .lang = "zh" }, /* China */
419 { .icao = "ZT", .cc = "CN", .lang = "zh" }, /* China */
420 { .icao = "ZU", .cc = "CN", .lang = "zh" }, /* China */
421 { .icao = "ZW", .cc = "CN", .lang = "zh" }, /* China */
422 { .icao = "ZY", .cc = "CN", .lang = "zh" }, /* China */
423 { .icao = NULL, .cc = NULL, .lang = NULL } /* Last entry */
424};
425
433const char *
434icao2cc(const char *icao)
435{
436 ASSERT(icao != NULL);
437 if (!is_valid_icao_code(icao))
438 return (NULL);
439 /*
440 * Doing a linear search is not particularly elegant, but the size
441 * of the ICAO table is fixed and small, so it probably doesn't
442 * matter anyway.
443 */
444 for (int i = 0; icao2cc_table[i].icao != NULL; i++) {
445 if (memcmp(icao, icao2cc_table[i].icao,
446 strlen(icao2cc_table[i].icao)) == 0)
447 return (icao2cc_table[i].cc);
448 }
449
450 return (NULL);
451}
452
462const char *
463icao2lang(const char *icao)
464{
465 for (int i = 0; icao2cc_table[i].icao != NULL; i++) {
466 if (memcmp(icao, icao2cc_table[i].icao,
467 strlen(icao2cc_table[i].icao)) == 0)
468 return (icao2cc_table[i].lang);
469 }
470 return ("XX");
471}
#define ASSERT(x)
Definition assert.h:208
bool_t is_valid_icao_code(const char *icao)
Definition helpers.c:312
const char * icao2lang(const char *icao)
Definition icao2cc.c:463
const char * icao2cc(const char *icao)
Definition icao2cc.c:434