Make h2ph generate constant subs
Roderick Schertler [Fri, 18 Apr 1997 18:23:46 +0000 (14:23 -0400)]
>> Shouldn't these:
>>     eval 'sub RUN_LVL {1;}';
>> be:
>>     eval 'sub RUN_LVL() {1;}';
>
> I'd say so.  Who can tell us whether h2ph is easily changeable?

It is, here's a patch.  It could still use changes so that it emits new
style sub invocations so that more constant folding happens, but that's
trickier.  Additional changes in the patch are removal of a "chdir
/usr/include" (which prevented you from converting files in other
directories and wasn't needed for the standard invocation) and addition
of a -d switch to specify output directory (so I could test my changes
more easily).

Somewhere around here I've got the start of regression suite for h2ph,
remind me to dust it off for _50.

Another bug in h2ph it would be nice to fix:

    $ echo "
     #define FOO (BAR || BAZ)
#if FOO
#endif" | h2ph | perl
    Undefined subroutine &main::BAR called at - line 1.

I can't regenerate my vendor's current headers due to this one.

p5p-msgid: pz2088w5ot.fsf@eeyore.ibcinc.com

utils/h2ph.PL

index 70f9e01..3471300 100644 (file)
@@ -35,9 +35,15 @@ $Config{startperl}
 print OUT <<'!NO!SUBS!';
 
 use Config;
-$perlincl = @Config{installsitearch};
+use File::Path qw(mkpath);
 
-chdir '/usr/include' || die "Can't cd /usr/include";
+my $Exit = 0;
+
+my $Dest_dir = (@ARGV && $ARGV[0] =~ s/^-d//)
+                   ? shift || shift
+                   : $Config{installsitearch};
+die "Destination directory $Dest_dir doesn't exist or isn't a directory\n"
+    unless -d $Dest_dir;
 
 @isatype = split(' ',<<END);
        char    uchar   u_char
@@ -66,12 +72,10 @@ foreach $file (@ARGV) {
        print "$file -> $outfile\n";
        if ($file =~ m|^(.*)/|) {
            $dir = $1;
-           if (!-d "$perlincl/$dir") {
-               mkdir("$perlincl/$dir",0777);
-           }
+           mkpath "$Dest_dir/$dir";
        }
-       open(IN,"$file") || ((warn "Can't open $file: $!\n"),next);
-       open(OUT,">$perlincl/$outfile") || die "Can't create $outfile: $!\n";
+       open(IN,"$file") || (($Exit = 1),(warn "Can't open $file: $!\n"),next);
+       open(OUT,">$Dest_dir/$outfile") || die "Can't create $outfile: $!\n";
     }
     while (<IN>) {
        chop;
@@ -96,7 +100,9 @@ foreach $file (@ARGV) {
                s/\s+$//;
                if (s/^\(([\w,\s]*)\)//) {
                    $args = $1;
+                   my $proto = '() ';
                    if ($args ne '') {
+                       $proto = '';
                        foreach $arg (split(/,\s*/,$args)) {
                            $arg =~ s/^\s*([^\s].*[^\s])\s*$/$1/;
                            $curargs{$arg} = 1;
@@ -110,10 +116,10 @@ foreach $file (@ARGV) {
                    if ($t ne '') {
                        $new =~ s/(['\\])/\\$1/g;
                        print OUT $t,
-                         "eval 'sub $name {\n$t    ${args}eval \"$new\";\n$t}';\n";
+                         "eval 'sub $name $proto\{\n$t    ${args}eval \"$new\";\n$t}';\n";
                    }
                    else {
-                       print OUT "sub $name {\n    ${args}eval \"$new\";\n}\n";
+                       print OUT "sub $name $proto\{\n    ${args}eval \"$new\";\n}\n";
                    }
                    %curargs = ();
                }
@@ -123,10 +129,10 @@ foreach $file (@ARGV) {
                    $new = 1 if $new eq '';
                    if ($t ne '') {
                        $new =~ s/(['\\])/\\$1/g;
-                       print OUT $t,"eval 'sub $name {",$new,";}';\n";
+                       print OUT $t,"eval 'sub $name () {",$new,";}';\n";
                    }
                    else {
-                       print OUT $t,"sub $name {",$new,";}\n";
+                       print OUT $t,"sub $name () {",$new,";}\n";
                    }
                }
            }
@@ -181,6 +187,8 @@ foreach $file (@ARGV) {
     print OUT "1;\n";
 }
 
+exit $Exit;
+
 sub expr {
     while ($_ ne '') {
        s/^(\s+)//              && do {$new .= ' '; next;};
@@ -258,8 +266,8 @@ sub expr {
            else {
                if ($inif && $new !~ /defined\s*\($/) {
                    $new .= '(defined(&' . $id . ') ? &' . $id . ' : 0)';
-               } 
-               elsif (/^\[/) { 
+               }
+               elsif (/^\[/) {
                    $new .= ' $' . $id;
                }
                else {
@@ -291,6 +299,10 @@ It is most easily run while in /usr/include:
 
        cd /usr/include; h2ph * sys/*
 
+The output files are placed in the hierarchy rooted at Perl's
+architecture dependent library directory.  You can specify a different
+hierarchy with a B<-d> switch.
+
 If run with no arguments, filters standard input to standard output.
 
 =head1 ENVIRONMENT