Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / perl5 / utils / perlcc.PL
1 #!/usr/local/bin/perl
2  
3 use Config;
4 use File::Basename qw(&basename &dirname);
5 use Cwd;
6  
7 # List explicitly here the variables you want Configure to
8 # generate.  Metaconfig only looks for shell variables, so you
9 # have to mention them as if they were shell variables, not
10 # %Config entries.  Thus you write
11 #  $startperl
12 # to ensure Configure will look for $Config{startperl}.
13 # Wanted:  $archlibexp
14  
15 # This forces PL files to create target in same directory as PL file.
16 # This is so that make depend always knows where to find PL derivatives.
17 $origdir = cwd;
18 chdir dirname($0);
19 $file = basename($0, '.PL');
20 $file .= '.com' if $^O eq 'VMS';
21  
22 open OUT,">$file" or die "Can't create $file: $!";
23  
24 print "Extracting $file (with variable substitutions)\n";
25  
26 # In this section, perl variables will be expanded during extraction.
27 # You can use $Config{...} to use Configure variables.
28  
29 print OUT <<"!GROK!THIS!";
30 $Config{startperl}
31     eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
32     if \$running_under_some_shell;
33 !GROK!THIS!
34  
35 # In the following, perl variables are not expanded during extraction.
36  
37 print OUT <<'!NO!SUBS!';
38
39 use Config;
40 use strict;
41 use FileHandle;
42 use File::Basename qw(&basename &dirname);
43 use Cwd;
44
45 use Getopt::Long;
46
47 $Getopt::Long::bundling_override = 1;
48 $Getopt::Long::passthrough = 0;
49 $Getopt::Long::ignore_case = 0;
50
51 my $options = {};
52 my $_fh;
53
54 main();
55
56 sub main
57 {
58
59     GetOptions
60             (
61             $options,   "L:s",
62                         "I:s",
63                         "C:s",
64                         "o:s",
65                         "e:s",
66                         "regex:s",
67                         "verbose:s",
68                         "log:s",
69                                                 "argv:s",
70                         "gen",
71                         "sav",
72                         "run",
73                         "prog",
74                         "mod"
75             );
76
77
78     my $key;
79
80     local($") = "|";
81
82     _usage() if (!_checkopts());
83     push(@ARGV, _maketempfile()) if ($options->{'e'});
84
85     _usage() if (!@ARGV);
86                 
87     my $file;
88     foreach $file (@ARGV)
89     {
90         _print("
91 --------------------------------------------------------------------------------
92 Compiling $file:
93 --------------------------------------------------------------------------------
94 ", 36 );
95         _doit($file);
96     }
97 }
98         
99 sub _doit
100 {
101     my ($file) = @_;
102
103     my ($program_ext, $module_ext) = _getRegexps();
104     my ($obj, $objfile, $so, $type);
105
106     if  (
107             (($file =~ m"@$program_ext") && ($file !~ m"@$module_ext"))
108             || (defined($options->{'prog'}) || defined($options->{'run'}))
109         )
110     {
111         $objfile = ($options->{'C'}) ?     $options->{'C'} : "$file.c";
112         $type = 'program';
113
114         $obj =         ($options->{'o'})?     $options->{'o'} : 
115                                             _getExecutable( $file,$program_ext);
116
117         return() if (!$obj);
118
119     }
120     elsif (($file =~ m"@$module_ext") || ($options->{'mod'}))
121     {
122         die "Shared objects are not supported on Win32 yet!!!!\n"
123                                       if ($Config{'osname'} eq 'MSWin32');
124
125         $obj =         ($options->{'o'})?    $options->{'o'} :
126                                             _getExecutable($file, $module_ext);
127         $so = "$obj.$Config{so}";
128         $type = 'sharedlib';
129         return() if (!$obj);
130         $objfile = ($options->{'C'}) ?     $options->{'C'} : "$file.c";
131     }
132     else
133     {
134         _error("noextension", $file, $program_ext, $module_ext);
135         return();
136     }
137
138     if ($type eq 'program')
139     {
140         _print("Making C($objfile) for $file!\n", 36 );
141
142         my $errcode = _createCode($objfile, $file);
143         (_print( "ERROR: In generating code for $file!\n", -1), return()) 
144                                                                 if ($errcode);
145
146         _print("Compiling C($obj) for $file!\n", 36 ) if (!$options->{'gen'});
147         $errcode = _compileCode($file, $objfile, $obj) 
148                                             if (!$options->{'gen'});
149
150         if ($errcode)
151                 {
152                         _print( "ERROR: In compiling code for $objfile !\n", -1);
153                         my $ofile = File::Basename::basename($objfile);
154                         $ofile =~ s"\.c$"\.o"s;
155                         
156                         _removeCode("$ofile"); 
157                         return()
158                 }
159     
160         _runCode($obj) if ($options->{'run'});
161
162         _removeCode($objfile) if (!$options->{'sav'} || 
163                                     ($options->{'e'} && !$options->{'C'}));
164
165         _removeCode($file) if ($options->{'e'}); 
166
167         _removeCode($obj) if (($options->{'e'}
168                                && !$options->{'sav'}
169                                && !$options->{'o'})
170                               || ($options->{'run'} && !$options->{'sav'}));
171     }
172     else
173     {
174         _print( "Making C($objfile) for $file!\n", 36 );
175         my $errcode = _createCode($objfile, $file, $obj);
176         (_print( "ERROR: In generating code for $file!\n", -1), return()) 
177                                                                 if ($errcode);
178     
179         _print( "Compiling C($so) for $file!\n", 36 ) if (!$options->{'gen'});
180
181         my $errorcode = 
182             _compileCode($file, $objfile, $obj, $so ) if (!$options->{'gen'});
183
184         (_print( "ERROR: In compiling code for $objfile!\n", -1), return()) 
185                                                                 if ($errcode);
186     }
187 }
188
189 sub _getExecutable
190 {
191     my ($sourceprog, $ext) = @_;
192     my ($obj);
193
194     if (defined($options->{'regex'}))
195     {
196         eval("(\$obj = \$sourceprog) =~ $options->{'regex'}");
197         return(0) if (_error('badeval', $@));
198         return(0) if (_error('equal', $obj, $sourceprog));
199     }
200     elsif (defined ($options->{'ext'}))
201     {
202         ($obj = $sourceprog) =~ s"@$ext"$options->{ext}"g;        
203         return(0) if (_error('equal', $obj, $sourceprog));
204     }
205         elsif (defined ($options->{'run'}))
206         {
207                 $obj = "perlc$$";
208         }
209     else
210     {
211         ($obj = $sourceprog) =~ s"@$ext""g;
212         return(0) if (_error('equal', $obj, $sourceprog));
213     }
214     return($obj);
215 }
216
217 sub _createCode
218 {
219     my ( $generated_cfile, $file, $final_output ) = @_;
220     my $return;
221
222     local($") = " -I";
223
224     if (@_ == 2)                                   # compiling a program   
225     {
226         _print( "$^X -I@INC -MO=CC,-o$generated_cfile $file\n", 36);
227         $return =  _run("$\18 -I@INC -MO=CC,-o$generated_cfile $file", 9);
228         $return;
229     }
230     else                                           # compiling a shared object
231     {            
232         _print( 
233             "$\18 -I@INC -MO=CC,-m$final_output,-o$generated_cfile $file\n", 36);
234         $return = 
235         _run("$\18 -I@INC -MO=CC,-m$final_output,-o$generated_cfile $file", 9);
236         $return;
237     }
238 }
239
240 sub _compileCode
241 {
242     my ($sourceprog, $generated_cfile, $output_executable, $shared_object) = @_;
243     my @return;
244
245     if (@_ == 3)                            # just compiling a program 
246     {
247         $return[0] = 
248         _ccharness('static', $sourceprog, "-o", $output_executable, $generated_cfile);  
249         $return[0];
250     }
251     else
252     {
253         my $object_file = $generated_cfile;
254         $object_file =~ s"\.c$"$Config{_o}";   
255
256         $return[0] = _ccharness('compile', $sourceprog, "-c", $generated_cfile);
257         $return[1] = _ccharness
258                             (
259                                 'dynamic', 
260                                 $sourceprog, "-o", 
261                                 $shared_object, $object_file 
262                             );
263         return(1) if (grep ($_, @return));
264         return(0);
265     }
266 }
267
268 sub _runCode
269 {
270     my ($executable) = @_;
271     _print("$executable $options->{'argv'}\n", 36);
272     _run("$executable $options->{'argv'}", -1 );
273 }
274
275 sub _removeCode
276 {
277     my ($file) = @_;
278     unlink($file) if (-e $file);
279 }
280
281 sub _ccharness
282 {
283     my $type = shift;
284     my (@args) = @_;
285     local($") = " ";
286
287     my $sourceprog = shift(@args);
288     my ($libdir, $incdir);
289
290     if (-d "$Config{installarchlib}/CORE")
291     {
292         $libdir = "-L$Config{installarchlib}/CORE";
293         $incdir = "-I$Config{installarchlib}/CORE";
294     }
295     else
296     {
297         $libdir = "-L.. -L."; 
298         $incdir = "-I.. -I.";
299     }
300
301     $libdir .= " -L$options->{L}" if (defined($options->{L}));
302     $incdir .= " -I$options->{L}" if (defined($options->{L}));
303
304     my $linkargs = '';
305
306     if (!grep(/^-[cS]$/, @args))
307     {
308         my $lperl = $^O eq 'os2' ? '-llibperl' : '-lperl';
309         my $flags = $type eq 'dynamic' ? $Config{lddlflags} : $Config{ldflags};
310         $linkargs = "$flags $libdir $lperl @Config{libs}";
311     }
312
313     my @sharedobjects = _getSharedObjects($sourceprog); 
314
315     my $cccmd = 
316         "$Config{cc} @Config{qw(ccflags optimize)} $incdir @sharedobjects @args $linkargs";
317
318
319     _print ("$cccmd\n", 36);
320     _run("$cccmd", 18 );
321 }
322
323 sub _getSharedObjects
324 {
325     my ($sourceprog) = @_;
326     my ($tmpfile, $incfile);
327     my (@return);
328     local($") = " -I";
329
330     if ($Config{'osname'} eq 'MSWin32') 
331     { 
332         # _addstuff;    
333     }
334     else
335     {
336         my ($tmpprog);
337         ($tmpprog = $sourceprog) =~ s"(.*)[\/\\](.*)"$2";
338         $tmpfile = "/tmp/$tmpprog.tst";
339         $incfile = "/tmp/$tmpprog.val";
340     }
341
342     my $fd = new FileHandle("> $tmpfile") || die "Couldn't open $tmpfile!\n";
343     my $fd2 = 
344         new FileHandle("$sourceprog") || die "Couldn't open $sourceprog!\n";
345
346     my $perl = <$fd2>;  # strip off header;
347
348     print $fd 
349 <<"EOF";
350         use FileHandle;
351         my \$fh3  = new FileHandle("> $incfile") 
352                                         || die "Couldn't open $incfile\\n";
353
354         my \$key;
355         foreach \$key (keys(\%INC)) { print \$fh3 "\$key:\$INC{\$key}\\n"; }
356         close(\$fh3);
357         exit();
358 EOF
359
360     print $fd (   <$fd2>    );
361     close($fd);
362
363     _print("$\18 -I@INC $tmpfile\n", 36);
364     _run("$\18 -I@INC $tmpfile", 9 );
365
366     $fd = new FileHandle ("$incfile"); 
367     my @lines = <$fd>;    
368
369     unlink($tmpfile);
370     unlink($incfile);
371
372     my $line;
373     my $autolib;
374
375     foreach $line (@lines) 
376     {
377         chomp($line);
378         my ($modname, $modpath) = split(':', $line);
379         my ($dir, $file) = ($modpath=~ m"(.*)[\\/]($modname)");
380         
381         if ($autolib = _lookforAuto($dir, $file))
382         {
383             push(@return, $autolib);
384         }
385     }
386
387     return(@return);
388 }
389
390 sub _maketempfile
391 {
392     my $return;
393
394 #    if ($Config{'osname'} eq 'MSWin32') 
395 #            { $return = "C:\\TEMP\\comp$$.p"; }
396 #    else
397 #            { $return = "/tmp/comp$$.p"; }
398
399     $return = "comp$$.p"; 
400
401     my $fd = new FileHandle( "> $return") || die "Couldn't open $return!\n";
402     print $fd $options->{'e'};
403     close($fd);
404
405     return($return);
406 }
407     
408     
409 sub _lookforAuto
410 {
411     my ($dir, $file) = @_;    
412
413     my $relshared;
414     my $return;
415
416     ($relshared = $file) =~ s"(.*)\.pm"$1";
417
418     my ($tmp, $modname) = ($relshared =~ m"(?:(.*)[\\/]){0,1}(.*)"s);
419
420     $relshared .= 
421         ($Config{'osname'} eq 'MSWin32')? "\\$modname.dll" : "/$modname.so";
422     
423
424
425     if (-e ($return = "$Config{'installarchlib'}/auto/$relshared") )
426     {
427         return($return);    
428     }
429     elsif (-e ($return = "$Config{'installsitearch'}/auto/$relshared"))
430     {
431         return($return);
432     }
433     elsif (-e ($return = "$dir/arch/auto/$relshared"))
434     {
435         return($return);    
436     }
437     else
438     {
439         return(undef);
440     }
441 }
442
443 sub _getRegexps    # make the appropriate regexps for making executables, 
444 {                  # shared libs
445
446     my ($program_ext, $module_ext) = ([],[]); 
447
448
449     @$program_ext = ($ENV{PERL_SCRIPT_EXT})? split(':', $ENV{PERL_SCRIPT_EXT}) :
450                                             ('.p$', '.pl$', '.bat$');
451
452
453     @$module_ext  = ($ENV{PERL_MODULE_EXT})? split(':', $ENV{PERL_MODULE_EXT}) :
454                                             ('.pm$');
455
456
457     _mungeRegexp( $program_ext );
458     _mungeRegexp( $module_ext  );    
459
460     return($program_ext, $module_ext);
461 }
462
463 sub _mungeRegexp
464 {
465     my ($regexp) = @_;
466
467     grep(s:(^|[^\\])\.:$1\x00\\.:g, @$regexp);
468     grep(s:(^|[^\x00])\\\.:$1\.:g,  @$regexp);
469     grep(s:\x00::g,                 @$regexp);
470 }
471
472
473 sub _error
474 {
475     my ($type, @args) = @_;
476
477     if ($type eq 'equal')
478     {
479             
480         if ($args[0] eq $args[1])
481         {
482             _print ("ERROR: The object file '$args[0]' does not generate a legitimate executable file! Skipping!\n", -1);
483             return(1);
484         }
485     }
486     elsif ($type eq 'badeval')
487     {
488         if ($args[0])
489         {
490             _print ("ERROR: $args[0]\n", -1);
491             return(1);
492         }
493     }
494     elsif ($type eq 'noextension')
495     {
496         my $progext = join(',', @{$args[1]});
497         my $modext  = join(',', @{$args[2]});
498
499         $progext =~ s"\\""g;
500         $modext  =~ s"\\""g;
501
502         $progext =~ s"\$""g;
503         $modext  =~ s"\$""g;
504
505         _print 
506         (
507 "
508 ERROR: '$args[0]' does not have a proper extension! Proper extensions are:
509
510     PROGRAM:       $progext 
511     SHARED OBJECT: $modext
512
513 Use the '-prog' flag to force your files to be interpreted as programs.
514 Use the '-mod' flag to force your files to be interpreted as modules.
515 ", -1
516         );
517         return(1);
518     }
519
520     return(0);
521 }
522
523 sub _checkopts
524 {
525     my @errors;
526     local($") = "\n";
527
528     if ($options->{'log'})
529     {
530         $_fh = new FileHandle(">> $options->{'log'}") || push(@errors, "ERROR: Couldn't open $options->{'log'}\n");
531     }
532
533     if (($options->{'c'}) && (@ARGV > 1) && ($options->{'sav'} ))
534     {
535         push(@errors, 
536 "ERROR: The '-sav' and '-C' options are incompatible when you have more than 
537        one input file! ('-C' explicitly names resulting C code, '-sav' saves it,
538        and hence, with more than one file, the c code will be overwritten for 
539        each file that you compile)\n");
540     }
541     if (($options->{'o'}) && (@ARGV > 1))
542     {
543         push(@errors, 
544 "ERROR: The '-o' option is incompatible when you have more than one input file! 
545        (-o explicitly names the resulting executable, hence, with more than 
546        one file the names clash)\n");
547     }
548
549     if ($options->{'e'} && $options->{'sav'} && !$options->{'o'} && 
550                                                             !$options->{'C'})
551     {
552         push(@errors, 
553 "ERROR: You need to specify where you are going to save the resulting 
554        executable or C code,  when using '-sav' and '-e'. Use '-o' or '-C'.\n");
555     }
556
557     if (($options->{'regex'} || $options->{'run'} || $options->{'o'}) 
558                                                     && $options->{'gen'})
559     {
560         push(@errors, 
561 "ERROR: The options '-regex', '-run', and '-o' are incompatible with '-gen'. 
562        '-gen' says to stop at C generation, and the other three modify the 
563        compilation and/or running process!\n");
564     }
565
566     if ($options->{'run'} && $options->{'mod'})
567     {
568         push(@errors, 
569 "ERROR: Can't run modules that you are compiling! '-run' and '-mod' are 
570        incompatible!\n"); 
571     }
572
573     if ($options->{'e'} && @ARGV)
574     {
575         push (@errors, 
576 "ERROR: The option '-e' needs to be all by itself without any other 
577        file arguments!\n");
578     }
579     if ($options->{'e'} && !($options->{'o'} || $options->{'run'}))
580     {
581         $options->{'run'} = 1;
582     }
583
584     if (!defined($options->{'verbose'})) 
585     { 
586         $options->{'verbose'} = ($options->{'log'})? 64 : 7; 
587     }
588
589     my $verbose_error;
590
591     if ($options->{'verbose'} =~ m"[^tagfcd]" && 
592             !( $options->{'verbose'} eq '0' || 
593                 ($options->{'verbose'} < 64 && $options->{'verbose'} > 0)))
594     {
595         $verbose_error = 1;
596         push(@errors, 
597 "ERROR: Illegal verbosity level.  Needs to have either the letters 
598        't','a','g','f','c', or 'd' in it or be between 0 and 63, inclusive.\n");
599     }
600
601     $options->{'verbose'} = ($options->{'verbose'} =~ m"[tagfcd]")? 
602                             ($options->{'verbose'} =~ m"d") * 32 +     
603                             ($options->{'verbose'} =~ m"c") * 16 +     
604                             ($options->{'verbose'} =~ m"f") * 8     +     
605                             ($options->{'verbose'} =~ m"t") * 4     +     
606                             ($options->{'verbose'} =~ m"a") * 2     +     
607                             ($options->{'verbose'} =~ m"g") * 1     
608                                                     : $options->{'verbose'};
609
610     if     (!$verbose_error && (    $options->{'log'} && 
611                                 !(
612                                     ($options->{'verbose'} & 8)   || 
613                                     ($options->{'verbose'} & 16)  || 
614                                     ($options->{'verbose'} & 32 ) 
615                                 )
616                             )
617         )
618     {
619         push(@errors, 
620 "ERROR: The verbosity level '$options->{'verbose'}' does not output anything 
621        to a logfile, and you specified '-log'!\n");
622     } # }
623
624     if     (!$verbose_error && (    !$options->{'log'} && 
625                                 (
626                                     ($options->{'verbose'} & 8)   || 
627                                     ($options->{'verbose'} & 16)  || 
628                                     ($options->{'verbose'} & 32)  || 
629                                     ($options->{'verbose'} & 64)
630                                 )
631                             )
632         )
633     {
634         push(@errors, 
635 "ERROR: The verbosity level '$options->{'verbose'}' requires that you also 
636        specify a logfile via '-log'\n");
637     } # }
638
639
640     (_print( "\n". join("\n", @errors), -1), return(0)) if (@errors);
641     return(1);
642 }
643
644 sub _print
645 {
646     my ($text, $flag ) = @_;
647     
648     my $logflag = int($flag/8) * 8;
649     my $regflag = $flag % 8;
650
651     if ($flag == -1 || ($flag & $options->{'verbose'}))
652     {
653         my $dolog = ((($logflag & $options->{'verbose'}) || $flag == -1) 
654                                                         && $options->{'log'}); 
655
656         my $doreg = (($regflag & $options->{'verbose'}) || $flag == -1);
657         
658         if ($doreg) { print( STDERR $text ); }
659         if ($dolog) { print $_fh $text; }
660     }
661 }
662
663 sub _run
664 {
665     my ($command, $flag) = @_;
666
667     my $logflag = ($flag != -1)? int($flag/8) * 8 : 0;
668     my $regflag = $flag % 8;
669
670     if ($flag == -1 || ($flag & $options->{'verbose'}))
671     {
672         my $dolog = ($logflag & $options->{'verbose'} && $options->{'log'});
673         my $doreg = (($regflag & $options->{'verbose'}) || $flag == -1);
674
675         if ($doreg && !$dolog) 
676             { system("$command"); }
677
678         elsif ($doreg && $dolog) 
679             { my $text = `$command 2>&1`; print $_fh $text; print STDERR $text;}
680         else 
681             { my $text = `$command 2>&1`; print $_fh $text; }
682     }
683     else 
684     {
685         `$command 2>&1`; 
686     }
687     return($?);
688 }
689
690 sub _usage
691 {
692     _print
693     ( 
694     <<"EOF"
695
696 Usage: $0 <file_list> 
697
698     Flags with arguments
699         -L       < extra library dirs for installation (form of 'dir1:dir2') >
700         -I       < extra include dirs for installation (form of 'dir1:dir2') >
701         -C       < explicit name of resulting C code > 
702         -o       < explicit name of resulting executable >
703         -e       < to compile 'one liners'. Need executable name (-o) or '-run'>
704         -regex   < rename regex, -regex 's/\.p/\.exe/' compiles a.p to a.exe >
705         -verbose < verbose level (1-63, or following letters 'gatfcd' >
706         -argv    < arguments for the executables to be run via '-run' or '-e' > 
707
708     Boolean flags
709         -gen     ( to just generate the c code. Implies '-sav' )
710         -sav     ( to save intermediate c code, (and executables with '-run'))
711         -run     ( to run the compiled program on the fly, as were interpreted.)
712         -prog    ( to indicate that the files on command line are programs )
713         -mod     ( to indicate that the files on command line are modules  )
714
715 EOF
716 , -1
717
718     );
719     exit(255);
720 }
721
722
723 __END__
724
725 =head1 NAME
726
727 perlcc - frontend for perl compiler
728
729 =head1 SYNOPSIS
730
731     %prompt  perlcc a.p        # compiles into executable 'a'
732
733     %prompt  perlcc A.pm       # compile into 'A.so'
734
735     %prompt  perlcc a.p -o execute  # compiles 'a.p' into 'execute'.
736
737     %prompt  perlcc a.p -o execute -run # compiles 'a.p' into execute, runs on
738                                         # the fly
739
740     %prompt  perlcc a.p -o execute -run -argv 'arg1 arg2 arg3' 
741                                         # compiles into execute, runs with 
742                                         # arg1 arg2 arg3 as @ARGV
743
744     %prompt perlcc a.p b.p c.p -regex 's/\.p/\.exe'
745                                         # compiles into 'a.exe','b.exe','c.exe'.
746
747     %prompt perlcc a.p -log compilelog  # compiles into 'a', saves compilation
748                                         # info into compilelog, as well
749                                         # as mirroring to screen
750
751     %prompt perlcc a.p -log compilelog -verbose cdf 
752                                         # compiles into 'a', saves compilation
753                                         # info into compilelog, being silent
754                                         # on screen.
755
756     %prompt perlcc a.p -C a.c -gen      # generates C code (into a.c) and 
757                                         # stops without compile.
758
759     %prompt perlcc a.p -L ../lib a.c 
760                                         # Compiles with the perl libraries 
761                                         # inside ../lib included.
762
763 =head1 DESCRIPTION
764
765 'perlcc' is the frontend into the perl compiler. Typing 'perlcc a.p'
766 compiles the code inside a.p into a standalone executable, and 
767 perlcc A.pm will compile into a shared object, A.so, suitable for inclusion 
768 into a perl program via "use A".
769
770 There are quite a few flags to perlcc which help with such issues as compiling 
771 programs in bulk, testing compiled programs for compatibility with the 
772 interpreter, and controlling.
773
774 =head1 OPTIONS 
775
776 =over 4
777
778 =item -L < library_directories >
779
780 Adds directories in B<library_directories> to the compilation command.
781
782 =item -I  < include_directories > 
783
784 Adds directories inside B<include_directories> to the compilation command.
785
786 =item -C   < c_code_name > 
787
788 Explicitly gives the name B<c_code_name> to the generated c code which is to 
789 be compiled. Can only be used if compiling one file on the command line.
790
791 =item -o   < executable_name >
792
793 Explicitly gives the name B<executable_name> to the executable which is to be
794 compiled. Can only be used if compiling one file on the command line.
795
796 =item -e   < perl_line_to_execute>
797
798 Compiles 'one liners', in the same way that B<perl -e> runs text strings at 
799 the command line. Default is to have the 'one liner' be compiled, and run all
800 in one go (see B<-run>); giving the B<-o> flag saves the resultant executable, 
801 rather than throwing it away. Use '-argv' to pass arguments to the executable
802 created.
803
804 =item -regex   <rename_regex>
805
806 Gives a rule B<rename_regex> - which is a legal perl regular expression - to 
807 create executable file names.
808
809 =item -verbose <verbose_level>
810
811 Show exactly what steps perlcc is taking to compile your code. You can change 
812 the verbosity level B<verbose_level> much in the same way that the '-D' switch 
813 changes perl's debugging level, by giving either a number which is the sum of 
814 bits you want or a list of letters representing what you wish to see. Here are 
815 the verbosity levels so far :
816
817     Bit 1(g):      Code Generation Errors to STDERR
818     Bit 2(a):      Compilation Errors to STDERR
819     Bit 4(t):      Descriptive text to STDERR 
820     Bit 8(f):      Code Generation Errors to file (B<-log> flag needed)
821     Bit 16(c):     Compilation Errors to file (B<-log> flag needed)
822     Bit 32(d):     Descriptive text to file (B<-log> flag needed) 
823
824 If the B<-log> tag is given, the default verbose level is 63 (ie: mirroring 
825 all of perlcc's output to both the screen and to a log file). If no B<-log>
826 tag is given, then the default verbose level is 7 (ie: outputting all of 
827 perlcc's output to STDERR).
828
829 NOTE: Because of buffering concerns, you CANNOT shadow the output of '-run' to
830 both a file, and to the screen! Suggestions are welcome on how to overcome this
831 difficulty, but for now it simply does not work properly, and hence will only go
832 to the screen.
833
834 =item -log <logname>
835
836 Opens, for append, a logfile to save some or all of the text for a given 
837 compile command. No rewrite version is available, so this needs to be done 
838 manually.
839
840 =item -argv <arguments>
841
842 In combination with '-run' or '-e', tells perlcc to run the resulting 
843 executable with the string B<arguments> as @ARGV.
844
845 =item -sav
846
847 Tells perl to save the intermediate C code. Usually, this C code is the name
848 of the perl code, plus '.c'; 'perlcode.p' gets generated in 'perlcode.p.c',
849 for example. If used with the '-e' operator, you need to tell perlcc where to 
850 save resulting executables.
851
852 =item -gen
853
854 Tells perlcc to only create the intermediate C code, and not compile the 
855 results. Does an implicit B<-sav>, saving the C code rather than deleting it.
856
857 =item -run
858
859 Immediately run the perl code that has been generated. NOTE: IF YOU GIVE THE 
860 B<-run> FLAG TO B<perlcc>, THEN THE REST OF @ARGV WILL BE INTERPRETED AS 
861 ARGUMENTS TO THE PROGRAM THAT YOU ARE COMPILING.
862
863 =item -prog
864
865 Indicate that the programs at the command line are programs, and should be
866 compiled as such. B<perlcc> will automatically determine files to be 
867 programs if they have B<.p>, B<.pl>, B<.bat> extensions.
868
869 =item -mod
870
871 Indicate that the programs at the command line are modules, and should be
872 compiled as such. B<perlcc> will automatically determine files to be 
873 modules if they have the extension B<.pm>.
874
875 =back
876
877 =head1 ENVIRONMENT
878
879 Most of the work of B<perlcc> is done at the command line. However, you can 
880 change the heuristic which determines what is a module and what is a program.
881 As indicated above, B<perlcc> assumes that the extensions:
882
883 .p$, .pl$, and .bat$
884
885 indicate a perl program, and:
886
887 .pm$
888
889 indicate a library, for the purposes of creating executables. And furthermore,
890 by default, these extensions will be replaced (and dropped ) in the process of 
891 creating an executable. 
892
893 To change the extensions which are programs, and which are modules, set the
894 environmental variables:
895
896 PERL_SCRIPT_EXT
897 PERL_MODULE_EXT
898
899 These two environmental variables take colon-separated, legal perl regular 
900 expressions, and are used by perlcc to decide which objects are which. 
901 For example:
902
903 setenv PERL_SCRIPT_EXT  '.prl$:.perl$'
904 prompt%   perlcc sample.perl
905
906 will compile the script 'sample.perl' into the executable 'sample', and
907
908 setenv PERL_MODULE_EXT  '.perlmod$:.perlmodule$'
909
910 prompt%   perlcc sample.perlmod
911
912 will  compile the module 'sample.perlmod' into the shared object 
913 'sample.so'
914
915 NOTE: the '.' in the regular expressions for PERL_SCRIPT_EXT and PERL_MODULE_EXT
916 is a literal '.', and not a wild-card. To get a true wild-card, you need to 
917 backslash the '.'; as in:
918
919 setenv PERL_SCRIPT_EXT '\.\.\.\.\.'
920
921 which would have the effect of compiling ANYTHING (except what is in 
922 PERL_MODULE_EXT) into an executable with 5 less characters in its name.
923
924 =head1 FILES
925
926 'perlcc' uses a temporary file when you use the B<-e> option to evaluate 
927 text and compile it. This temporary file is 'perlc$$.p'. The temporary C code is
928 perlc$$.p.c, and the temporary executable is perlc$$.
929
930 When you use '-run' and don't save your executable, the temporary executable is
931 perlc$$
932
933 =head1 BUGS
934
935 perlcc currently cannot compile shared objects on Win32. This should be fixed
936 by perl5.005.
937
938 =cut
939
940 !NO!SUBS!
941
942 close OUT or die "Can't close $file: $!";
943 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
944 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
945 chdir $origdir;