Re: lib/sort.t failure -- real PATCH enclosed
[p5sagit/p5-mst-13.2.git] / ext / Encode / Encode.pm
CommitLineData
2c674647 1package Encode;
51ef4e11 2use strict;
c731e18e 3our $VERSION = do { my @r = (q$Revision: 1.30 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };
5129552c 4our $DEBUG = 0;
2c674647 5
6require DynaLoader;
7require Exporter;
8
51ef4e11 9our @ISA = qw(Exporter DynaLoader);
2c674647 10
4411f3b6 11# Public, encouraged API is exported by default
51ef4e11 12our @EXPORT = qw (
4411f3b6 13 encode
14 decode
15 encode_utf8
16 decode_utf8
17 find_encoding
51ef4e11 18 encodings
4411f3b6 19);
20
51ef4e11 21our @EXPORT_OK =
2c674647 22 qw(
51ef4e11 23 define_encoding
2c674647 24 from_to
25 is_utf8
4411f3b6 26 is_8bit
27 is_16bit
a12c0f56 28 utf8_upgrade
29 utf8_downgrade
4411f3b6 30 _utf8_on
31 _utf8_off
2c674647 32 );
33
34bootstrap Encode ();
35
4411f3b6 36# Documentation moved after __END__ for speed - NI-S
2c674647 37
bf230f3d 38use Carp;
39
a63c962f 40our $ON_EBCDIC = (ord("A") == 193);
f2a2953c 41
5d030b67 42use Encode::Alias;
43
5129552c 44# Make a %Encoding package variable to allow a certain amount of cheating
45our %Encoding;
a999c27c 46our %ExtModule;
47
48my @codepages = qw(
49 37 424 437 500 737 775 850 852 855
50 856 857 860 861 862 863 864 865 866
51 869 874 875 932 936 949 950 1006 1026
52 1047 1250 1251 1252 1253 1254 1255 1256 1257
53 1258
54 );
55
56my @macintosh = qw(
57 CentralEurRoman Croatian Cyrillic Greek
58 Iceland Roman Rumanian Sami
59 Thai Turkish Ukrainian
60 );
d1ed7747 61
5129552c 62for my $k (2..11,13..16){
c731e18e 63 $ExtModule{"iso-8859-$k"} = 'Encode::Byte';
5129552c 64}
65
a999c27c 66for my $k (@codepages){
c731e18e 67 $ExtModule{"cp$k"} = 'Encode::Byte';
5129552c 68}
69
a999c27c 70for my $k (@macintosh)
71{
c731e18e 72 $ExtModule{"mac$k"} = 'Encode::Byte';
73}
74
75for my $k (qw(UCS-2BE UCS-2LE UTF-16 UTF-16BE UTF-16LE
76 UTF-32 UTF-32BE UTF-32LE)){
77 $ExtModule{$k} = 'Encode::Unicode';
a999c27c 78}
79
80%ExtModule =
81 (%ExtModule,
c731e18e 82 'koi8-r' => 'Encode::Byte',
83 'posix-bc' => 'Encode::EBCDIC',
84 cp37 => 'Encode::EBCDIC',
85 cp1026 => 'Encode::EBCDIC',
86 cp1047 => 'Encode::EBCDIC',
87 cp500 => 'Encode::EBCDIC',
88 cp875 => 'Encode::EBCDIC',
89 dingbats => 'Encode::Symbol',
90 macDingbats => 'Encode::Symbol',
91 macSymbol => 'Encode::Symbol',
92 symbol => 'Encode::Symbol',
93 viscii => 'Encode::Byte',
a999c27c 94);
95
a63c962f 96unless ($ON_EBCDIC) { # CJK added to autoload unless EBCDIC env
f2a2953c 97%ExtModule =
98 (%ExtModule,
a999c27c 99
c731e18e 100 'cp936' => 'Encode::CN',
101 'euc-cn' => 'Encode::CN',
102 'gb12345-raw' => 'Encode::CN',
103 'gb2312-raw' => 'Encode::CN',
104 'gbk' => 'Encode::CN',
105 'iso-ir-165' => 'Encode::CN',
106
107 '7bit-jis' => 'Encode::JP',
108 'cp932' => 'Encode::JP',
109 'euc-jp' => 'Encode::JP',
110 'iso-2022-jp' => 'Encode::JP',
111 'iso-2022-jp-1' => 'Encode::JP',
112 'jis0201-raw' => 'Encode::JP',
113 'jis0208-raw' => 'Encode::JP',
114 'jis0212-raw' => 'Encode::JP',
115 'macJapanese' => 'Encode::JP',
116 'shiftjis' => 'Encode::JP',
117
118 'cp949' => 'Encode::KR',
119 'euc-kr' => 'Encode::KR',
120 'ksc5601' => 'Encode::KR',
121 'macKorean' => 'Encode::KR',
122
123 'big5' => 'Encode::TW',
124 'big5-hkscs' => 'Encode::TW',
125 'cp950' => 'Encode::TW',
126
127 'big5plus' => 'Encode::HanExtra',
128 'euc-tw' => 'Encode::HanExtra',
129 'gb18030' => 'Encode::HanExtra',
f2a2953c 130 );
131}
5129552c 132
656753f8 133sub encodings
134{
5129552c 135 my $class = shift;
071db25d 136 my @modules = (@_ and $_[0] eq ":all") ? values %ExtModule : @_;
c731e18e 137 for my $mod (@modules){
138 $mod =~ s,::,/,g or $mod = "Encode/$mod";
139 $mod .= '.pm';
140 $DEBUG and warn "about to require $mod;";
141 eval { require $mod; };
5129552c 142 }
c731e18e 143 my %modules = map {$_ => 1} @modules;
5129552c 144 return
c731e18e 145 sort grep {!/^(?:Internal|Unicode)$/o} keys %Encoding;
51ef4e11 146}
147
51ef4e11 148sub define_encoding
149{
18586f54 150 my $obj = shift;
151 my $name = shift;
5129552c 152 $Encoding{$name} = $obj;
18586f54 153 my $lc = lc($name);
154 define_alias($lc => $obj) unless $lc eq $name;
155 while (@_)
156 {
157 my $alias = shift;
158 define_alias($alias,$obj);
159 }
160 return $obj;
656753f8 161}
162
656753f8 163sub getEncoding
164{
dd9703c9 165 my ($class,$name,$skip_external) = @_;
18586f54 166 my $enc;
167 if (ref($name) && $name->can('new_sequence'))
168 {
169 return $name;
170 }
171 my $lc = lc $name;
5129552c 172 if (exists $Encoding{$name})
18586f54 173 {
5129552c 174 return $Encoding{$name};
18586f54 175 }
5129552c 176 if (exists $Encoding{$lc})
18586f54 177 {
5129552c 178 return $Encoding{$lc};
18586f54 179 }
c50d192e 180
5129552c 181 my $oc = $class->find_alias($name);
c50d192e 182 return $oc if defined $oc;
183
5129552c 184 $oc = $class->find_alias($lc) if $lc ne $name;
c50d192e 185 return $oc if defined $oc;
186
c731e18e 187 unless ($skip_external)
d1ed7747 188 {
c731e18e 189 if (my $mod = $ExtModule{$name} || $ExtModule{$lc}){
190 $mod =~ s,::,/,g ; $mod .= '.pm';
191 eval{ require $mod; };
192 return $Encoding{$name} if exists $Encoding{$name};
193 }
d1ed7747 194 }
18586f54 195 return;
656753f8 196}
197
4411f3b6 198sub find_encoding
199{
dd9703c9 200 my ($name,$skip_external) = @_;
201 return __PACKAGE__->getEncoding($name,$skip_external);
4411f3b6 202}
203
204sub encode
205{
18586f54 206 my ($name,$string,$check) = @_;
207 my $enc = find_encoding($name);
208 croak("Unknown encoding '$name'") unless defined $enc;
209 my $octets = $enc->encode($string,$check);
210 return undef if ($check && length($string));
211 return $octets;
4411f3b6 212}
213
214sub decode
215{
18586f54 216 my ($name,$octets,$check) = @_;
217 my $enc = find_encoding($name);
218 croak("Unknown encoding '$name'") unless defined $enc;
219 my $string = $enc->decode($octets,$check);
220 $_[1] = $octets if $check;
221 return $string;
4411f3b6 222}
223
224sub from_to
225{
18586f54 226 my ($string,$from,$to,$check) = @_;
227 my $f = find_encoding($from);
228 croak("Unknown encoding '$from'") unless defined $f;
229 my $t = find_encoding($to);
230 croak("Unknown encoding '$to'") unless defined $t;
231 my $uni = $f->decode($string,$check);
232 return undef if ($check && length($string));
a999c27c 233 $string = $t->encode($uni,$check);
18586f54 234 return undef if ($check && length($uni));
3ef515df 235 return defined($_[0] = $string) ? length($string) : undef ;
4411f3b6 236}
237
238sub encode_utf8
239{
18586f54 240 my ($str) = @_;
c731e18e 241 utf8::encode($str);
18586f54 242 return $str;
4411f3b6 243}
244
245sub decode_utf8
246{
18586f54 247 my ($str) = @_;
248 return undef unless utf8::decode($str);
249 return $str;
5ad8ef52 250}
251
f2a2953c 252predefine_encodings();
253
254#
255# This is to restore %Encoding if really needed;
256#
257sub predefine_encodings{
258 if ($ON_EBCDIC) {
259 # was in Encode::UTF_EBCDIC
260 package Encode::UTF_EBCDIC;
261 *name = sub{ shift->{'Name'} };
262 *new_sequence = sub{ return $_[0] };
263 *decode = sub{
264 my ($obj,$str,$chk) = @_;
265 my $res = '';
266 for (my $i = 0; $i < length($str); $i++) {
267 $res .=
268 chr(utf8::unicode_to_native(ord(substr($str,$i,1))));
269 }
270 $_[1] = '' if $chk;
271 return $res;
272 };
273 *encode = sub{
274 my ($obj,$str,$chk) = @_;
275 my $res = '';
276 for (my $i = 0; $i < length($str); $i++) {
277 $res .=
278 chr(utf8::native_to_unicode(ord(substr($str,$i,1))));
279 }
280 $_[1] = '' if $chk;
281 return $res;
282 };
c731e18e 283 $Encode::Encoding{Internal} =
284 bless {Name => "UTF_EBCDIC"} => "Encode::UTF_EBCDIC";
f2a2953c 285 } else {
286 # was in Encode::UTF_EBCDIC
287 package Encode::Internal;
288 *name = sub{ shift->{'Name'} };
289 *new_sequence = sub{ return $_[0] };
290 *decode = sub{
291 my ($obj,$str,$chk) = @_;
292 utf8::upgrade($str);
293 $_[1] = '' if $chk;
294 return $str;
295 };
296 *encode = \&decode;
297 $Encode::Encoding{Unicode} =
c731e18e 298 bless {Name => "Internal"} => "Encode::Internal";
f2a2953c 299 }
300
301 {
302 # was in Encode::utf8
303 package Encode::utf8;
304 *name = sub{ shift->{'Name'} };
305 *new_sequence = sub{ return $_[0] };
306 *decode = sub{
307 my ($obj,$octets,$chk) = @_;
308 my $str = Encode::decode_utf8($octets);
309 if (defined $str) {
310 $_[1] = '' if $chk;
311 return $str;
312 }
313 return undef;
314 };
315 *encode = sub {
316 my ($obj,$string,$chk) = @_;
317 my $octets = Encode::encode_utf8($string);
318 $_[1] = '' if $chk;
319 return $octets;
320 };
321 $Encode::Encoding{utf8} =
c731e18e 322 bless {Name => "utf8"} => "Encode::utf8";
f2a2953c 323 }
324 # do externals if necessary
325 require File::Basename;
326 require File::Spec;
c731e18e 327 for my $ext (qw()){
f2a2953c 328 my $pm =
329 File::Spec->catfile(File::Basename::dirname($INC{'Encode.pm'}),
330 "Encode", "$ext.pm");
331 do $pm;
332 }
333}
334
18586f54 335require Encode::Encoding;
336require Encode::XS;
4411f3b6 337
656753f8 3381;
339
2a936312 340__END__
341
4411f3b6 342=head1 NAME
343
344Encode - character encodings
345
346=head1 SYNOPSIS
347
348 use Encode;
349
67d7b5ef 350
351=head2 Table of Contents
352
353Encode consists of a collection of modules which details are too big
354to fit in one document. This POD itself explains the top-level APIs
355and general topics at a glance. For other topics and more details,
356see the PODs below;
357
358 Name Description
359 --------------------------------------------------------
360 Encode::Alias Alias defintions to encodings
361 Encode::Encoding Encode Implementation Base Class
362 Encode::Supported List of Supported Encodings
363 Encode::CN Simplified Chinese Encodings
364 Encode::JP Japanese Encodings
365 Encode::KR Korean Encodings
366 Encode::TW Traditional Chinese Encodings
367 --------------------------------------------------------
368
4411f3b6 369=head1 DESCRIPTION
370
47bfe92f 371The C<Encode> module provides the interfaces between Perl's strings
67d7b5ef 372and the rest of the system. Perl strings are sequences of
373B<characters>.
374
375The repertoire of characters that Perl can represent is at least that
376defined by the Unicode Consortium. On most platforms the ordinal
377values of the characters (as returned by C<ord(ch)>) is the "Unicode
378codepoint" for the character (the exceptions are those platforms where
379the legacy encoding is some variant of EBCDIC rather than a super-set
380of ASCII - see L<perlebcdic>).
381
382Traditionally computer data has been moved around in 8-bit chunks
383often called "bytes". These chunks are also known as "octets" in
384networking standards. Perl is widely used to manipulate data of many
385types - not only strings of characters representing human or computer
386languages but also "binary" data being the machines representation of
387numbers, pixels in an image - or just about anything.
388
389When Perl is processing "binary data" the programmer wants Perl to
390process "sequences of bytes". This is not a problem for Perl - as a
391byte has 256 possible values it easily fits in Perl's much larger
392"logical character".
393
394=head2 TERMINOLOGY
4411f3b6 395
67d7b5ef 396=over 4
21938dfa 397
67d7b5ef 398=item *
399
400I<character>: a character in the range 0..(2**32-1) (or more).
401(What Perl's strings are made of.)
402
403=item *
404
405I<byte>: a character in the range 0..255
406(A special case of a Perl character.)
407
408=item *
409
410I<octet>: 8 bits of data, with ordinal values 0..255
411(Term for bytes passed to or from a non-Perl context, e.g. disk file.)
412
413=back
4411f3b6 414
67d7b5ef 415The marker [INTERNAL] marks Internal Implementation Details, in
416general meant only for those who think they know what they are doing,
417and such details may change in future releases.
418
419=head1 PERL ENCODING API
4411f3b6 420
421=over 4
422
f2a2953c 423=item $octets = encode(ENCODING, $string[, CHECK])
4411f3b6 424
47bfe92f 425Encodes string from Perl's internal form into I<ENCODING> and returns
67d7b5ef 426a sequence of octets. ENCODING can be either a canonical name or
427alias. For encoding names and aliases, see L</"Defining Aliases">.
428For CHECK see L</"Handling Malformed Data">.
4411f3b6 429
67d7b5ef 430For example to convert (internally UTF-8 encoded) Unicode string to
431iso-8859-1 (also known as Latin1),
681a7c68 432
67d7b5ef 433 $octets = encode("iso-8859-1", $unicode);
681a7c68 434
f2a2953c 435=item $string = decode(ENCODING, $octets[, CHECK])
4411f3b6 436
47bfe92f 437Decode sequence of octets assumed to be in I<ENCODING> into Perl's
67d7b5ef 438internal form and returns the resulting string. as in encode(),
439ENCODING can be either a canonical name or alias. For encoding names
440and aliases, see L</"Defining Aliases">. For CHECK see
47bfe92f 441L</"Handling Malformed Data">.
442
1b2c56c8 443For example to convert ISO-8859-1 data to UTF-8:
681a7c68 444
67d7b5ef 445 $utf8 = decode("iso-8859-1", $latin1);
681a7c68 446
f2a2953c 447=item [$length =] from_to($string, FROM_ENCODING, TO_ENCODING [,CHECK])
47bfe92f 448
2b106fbe 449Convert B<in-place> the data between two encodings. How did the data
450in $string originally get to be in FROM_ENCODING? Either using
67d7b5ef 451encode() or through PerlIO: See L</"Encoding and IO">.
452For encoding names and aliases, see L</"Defining Aliases">.
453For CHECK see L</"Handling Malformed Data">.
2b106fbe 454
1b2c56c8 455For example to convert ISO-8859-1 data to UTF-8:
2b106fbe 456
457 from_to($data, "iso-8859-1", "utf-8");
458
459and to convert it back:
460
461 from_to($data, "utf-8", "iso-8859-1");
4411f3b6 462
ab97ca19 463Note that because the conversion happens in place, the data to be
464converted cannot be a string constant, it must be a scalar variable.
465
3ef515df 466from_to() return the length of the converted string on success, undef
467otherwise.
468
4411f3b6 469=back
470
f2a2953c 471=head2 UTF-8 / utf8
472
473The Unicode consortium defines the UTF-8 standard as a way of encoding
474the entire Unicode repertoire as sequences of octets. This encoding is
475expected to become very widespread. Perl can use this form internally
476to represent strings, so conversions to and from this form are
477particularly efficient (as octets in memory do not have to change,
478just the meta-data that tells Perl how to treat them).
479
480=over 4
481
482=item $octets = encode_utf8($string);
483
484The characters that comprise string are encoded in Perl's superset of UTF-8
485and the resulting octets returned as a sequence of bytes. All possible
486characters have a UTF-8 representation so this function cannot fail.
487
488=item $string = decode_utf8($octets [, CHECK]);
489
490The sequence of octets represented by $octets is decoded from UTF-8
491into a sequence of logical characters. Not all sequences of octets
492form valid UTF-8 encodings, so it is possible for this call to fail.
493For CHECK see L</"Handling Malformed Data">.
494
495=back
496
51ef4e11 497=head2 Listing available encodings
498
5129552c 499 use Encode;
500 @list = Encode->encodings();
501
502Returns a list of the canonical names of the available encodings that
503are loaded. To get a list of all available encodings including the
504ones that are not loaded yet, say
505
506 @all_encodings = Encode->encodings(":all");
507
508Or you can give the name of specific module.
509
c731e18e 510 @with_jp = Encode->encodings("Encode::JP");
511
512When "::" is not in the name, "Encode::" is assumed.
51ef4e11 513
c731e18e 514 @ebcdic = Encode->encodings("EBCDIC");
5d030b67 515
a63c962f 516To find which encodings are supported by this package in details,
5d030b67 517see L<Encode::Supported>.
51ef4e11 518
519=head2 Defining Aliases
520
67d7b5ef 521To add new alias to a given encoding, Use;
522
5129552c 523 use Encode;
524 use Encode::Alias;
a63c962f 525 define_alias(newName => ENCODING);
51ef4e11 526
3ef515df 527After that, newName can be used as an alias for ENCODING.
f2a2953c 528ENCODING may be either the name of an encoding or an
529I<encoding object>
51ef4e11 530
5d030b67 531See L<Encode::Alias> on details.
51ef4e11 532
4411f3b6 533=head1 Encoding and IO
534
535It is very common to want to do encoding transformations when
536reading or writing files, network connections, pipes etc.
47bfe92f 537If Perl is configured to use the new 'perlio' IO system then
4411f3b6 538C<Encode> provides a "layer" (See L<perliol>) which can transform
539data as it is read or written.
540
8e86646e 541Here is how the blind poet would modernise the encoding:
542
42234700 543 use Encode;
8e86646e 544 open(my $iliad,'<:encoding(iso-8859-7)','iliad.greek');
545 open(my $utf8,'>:utf8','iliad.utf8');
546 my @epic = <$iliad>;
547 print $utf8 @epic;
548 close($utf8);
549 close($illiad);
4411f3b6 550
551In addition the new IO system can also be configured to read/write
552UTF-8 encoded characters (as noted above this is efficient):
553
e9692b5b 554 open(my $fh,'>:utf8','anything');
555 print $fh "Any \x{0021} string \N{SMILEY FACE}\n";
4411f3b6 556
557Either of the above forms of "layer" specifications can be made the default
558for a lexical scope with the C<use open ...> pragma. See L<open>.
559
560Once a handle is open is layers can be altered using C<binmode>.
561
47bfe92f 562Without any such configuration, or if Perl itself is built using
4411f3b6 563system's own IO, then write operations assume that file handle accepts
564only I<bytes> and will C<die> if a character larger than 255 is
565written to the handle. When reading, each octet from the handle
566becomes a byte-in-a-character. Note that this default is the same
47bfe92f 567behaviour as bytes-only languages (including Perl before v5.6) would
568have, and is sufficient to handle native 8-bit encodings
569e.g. iso-8859-1, EBCDIC etc. and any legacy mechanisms for handling
570other encodings and binary data.
571
572In other cases it is the programs responsibility to transform
573characters into bytes using the API above before doing writes, and to
574transform the bytes read from a handle into characters before doing
575"character operations" (e.g. C<lc>, C</\W+/>, ...).
576
47bfe92f 577You can also use PerlIO to convert larger amounts of data you don't
1b2c56c8 578want to bring into memory. For example to convert between ISO-8859-1
47bfe92f 579(Latin 1) and UTF-8 (or UTF-EBCDIC in EBCDIC machines):
580
e9692b5b 581 open(F, "<:encoding(iso-8859-1)", "data.txt") or die $!;
582 open(G, ">:utf8", "data.utf") or die $!;
583 while (<F>) { print G }
584
585 # Could also do "print G <F>" but that would pull
586 # the whole file into memory just to write it out again.
587
588More examples:
47bfe92f 589
e9692b5b 590 open(my $f, "<:encoding(cp1252)")
591 open(my $g, ">:encoding(iso-8859-2)")
592 open(my $h, ">:encoding(latin9)") # iso-8859-15
47bfe92f 593
594See L<PerlIO> for more information.
4411f3b6 595
1768d7eb 596See also L<encoding> for how to change the default encoding of the
d521382b 597data in your script.
1768d7eb 598
67d7b5ef 599=head1 Handling Malformed Data
600
f2a2953c 601If I<CHECK> is not set, (en|de)code will put I<substitution character> in
602place of the malformed character. for UCM-based encodings,
603E<lt>subcharE<gt> will be used. For Unicode, \xFFFD is used. If the
604data is supposed to be UTF-8, an optional lexical warning (category
605utf8) is given.
67d7b5ef 606
f2a2953c 607If I<CHECK> is true but not a code reference, dies with an error message.
67d7b5ef 608
f2a2953c 609In future you will be able to use a code reference to a callback
610function for the value of I<CHECK> but its API is still undecided.
67d7b5ef 611
612=head1 Defining Encodings
613
614To define a new encoding, use:
615
616 use Encode qw(define_alias);
617 define_encoding($object, 'canonicalName' [, alias...]);
618
619I<canonicalName> will be associated with I<$object>. The object
620should provide the interface described in L<Encode::Encoding>
621If more than two arguments are provided then additional
622arguments are taken as aliases for I<$object> as for C<define_alias>.
623
f2a2953c 624See L<Encode::Encoding> for more details.
625
4411f3b6 626=head1 Messing with Perl's Internals
627
47bfe92f 628The following API uses parts of Perl's internals in the current
629implementation. As such they are efficient, but may change.
4411f3b6 630
631=over 4
632
a63c962f 633=item is_utf8(STRING [, CHECK])
4411f3b6 634
635[INTERNAL] Test whether the UTF-8 flag is turned on in the STRING.
47bfe92f 636If CHECK is true, also checks the data in STRING for being well-formed
637UTF-8. Returns true if successful, false otherwise.
4411f3b6 638
a63c962f 639=item _utf8_on(STRING)
4411f3b6 640
641[INTERNAL] Turn on the UTF-8 flag in STRING. The data in STRING is
642B<not> checked for being well-formed UTF-8. Do not use unless you
643B<know> that the STRING is well-formed UTF-8. Returns the previous
644state of the UTF-8 flag (so please don't test the return value as
645I<not> success or failure), or C<undef> if STRING is not a string.
646
a63c962f 647=item _utf8_off(STRING)
4411f3b6 648
649[INTERNAL] Turn off the UTF-8 flag in STRING. Do not use frivolously.
650Returns the previous state of the UTF-8 flag (so please don't test the
651return value as I<not> success or failure), or C<undef> if STRING is
652not a string.
653
654=back
655
656=head1 SEE ALSO
657
5d030b67 658L<Encode::Encoding>,
659L<Encode::Supported>,
660L<PerlIO>,
661L<encoding>,
662L<perlebcdic>,
663L<perlfunc/open>,
664L<perlunicode>,
665L<utf8>,
666the Perl Unicode Mailing List E<lt>perl-unicode@perl.orgE<gt>
4411f3b6 667
668=cut