Update Module::Build to 0.3603
[p5sagit/p5-mst-13.2.git] / cpan / Module-Build / lib / Module / Build / Compat.pm
CommitLineData
bb4e9162 1package Module::Build::Compat;
2
3use strict;
4use vars qw($VERSION);
7dc9e1b4 5$VERSION = '0.3603';
bb4e9162 6
23837600 7use File::Basename ();
bb4e9162 8use File::Spec;
9use IO::File;
10use Config;
11use Module::Build;
12use Module::Build::ModuleInfo;
7dc9e1b4 13use Module::Build::Version;
bb4e9162 14use Data::Dumper;
15
738349a8 16my %convert_installdirs = (
17 PERL => 'core',
18 SITE => 'site',
19 VENDOR => 'vendor',
20);
21
53fc1c7e 22my %makefile_to_build =
bb4e9162 23 (
24 TEST_VERBOSE => 'verbose',
25 VERBINST => 'verbose',
738349a8 26 INC => sub { map {(extra_compiler_flags => $_)} Module::Build->split_like_shell(shift) },
27 POLLUTE => sub { (extra_compiler_flags => '-DPERL_POLLUTE') },
28 INSTALLDIRS => sub { (installdirs => $convert_installdirs{uc shift()}) },
29 LIB => sub {
30 my $lib = shift;
31 my %config = (
32 installprivlib => $lib,
33 installsitelib => $lib,
34 installarchlib => "$lib/$Config{archname}",
35 installsitearch => "$lib/$Config{archname}"
36 );
37 return map { (config => "$_=$config{$_}") } keys %config;
38 },
39
40 # Convert INSTALLVENDORLIB and friends.
41 (
42 map {
23837600 43 my $name = $_;
738349a8 44 $name => sub {
23837600 45 my @ret = (config => lc($name) . "=" . shift );
738349a8 46 print STDERR "# Converted to @ret\n";
47
48 return @ret;
49 }
23837600 50 } qw(
51 INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH
52 INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB
53 INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN
54 INSTALLSCRIPT INSTALLSITESCRIPT INSTALLVENDORSCRIPT
55 INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDORMAN1DIR
56 INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDORMAN3DIR
57 )
738349a8 58 ),
bb4e9162 59
60 # Some names they have in common
61 map {$_, lc($_)} qw(DESTDIR PREFIX INSTALL_BASE UNINST),
62 );
63
738349a8 64my %macro_to_build = %makefile_to_build;
65# "LIB=foo make" is not the same as "perl Makefile.PL LIB=foo"
66delete $macro_to_build{LIB};
bb4e9162 67
613f422f 68sub _simple_prereq {
69 return $_[0] =~ /^[0-9_]+\.?[0-9_]*$/; # crudly, a decimal literal
70}
71
72sub _merge_prereq {
73 my ($req, $breq) = @_;
74 $req ||= {};
75 $breq ||= {};
76
77 # validate formats
78 for my $p ( $req, $breq ) {
79 for my $k (keys %$p) {
7dc9e1b4 80 next if $k eq 'perl';
613f422f 81 die "Prereq '$p->{$k}' for '$k' is not supported by Module::Build::Compat\n"
82 unless _simple_prereq($p->{$k});
83 }
84 }
85 # merge
86 my $merge = { %$req };
87 for my $k ( keys %$breq ) {
88 my $v1 = $merge->{$k} || 0;
89 my $v2 = $breq->{$k};
90 $merge->{$k} = $v1 > $v2 ? $v1 : $v2;
91 }
92 return %$merge;
93}
53fc1c7e 94
95
bb4e9162 96sub create_makefile_pl {
97 my ($package, $type, $build, %args) = @_;
53fc1c7e 98
bb4e9162 99 die "Don't know how to build Makefile.PL of type '$type'"
100 unless $type =~ /^(small|passthrough|traditional)$/;
101
613f422f 102 if ($type eq 'passthrough') {
103 $build->log_warn(<<"HERE");
53fc1c7e 104
105IMPORTANT NOTE: The '$type' style of Makefile.PL is deprecated and
613f422f 106may be removed in a future version of Module::Build in favor of the
107'configure_requires' property. See Module::Build::Compat
108documentation for details.
109
110HERE
111 }
112
bb4e9162 113 my $fh;
114 if ($args{fh}) {
115 $fh = $args{fh};
116 } else {
117 $args{file} ||= 'Makefile.PL';
738349a8 118 local $build->{properties}{quiet} = 1;
119 $build->delete_filetree($args{file});
bb4e9162 120 $fh = IO::File->new("> $args{file}") or die "Can't write $args{file}: $!";
121 }
122
123 print {$fh} "# Note: this file was auto-generated by ", __PACKAGE__, " version $VERSION\n";
124
53fc1c7e 125 # Minimum perl version should be specified as "require 5.XXXXXX" in
7a827510 126 # Makefile.PL
127 my $requires = $build->requires;
128 if ( my $minimum_perl = $requires->{perl} ) {
7dc9e1b4 129 my $min_ver = Module::Build::Version->new($minimum_perl)->numify;
130 print {$fh} "require $min_ver;\n";
7a827510 131 }
132
dc8021d3 133 # If a *bundled* custom subclass is being used, make sure we add its
738349a8 134 # directory to @INC. Also, lib.pm always needs paths in Unix format.
bb4e9162 135 my $subclass_load = '';
136 if (ref($build) ne "Module::Build") {
137 my $subclass_dir = $package->subclass_dir($build);
dc8021d3 138
bb4e9162 139 if (File::Spec->file_name_is_absolute($subclass_dir)) {
140 my $base_dir = $build->base_dir;
141
142 if ($build->dir_contains($base_dir, $subclass_dir)) {
143 $subclass_dir = File::Spec->abs2rel($subclass_dir, $base_dir);
738349a8 144 $subclass_dir = $package->unixify_dir($subclass_dir);
dc8021d3 145 $subclass_load = "use lib '$subclass_dir';";
bb4e9162 146 }
738349a8 147 # Otherwise, leave it the empty string
dc8021d3 148
149 } else {
738349a8 150 $subclass_dir = $package->unixify_dir($subclass_dir);
dc8021d3 151 $subclass_load = "use lib '$subclass_dir';";
bb4e9162 152 }
bb4e9162 153 }
dc8021d3 154
bb4e9162 155 if ($type eq 'small') {
156 printf {$fh} <<'EOF', $subclass_load, ref($build), ref($build);
157 use Module::Build::Compat 0.02;
158 %s
159 Module::Build::Compat->run_build_pl(args => \@ARGV);
160 require %s;
161 Module::Build::Compat->write_makefile(build_class => '%s');
162EOF
163
164 } elsif ($type eq 'passthrough') {
165 printf {$fh} <<'EOF', $subclass_load, ref($build), ref($build);
53fc1c7e 166
bb4e9162 167 unless (eval "use Module::Build::Compat 0.02; 1" ) {
168 print "This module requires Module::Build to install itself.\n";
53fc1c7e 169
bb4e9162 170 require ExtUtils::MakeMaker;
171 my $yn = ExtUtils::MakeMaker::prompt
172 (' Install Module::Build now from CPAN?', 'y');
53fc1c7e 173
bb4e9162 174 unless ($yn =~ /^y/i) {
175 die " *** Cannot install without Module::Build. Exiting ...\n";
176 }
53fc1c7e 177
bb4e9162 178 require Cwd;
179 require File::Spec;
180 require CPAN;
53fc1c7e 181
bb4e9162 182 # Save this 'cause CPAN will chdir all over the place.
183 my $cwd = Cwd::cwd();
53fc1c7e 184
bb4e9162 185 CPAN::Shell->install('Module::Build::Compat');
47f13fd5 186 CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
187 or die "Couldn't install Module::Build, giving up.\n";
53fc1c7e 188
bb4e9162 189 chdir $cwd or die "Cannot chdir() back to $cwd: $!";
190 }
191 eval "use Module::Build::Compat 0.02; 1" or die $@;
192 %s
193 Module::Build::Compat->run_build_pl(args => \@ARGV);
53fc1c7e 194 my $build_script = 'Build';
94410036 195 $build_script .= '.com' if $^O eq 'VMS';
196 exit(0) unless(-e $build_script); # cpantesters convention
bb4e9162 197 require %s;
198 Module::Build::Compat->write_makefile(build_class => '%s');
199EOF
53fc1c7e 200
bb4e9162 201 } elsif ($type eq 'traditional') {
202
203 my (%MM_Args, %prereq);
204 if (eval "use Tie::IxHash; 1") {
205 tie %MM_Args, 'Tie::IxHash'; # Don't care if it fails here
206 tie %prereq, 'Tie::IxHash'; # Don't care if it fails here
207 }
53fc1c7e 208
bb4e9162 209 my %name = ($build->module_name
210 ? (NAME => $build->module_name)
211 : (DISTNAME => $build->dist_name));
53fc1c7e 212
bb4e9162 213 my %version = ($build->dist_version_from
214 ? (VERSION_FROM => $build->dist_version_from)
215 : (VERSION => $build->dist_version)
216 );
217 %MM_Args = (%name, %version);
53fc1c7e 218
613f422f 219 %prereq = _merge_prereq( $build->requires, $build->build_requires );
bb4e9162 220 %prereq = map {$_, $prereq{$_}} sort keys %prereq;
53fc1c7e 221
23837600 222 delete $prereq{perl};
bb4e9162 223 $MM_Args{PREREQ_PM} = \%prereq;
53fc1c7e 224
bb4e9162 225 $MM_Args{INSTALLDIRS} = $build->installdirs eq 'core' ? 'perl' : $build->installdirs;
53fc1c7e 226
bb4e9162 227 $MM_Args{EXE_FILES} = [ sort keys %{$build->script_files} ] if $build->script_files;
53fc1c7e 228
94410036 229 $MM_Args{PL_FILES} = $build->PL_files || {};
23837600 230
231 if ($build->recursive_test_files) {
613f422f 232 $MM_Args{test} = { TESTS => join q{ }, $package->_test_globs($build) };
23837600 233 }
234
bb4e9162 235 local $Data::Dumper::Terse = 1;
236 my $args = Data::Dumper::Dumper(\%MM_Args);
237 $args =~ s/\{(.*)\}/($1)/s;
53fc1c7e 238
bb4e9162 239 print $fh <<"EOF";
240use ExtUtils::MakeMaker;
241WriteMakefile
242$args;
243EOF
244 }
245}
246
23837600 247sub _test_globs {
248 my ($self, $build) = @_;
249
250 return map { File::Spec->catfile($_, '*.t') }
251 @{$build->rscan_dir('t', sub { -d $File::Find::name })};
252}
bb4e9162 253
254sub subclass_dir {
255 my ($self, $build) = @_;
53fc1c7e 256
bb4e9162 257 return (Module::Build::ModuleInfo->find_module_dir_by_name(ref $build)
258 || File::Spec->catdir($build->config_dir, 'lib'));
259}
260
738349a8 261sub unixify_dir {
262 my ($self, $path) = @_;
263 return join '/', File::Spec->splitdir($path);
264}
265
bb4e9162 266sub makefile_to_build_args {
738349a8 267 my $class = shift;
bb4e9162 268 my @out;
269 foreach my $arg (@_) {
270 next if $arg eq '';
53fc1c7e 271
bb4e9162 272 my ($key, $val) = ($arg =~ /^(\w+)=(.+)/ ? ($1, $2) :
273 die "Malformed argument '$arg'");
274
275 # Do tilde-expansion if it looks like a tilde prefixed path
738349a8 276 ( $val ) = Module::Build->_detildefy( $val ) if $val =~ /^~/;
bb4e9162 277
278 if (exists $makefile_to_build{$key}) {
279 my $trans = $makefile_to_build{$key};
738349a8 280 push @out, $class->_argvify( ref($trans) ? $trans->($val) : ($trans => $val) );
bb4e9162 281 } elsif (exists $Config{lc($key)}) {
738349a8 282 push @out, $class->_argvify( config => lc($key) . "=$val" );
bb4e9162 283 } else {
284 # Assume M::B can handle it in lowercase form
738349a8 285 push @out, $class->_argvify("\L$key" => $val);
bb4e9162 286 }
287 }
288 return @out;
289}
290
738349a8 291sub _argvify {
292 my ($self, @pairs) = @_;
293 my @out;
294 while (@pairs) {
295 my ($k, $v) = splice @pairs, 0, 2;
296 push @out, ("--$k", $v);
297 }
298 return @out;
299}
300
bb4e9162 301sub makefile_to_build_macros {
302 my @out;
23837600 303 my %config; # must accumulate and return as a hashref
738349a8 304 while (my ($macro, $trans) = each %macro_to_build) {
bb4e9162 305 # On some platforms (e.g. Cygwin with 'make'), the mere presence
306 # of "EXPORT: FOO" in the Makefile will make $ENV{FOO} defined.
307 # Therefore we check length() too.
308 next unless exists $ENV{$macro} && length $ENV{$macro};
309 my $val = $ENV{$macro};
23837600 310 my @args = ref($trans) ? $trans->($val) : ($trans => $val);
311 while (@args) {
312 my ($k, $v) = splice(@args, 0, 2);
313 if ( $k eq 'config' ) {
314 if ( $v =~ /^([^=]+)=(.*)$/ ) {
315 $config{$1} = $2;
316 }
317 else {
318 warn "Couldn't parse config '$v'\n";
319 }
320 }
321 else {
322 push @out, ($k => $v);
323 }
324 }
bb4e9162 325 }
53fc1c7e 326 push @out, (config => \%config) if %config;
bb4e9162 327 return @out;
328}
329
330sub run_build_pl {
331 my ($pack, %in) = @_;
332 $in{script} ||= 'Build.PL';
333 my @args = $in{args} ? $pack->makefile_to_build_args(@{$in{args}}) : ();
334 print "# running $in{script} @args\n";
335 Module::Build->run_perl_script($in{script}, [], \@args) or die "Couldn't run $in{script}: $!";
336}
337
338sub fake_makefile {
339 my ($self, %args) = @_;
340 unless (exists $args{build_class}) {
341 warn "Unknown 'build_class', defaulting to 'Module::Build'\n";
342 $args{build_class} = 'Module::Build';
343 }
c1d8f74e 344 my $class = $args{build_class};
bb4e9162 345
c1d8f74e 346 my $perl = $class->find_perl_interpreter;
738349a8 347
348 # VMS MMS/MMK need to use MCR to run the Perl image.
349 $perl = 'MCR ' . $perl if $self->_is_vms_mms;
350
c1d8f74e 351 my $noop = ($class->is_windowsish ? 'rem>nul' :
738349a8 352 $self->_is_vms_mms ? 'Continue' :
bb4e9162 353 'true');
bb4e9162 354
738349a8 355 my $filetype = $class->is_vmsish ? '.COM' : '';
356
357 my $Build = 'Build' . $filetype . ' --makefile_env_macros 1';
358 my $unlink = $class->oneliner('1 while unlink $ARGV[0]', [], [$args{makefile}]);
86bddcbf 359 $unlink =~ s/\$/\$\$/g unless $class->is_vmsish;
738349a8 360
cdbde1c3 361 my $maketext = ($^O eq 'os2' ? "SHELL = sh\n\n" : '');
362
363 $maketext .= <<"EOF";
bb4e9162 364all : force_do_it
365 $perl $Build
366realclean : force_do_it
367 $perl $Build realclean
738349a8 368 $unlink
94410036 369distclean : force_do_it
370 $perl $Build distclean
371 $unlink
372
bb4e9162 373
374force_do_it :
375 @ $noop
376EOF
377
c1d8f74e 378 foreach my $action ($class->known_actions) {
94410036 379 next if $action =~ /^(all|distclean|realclean|force_do_it)$/; # Don't double-define
bb4e9162 380 $maketext .= <<"EOF";
381$action : force_do_it
382 $perl $Build $action
383EOF
384 }
53fc1c7e 385
738349a8 386 if ($self->_is_vms_mms) {
387 # Roll our own .EXPORT as MMS/MMK don't honor that directive.
53fc1c7e 388 $maketext .= "\n.FIRST\n\t\@ $noop\n";
738349a8 389 for my $macro (keys %macro_to_build) {
390 $maketext .= ".IFDEF $macro\n\tDEFINE $macro \"\$($macro)\"\n.ENDIF\n";
391 }
53fc1c7e 392 $maketext .= "\n";
738349a8 393 }
394 else {
395 $maketext .= "\n.EXPORT : " . join(' ', keys %macro_to_build) . "\n\n";
396 }
53fc1c7e 397
bb4e9162 398 return $maketext;
399}
400
401sub fake_prereqs {
402 my $file = File::Spec->catfile('_build', 'prereqs');
403 my $fh = IO::File->new("< $file") or die "Can't read $file: $!";
404 my $prereqs = eval do {local $/; <$fh>};
405 close $fh;
613f422f 406
407 my %merged = _merge_prereq( $prereqs->{requires}, $prereqs->{build_requires} );
bb4e9162 408 my @prereq;
613f422f 409 foreach (sort keys %merged) {
410 next if $_ eq 'perl';
411 push @prereq, "$_=>q[$merged{$_}]";
bb4e9162 412 }
bb4e9162 413 return unless @prereq;
414 return "# PREREQ_PM => { " . join(", ", @prereq) . " }\n\n";
415}
416
417
418sub write_makefile {
419 my ($pack, %in) = @_;
738349a8 420
421 unless (exists $in{build_class}) {
422 warn "Unknown 'build_class', defaulting to 'Module::Build'\n";
423 $in{build_class} = 'Module::Build';
424 }
425 my $class = $in{build_class};
426 $in{makefile} ||= $pack->_is_vms_mms ? 'Descrip.MMS' : 'Makefile';
427
bb4e9162 428 open MAKE, "> $in{makefile}" or die "Cannot write $in{makefile}: $!";
429 print MAKE $pack->fake_prereqs;
430 print MAKE $pack->fake_makefile(%in);
431 close MAKE;
432}
433
738349a8 434sub _is_vms_mms {
435 return Module::Build->is_vmsish && ($Config{make} =~ m/MM[SK]/i);
436}
437
bb4e9162 4381;
439__END__
440
23837600 441=for :stopwords passthrough
bb4e9162 442
443=head1 NAME
444
445Module::Build::Compat - Compatibility with ExtUtils::MakeMaker
446
447
448=head1 SYNOPSIS
449
450 # In a Build.PL :
451 use Module::Build;
452 my $build = Module::Build->new
453 ( module_name => 'Foo::Bar',
454 license => 'perl',
613f422f 455 create_makefile_pl => 'traditional' );
bb4e9162 456 ...
457
458
459=head1 DESCRIPTION
460
23837600 461Because C<ExtUtils::MakeMaker> has been the standard way to distribute
bb4e9162 462modules for a long time, many tools (CPAN.pm, or your system
23837600 463administrator) may expect to find a working F<Makefile.PL> in every
bb4e9162 464distribution they download from CPAN. If you want to throw them a
23837600 465bone, you can use C<Module::Build::Compat> to automatically generate a
466F<Makefile.PL> for you, in one of several different styles.
bb4e9162 467
23837600 468C<Module::Build::Compat> also provides some code that helps out the
469F<Makefile.PL> at runtime.
bb4e9162 470
471
472=head1 METHODS
473
474=over 4
475
476=item create_makefile_pl($style, $build)
477
23837600 478Creates a F<Makefile.PL> in the current directory in one of several
479styles, based on the supplied C<Module::Build> object C<$build>. This is
bb4e9162 480typically controlled by passing the desired style as the
23837600 481C<create_makefile_pl> parameter to C<Module::Build>'s C<new()> method;
482the F<Makefile.PL> will then be automatically created during the
bb4e9162 483C<distdir> action.
484
485The currently supported styles are:
486
487=over 4
488
613f422f 489=item traditional
490
491A F<Makefile.PL> will be created in the "traditional" style, i.e. it will
492use C<ExtUtils::MakeMaker> and won't rely on C<Module::Build> at all.
493In order to create the F<Makefile.PL>, we'll include the C<requires> and
494C<build_requires> dependencies as the C<PREREQ_PM> parameter.
495
496You don't want to use this style if during the C<perl Build.PL> stage
497you ask the user questions, or do some auto-sensing about the user's
498environment, or if you subclass C<Module::Build> to do some
499customization, because the vanilla F<Makefile.PL> won't do any of that.
500
bb4e9162 501=item small
502
23837600 503A small F<Makefile.PL> will be created that passes all functionality
504through to the F<Build.PL> script in the same directory. The user must
505already have C<Module::Build> installed in order to use this, or else
bb4e9162 506they'll get a module-not-found error.
507
613f422f 508=item passthrough (DEPRECATED)
bb4e9162 509
23837600 510This is just like the C<small> option above, but if C<Module::Build> is
bb4e9162 511not already installed on the user's system, the script will offer to
512use C<CPAN.pm> to download it and install it before continuing with
513the build.
514
613f422f 515This option has been deprecated and may be removed in a future version
516of Module::Build. Modern CPAN.pm and CPANPLUS will recognize the
517C<configure_requires> metadata property and install Module::Build before
518running Build.PL if Module::Build is listed and Module::Build now
519adds itself to configure_requires by default.
bb4e9162 520
613f422f 521Perl 5.10.1 includes C<configure_requires> support. In the future, when
522C<configure_requires> support is deemed sufficiently widespread, the
523C<passthrough> style will be removed.
bb4e9162 524
525=back
526
527=item run_build_pl(args => \@ARGV)
528
23837600 529This method runs the F<Build.PL> script, passing it any arguments the
bb4e9162 530user may have supplied to the C<perl Makefile.PL> command. Because
23837600 531C<ExtUtils::MakeMaker> and C<Module::Build> accept different arguments, this
bb4e9162 532method also performs some translation between the two.
533
534C<run_build_pl()> accepts the following named parameters:
535
536=over 4
537
538=item args
539
540The C<args> parameter specifies the parameters that would usually
541appear on the command line of the C<perl Makefile.PL> command -
542typically you'll just pass a reference to C<@ARGV>.
543
544=item script
545
546This is the filename of the script to run - it defaults to C<Build.PL>.
547
548=back
549
550=item write_makefile()
551
23837600 552This method writes a 'dummy' F<Makefile> that will pass all commands
553through to the corresponding C<Module::Build> actions.
bb4e9162 554
555C<write_makefile()> accepts the following named parameters:
556
557=over 4
558
559=item makefile
560
561The name of the file to write - defaults to the string C<Makefile>.
562
563=back
564
565=back
566
567
568=head1 SCENARIOS
569
570So, some common scenarios are:
571
572=over 4
573
574=item 1.
575
23837600 576Just include a F<Build.PL> script (without a F<Makefile.PL>
577script), and give installation directions in a F<README> or F<INSTALL>
bb4e9162 578document explaining how to install the module. In particular, explain
23837600 579that the user must install C<Module::Build> before installing your
bb4e9162 580module.
581
582Note that if you do this, you may make things easier for yourself, but
583harder for people with older versions of CPAN or CPANPLUS on their
584system, because those tools generally only understand the
585F<Makefile.PL>/C<ExtUtils::MakeMaker> way of doing things.
586
587=item 2.
588
23837600 589Include a F<Build.PL> script and a "traditional" F<Makefile.PL>,
bb4e9162 590created either manually or with C<create_makefile_pl()>. Users won't
23837600 591ever have to install C<Module::Build> if they use the F<Makefile.PL>, but
592they won't get to take advantage of C<Module::Build>'s extra features
bb4e9162 593either.
594
94410036 595For good measure, of course, test both the F<Makefile.PL> and the
bb4e9162 596F<Build.PL> before shipping.
597
598=item 3.
599
23837600 600Include a F<Build.PL> script and a "pass-through" F<Makefile.PL>
601built using C<Module::Build::Compat>. This will mean that people can
bb4e9162 602continue to use the "old" installation commands, and they may never
603notice that it's actually doing something else behind the scenes. It
604will also mean that your installation process is compatible with older
605versions of tools like CPAN and CPANPLUS.
606
607=back
608
609
610=head1 AUTHOR
611
77e96e88 612Ken Williams <kwilliams@cpan.org>
bb4e9162 613
614
615=head1 COPYRIGHT
616
77e96e88 617Copyright (c) 2001-2006 Ken Williams. All rights reserved.
bb4e9162 618
619This library is free software; you can redistribute it and/or
620modify it under the same terms as Perl itself.
621
622
623=head1 SEE ALSO
624
dc8021d3 625L<Module::Build>(3), L<ExtUtils::MakeMaker>(3)
bb4e9162 626
627
628=cut