~ubuntu-branches/ubuntu/raring/iso-codes/raring

« back to all changes in this revision

Viewing changes to notes/Country.pm

  • Committer: Bazaar Package Importer
  • Author(s): Alastair McKinstry
  • Date: 2004-08-27 12:15:33 UTC
  • Revision ID: james.westby@ubuntu.com-20040827121533-culsmj9wcnwqxya3
Tags: upstream-0.40
ImportĀ upstreamĀ versionĀ 0.40

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#-----------------------------------------------------------------------
 
2
 
 
3
=head1 NAME
 
4
 
 
5
Locale::Country - ISO codes for country identification (ISO 3166)
 
6
 
 
7
=head1 SYNOPSIS
 
8
 
 
9
    use Locale::Country;
 
10
    
 
11
    $country = code2country('jp');               # $country gets 'Japan'
 
12
    $code    = country2code('Norway');           # $code gets 'no'
 
13
    
 
14
    @codes   = all_country_codes();
 
15
    @names   = all_country_names();
 
16
    
 
17
    # add "uk" as a pseudo country code for United Kingdom
 
18
    Locale::Country::_alias_code('uk' => 'gb');
 
19
 
 
20
=cut
 
21
 
 
22
#-----------------------------------------------------------------------
 
23
 
 
24
package Locale::Country;
 
25
use strict;
 
26
require 5.002;
 
27
 
 
28
#-----------------------------------------------------------------------
 
29
 
 
30
=head1 DESCRIPTION
 
31
 
 
32
The C<Locale::Country> module provides access to the ISO
 
33
codes for identifying countries, as defined in ISO 3166.
 
34
You can either access the codes via the L<conversion routines>
 
35
(described below), or with the two functions which return lists
 
36
of all country codes or all country names.
 
37
 
 
38
There are three different code sets you can use for identifying
 
39
countries:
 
40
 
 
41
=over 4
 
42
 
 
43
=item B<alpha-2>
 
44
 
 
45
Two letter codes, such as 'tv' for Tuvalu.
 
46
This code set is identified with the symbol C<LOCALE_CODE_ALPHA_2>.
 
47
 
 
48
=item B<alpha-3>
 
49
 
 
50
Three letter codes, such as 'brb' for Barbados.
 
51
This code set is identified with the symbol C<LOCALE_CODE_ALPHA_3>.
 
52
 
 
53
=item B<numeric>
 
54
 
 
55
Numeric codes, such as 064 for Bhutan.
 
56
This code set is identified with the symbol C<LOCALE_CODE_NUMERIC>.
 
57
 
 
58
=back
 
59
 
 
60
All of the routines take an optional additional argument
 
61
which specifies the code set to use.
 
62
If not specified, it defaults to the two-letter codes.
 
63
This is partly for backwards compatibility (previous versions
 
64
of this module only supported the alpha-2 codes), and
 
65
partly because they are the most widely used codes.
 
66
 
 
67
The alpha-2 and alpha-3 codes are not case-dependent,
 
68
so you can use 'BO', 'Bo', 'bO' or 'bo' for Bolivia.
 
69
When a code is returned by one of the functions in
 
70
this module, it will always be lower-case.
 
71
 
 
72
=cut
 
73
 
 
74
#-----------------------------------------------------------------------
 
75
 
 
76
require Exporter;
 
77
use Carp;
 
78
use Locale::Constants;
 
79
 
 
80
 
 
81
#-----------------------------------------------------------------------
 
82
#       Public Global Variables
 
83
#-----------------------------------------------------------------------
 
84
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
 
85
$VERSION   = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/);
 
86
@ISA       = qw(Exporter);
 
87
@EXPORT    = qw(code2country country2code
 
88
                all_country_codes all_country_names
 
89
                country_code2code
 
90
                LOCALE_CODE_ALPHA_2 LOCALE_CODE_ALPHA_3 LOCALE_CODE_NUMERIC);
 
91
 
 
92
#-----------------------------------------------------------------------
 
93
#       Private Global Variables
 
94
#-----------------------------------------------------------------------
 
95
my $CODES     = [];
 
96
my $COUNTRIES = [];
 
97
 
 
98
 
 
99
#=======================================================================
 
100
 
 
101
=head1 CONVERSION ROUTINES
 
102
 
 
103
There are three conversion routines: C<code2country()>, C<country2code()>,
 
104
and C<country_code2code()>.
 
105
 
 
106
=over 8
 
107
 
 
108
=item code2country( CODE, [ CODESET ] )
 
109
 
 
110
This function takes a country code and returns a string
 
111
which contains the name of the country identified.
 
112
If the code is not a valid country code, as defined by ISO 3166,
 
113
then C<undef> will be returned:
 
114
 
 
115
    $country = code2country('fi');
 
116
 
 
117
=item country2code( STRING, [ CODESET ] )
 
118
 
 
119
This function takes a country name and returns the corresponding
 
120
country code, if such exists.
 
121
If the argument could not be identified as a country name,
 
122
then C<undef> will be returned:
 
123
 
 
124
    $code = country2code('Norway', LOCALE_CODE_ALPHA_3);
 
125
    # $code will now be 'nor'
 
126
 
 
127
The case of the country name is not important.
 
128
See the section L<KNOWN BUGS AND LIMITATIONS> below.
 
129
 
 
130
=item country_code2code( CODE, CODESET, CODESET )
 
131
 
 
132
This function takes a country code from one code set,
 
133
and returns the corresponding code from another code set.
 
134
 
 
135
    $alpha2 = country_code2code('fin',
 
136
                 LOCALE_CODE_ALPHA_3 => LOCALE_CODE_ALPHA_2);
 
137
    # $alpha2 will now be 'fi'
 
138
 
 
139
If the code passed is not a valid country code in
 
140
the first code set, or if there isn't a code for the
 
141
corresponding country in the second code set,
 
142
then C<undef> will be returned.
 
143
 
 
144
=back
 
145
 
 
146
=cut
 
147
 
 
148
#=======================================================================
 
149
sub code2country
 
150
{
 
151
    my $code = shift;
 
152
    my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
 
153
 
 
154
 
 
155
    return undef unless defined $code;
 
156
 
 
157
    #-------------------------------------------------------------------
 
158
    # Make sure the code is in the right form before we use it
 
159
    # to look up the corresponding country.
 
160
    # We have to sprintf because the codes are given as 3-digits,
 
161
    # with leading 0's. Eg 052 for Barbados.
 
162
    #-------------------------------------------------------------------
 
163
    if ($codeset == LOCALE_CODE_NUMERIC)
 
164
    {
 
165
        return undef if ($code =~ /\D/);
 
166
        $code = sprintf("%.3d", $code);
 
167
    }
 
168
    else
 
169
    {
 
170
        $code = lc($code);
 
171
    }
 
172
 
 
173
    if (exists $CODES->[$codeset]->{$code})
 
174
    {
 
175
        return $CODES->[$codeset]->{$code};
 
176
    }
 
177
    else
 
178
    {
 
179
        #---------------------------------------------------------------
 
180
        # no such country code!
 
181
        #---------------------------------------------------------------
 
182
        return undef;
 
183
    }
 
184
}
 
185
 
 
186
sub country2code
 
187
{
 
188
    my $country = shift;
 
189
    my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
 
190
 
 
191
 
 
192
    return undef unless defined $country;
 
193
    $country = lc($country);
 
194
    if (exists $COUNTRIES->[$codeset]->{$country})
 
195
    {
 
196
        return $COUNTRIES->[$codeset]->{$country};
 
197
    }
 
198
    else
 
199
    {
 
200
        #---------------------------------------------------------------
 
201
        # no such country!
 
202
        #---------------------------------------------------------------
 
203
        return undef;
 
204
    }
 
205
}
 
206
 
 
207
sub country_code2code
 
208
{
 
209
    (@_ == 3) or croak "country_code2code() takes 3 arguments!";
 
210
 
 
211
    my $code = shift;
 
212
    my $inset = shift;
 
213
    my $outset = shift;
 
214
    my $outcode = shift;
 
215
    my $country;
 
216
 
 
217
 
 
218
    return undef if $inset == $outset;
 
219
    $country = code2country($code, $inset);
 
220
    return undef if not defined $country;
 
221
    $outcode = country2code($country, $outset);
 
222
    return $outcode;
 
223
}
 
224
 
 
225
#=======================================================================
 
226
 
 
227
=head1 QUERY ROUTINES
 
228
 
 
229
There are two function which can be used to obtain a list of all codes,
 
230
or all country names:
 
231
 
 
232
=over 8
 
233
 
 
234
=item C<all_country_codes( [ CODESET ] )>
 
235
 
 
236
Returns a list of all two-letter country codes.
 
237
The codes are guaranteed to be all lower-case,
 
238
and not in any particular order.
 
239
 
 
240
=item C<all_country_names( [ CODESET ] )>
 
241
 
 
242
Returns a list of all country names for which there is a corresponding
 
243
country code in the specified code set.
 
244
The names are capitalised, and not returned in any particular order.
 
245
 
 
246
Not all countries have alpha-3 and numeric codes -
 
247
some just have an alpha-2 code,
 
248
so you'll get a different number of countries
 
249
depending on which code set you specify.
 
250
 
 
251
=back
 
252
 
 
253
=cut
 
254
 
 
255
#=======================================================================
 
256
sub all_country_codes
 
257
{
 
258
    my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
 
259
 
 
260
    return keys %{ $CODES->[$codeset] };
 
261
}
 
262
 
 
263
sub all_country_names
 
264
{
 
265
    my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
 
266
 
 
267
    return values %{ $CODES->[$codeset] };
 
268
}
 
269
 
 
270
#-----------------------------------------------------------------------
 
271
 
 
272
=head1 CODE ALIASING
 
273
 
 
274
This module supports a semi-private routine for specifying two letter
 
275
code aliases.
 
276
 
 
277
    Locale::Country::_alias_code( ALIAS => CODE [, CODESET ] )
 
278
 
 
279
This feature was added as a mechanism for handling
 
280
a "uk" code. The ISO standard says that the two-letter code for
 
281
"United Kingdom" is "gb", whereas domain names are all .uk.
 
282
 
 
283
By default the module does not understand "uk", since it is implementing
 
284
an ISO standard. If you would like 'uk' to work as the two-letter
 
285
code for United Kingdom, use the following:
 
286
 
 
287
    use Locale::Country;
 
288
    
 
289
    Locale::Country::_alias_code('uk' => 'gb');
 
290
 
 
291
With this code, both "uk" and "gb" are valid codes for United Kingdom,
 
292
with the reverse lookup returning "uk" rather than the usual "gb".
 
293
 
 
294
=cut
 
295
 
 
296
#-----------------------------------------------------------------------
 
297
 
 
298
sub _alias_code
 
299
{
 
300
    my $alias = shift;
 
301
    my $real  = shift;
 
302
    my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
 
303
 
 
304
    my $country;
 
305
 
 
306
 
 
307
    if (not exists $CODES->[$codeset]->{$real})
 
308
    {
 
309
        carp "attempt to alias \"$alias\" to unknown country code \"$real\"\n";
 
310
        return undef;
 
311
    }
 
312
    $country = $CODES->[$codeset]->{$real};
 
313
    $CODES->[$codeset]->{$alias} = $country;
 
314
    $COUNTRIES->[$codeset]->{"\L$country"} = $alias;
 
315
 
 
316
    return $alias;
 
317
}
 
318
 
 
319
#-----------------------------------------------------------------------
 
320
 
 
321
=head1 EXAMPLES
 
322
 
 
323
The following example illustrates use of the C<code2country()> function.
 
324
The user is prompted for a country code, and then told the corresponding
 
325
country name:
 
326
 
 
327
    $| = 1;   # turn off buffering
 
328
    
 
329
    print "Enter country code: ";
 
330
    chop($code = <STDIN>);
 
331
    $country = code2country($code, LOCALE_CODE_ALPHA_2);
 
332
    if (defined $country)
 
333
    {
 
334
        print "$code = $country\n";
 
335
    }
 
336
    else
 
337
    {
 
338
        print "'$code' is not a valid country code!\n";
 
339
    }
 
340
 
 
341
=head1 DOMAIN NAMES
 
342
 
 
343
Most top-level domain names are based on these codes,
 
344
but there are certain codes which aren't.
 
345
If you are using this module to identify country from hostname,
 
346
your best bet is to preprocess the country code.
 
347
 
 
348
For example, B<edu>, B<com>, B<gov> and friends would map to B<us>;
 
349
B<uk> would map to B<gb>. Any others?
 
350
 
 
351
=head1 KNOWN BUGS AND LIMITATIONS
 
352
 
 
353
=over 4
 
354
 
 
355
=item *
 
356
 
 
357
When using C<country2code()>, the country name must currently appear
 
358
exactly as it does in the source of the module. For example,
 
359
 
 
360
    country2code('United States')
 
361
 
 
362
will return B<us>, as expected. But the following will all return C<undef>:
 
363
 
 
364
    country2code('United States of America')
 
365
    country2code('Great Britain')
 
366
    country2code('U.S.A.')
 
367
 
 
368
If there's need for it, a future version could have variants
 
369
for country names.
 
370
 
 
371
=item *
 
372
 
 
373
In the current implementation, all data is read in when the
 
374
module is loaded, and then held in memory.
 
375
A lazy implementation would be more memory friendly.
 
376
 
 
377
=back
 
378
 
 
379
=head1 SEE ALSO
 
380
 
 
381
=over 4
 
382
 
 
383
=item Locale::Language
 
384
 
 
385
ISO two letter codes for identification of language (ISO 639).
 
386
 
 
387
=item Locale::Currency
 
388
 
 
389
ISO three letter codes for identification of currencies
 
390
and funds (ISO 4217).
 
391
 
 
392
=item ISO 3166
 
393
 
 
394
The ISO standard which defines these codes.
 
395
 
 
396
=item http://www.din.de/gremien/nas/nabd/iso3166ma/
 
397
 
 
398
Official home page for ISO 3166
 
399
 
 
400
=item http://www.egt.ie/standards/iso3166/iso3166-1-en.html
 
401
 
 
402
Another useful, but not official, home page.
 
403
 
 
404
=item http://www.cia.gov/cia/publications/factbook/docs/app-f.html
 
405
 
 
406
An appendix in the CIA world fact book which lists country codes
 
407
as defined by ISO 3166, FIPS 10-4, and internet domain names.
 
408
 
 
409
=back
 
410
 
 
411
 
 
412
=head1 AUTHOR
 
413
 
 
414
Neil Bowers E<lt>neilb@cre.canon.co.ukE<gt>
 
415
 
 
416
=head1 COPYRIGHT
 
417
 
 
418
Copyright (c) 1997-2001 Canon Research Centre Europe (CRE).
 
419
 
 
420
This module is free software; you can redistribute it and/or
 
421
modify it under the same terms as Perl itself.
 
422
 
 
423
=cut
 
424
 
 
425
#-----------------------------------------------------------------------
 
426
 
 
427
#=======================================================================
 
428
# initialisation code - stuff the DATA into the ALPHA2 hash
 
429
#=======================================================================
 
430
{
 
431
    my ($alpha2, $alpha3, $numeric);
 
432
    my $country;
 
433
 
 
434
    open(DATA, "/usr/share/iso-codes/iso-codes-2.tab") || 
 
435
      die "iso-codes data file not present";
 
436
 
 
437
    while (<DATA>)
 
438
    {
 
439
        next unless /\S/;
 
440
        chop;
 
441
        ($alpha2, $alpha3, $numeric, $country) = split(/\t/, $_, 4);
 
442
 
 
443
        $CODES->[LOCALE_CODE_ALPHA_2]->{$alpha2} = $country;
 
444
        $COUNTRIES->[LOCALE_CODE_ALPHA_2]->{"\L$country"} = $alpha2;
 
445
 
 
446
        if ($alpha3)
 
447
        {
 
448
            $CODES->[LOCALE_CODE_ALPHA_3]->{$alpha3} = $country;
 
449
            $COUNTRIES->[LOCALE_CODE_ALPHA_3]->{"\L$country"} = $alpha3;
 
450
        }
 
451
 
 
452
        if ($numeric)
 
453
        {
 
454
            $CODES->[LOCALE_CODE_NUMERIC]->{$numeric} = $country;
 
455
            $COUNTRIES->[LOCALE_CODE_NUMERIC]->{"\L$country"} = $numeric;
 
456
        }
 
457
        close(DATA);
 
458
 
 
459
    }
 
460
}
 
461
 
 
462
1;
 
463