diff options
author | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2004-06-10 17:26:15 +0000 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2004-06-10 17:26:15 +0000 |
commit | 09f4278941fe925f20d703828b105fac98aebb69 (patch) | |
tree | 05a03d6403cba649fb12c83a0e6641821f5448a5 /utils | |
parent | 94bf78a795a6b7b59c6efa35b65f1ca376fc4d00 (diff) | |
download | perl-09f4278941fe925f20d703828b105fac98aebb69.tar.gz |
Make h2ph able to understand a limited set of inline functions.
The glibc apparently now ships headers that use inline functions
instead of plain old macros.
p4raw-id: //depot/perl@22925
Diffstat (limited to 'utils')
-rw-r--r-- | utils/h2ph.PL | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/utils/h2ph.PL b/utils/h2ph.PL index c5cc185dd4..c6cd99a576 100644 --- a/utils/h2ph.PL +++ b/utils/h2ph.PL @@ -133,9 +133,9 @@ while (defined (my $file = next_file())) { s/\(\w+\s*\(\*\)\s*\(\w*\)\)\s*(-?\d+)/$1/; # (int (*)(foo_t))0 if (s/^\(([\w,\s]*)\)//) { $args = $1; - my $proto = '() '; + my $proto = '() '; if ($args ne '') { - $proto = ''; + $proto = ''; foreach my $arg (split(/,\s*/,$args)) { $arg =~ s/^\s*([^\s].*[^\s])\s*$/$1/; $curargs{$arg} = 1; @@ -268,7 +268,7 @@ while (defined (my $file = next_file())) { } elsif(/^ident\s+(.*)/) { print OUT $t, "# $1\n"; } - } elsif(/^\s*(typedef\s*)?enum\s*(\s+[a-zA-Z_]\w*\s*)?/) { + } elsif (/^\s*(typedef\s*)?enum\s*(\s+[a-zA-Z_]\w*\s*)?/) { # { for vi until(/\{[^}]*\}.*;/ || /;/) { last unless defined ($next = next_line($file)); chomp $next; @@ -300,6 +300,60 @@ while (defined (my $file = next_file())) { "unless defined(\&$enum_name);\n"); } } + } elsif (/^(?:__extension__\s+)?extern\s+__inline(?:__)?\s+/) { # { for vi + # This is a hack to parse the inline functions in the glibc headers. + # Warning: massive kludge ahead. We suppose inline functions are mainly + # constructed like macros. + while (1) { + last unless defined ($next = next_line($file)); + chomp $next; + undef $_, last if $next =~ /__THROW\s*;/; + $_ .= " $next"; + print OUT "# $next\n" if $opt_D; + last if $next =~ /^}|^{.*}\s*$/; + } + next if not defined; # because it's only a prototype + s/\b(__extension__|extern|__inline(?:__)?)\b//g; + if (s/^(?:\w|\s|\*)*\s(\w+)\s*//) { + $name = $1; + } else { + warn "name not found"; next; # shouldn't occur... + } + my @args; + if (s/^\(([^()]*)\)\s*(\w+\s*)*//) { + for my $arg (split /,/, $1) { + if ($arg =~ /(\w+)\s*$/) { + $curargs{$1} = 1; + push @args, $1; + } + } + } + $args = ( + @args + ? "local(" . (join ',', map "\$$_", @args) . ") = \@_;\n$t " + : "" + ); + my $proto = @args ? '' : '() '; + $new = ''; + s/\breturn\b//g; # "return" doesn't occur in macros usually... + expr(); + $new =~ s/(["\\])/\\$1/g; #"]); + $new = reindent($new); + $args = reindent($args); + if ($t ne '') { + $new =~ s/(['\\])/\\$1/g; #']); + if ($opt_h) { + print OUT $t, + "eval \"\\n#line $eval_index $outfile\\n\" . 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n"; + $eval_index++; + } else { + print OUT $t, + "eval 'sub $name $proto\{\n$t ${args}eval q($new);\n$t}' unless defined(\&$name);\n"; + } + } else { + print OUT "unless(defined(\&$name)) {\n sub $name $proto\{\n\t${args}eval q($new);\n }\n}\n"; + } + %curargs = (); } } $Is_converted{$file} = 1; @@ -308,7 +362,7 @@ while (defined (my $file = next_file())) { $next = ''; } else { print OUT "1;\n"; - queue_includes_from($file) if ($opt_a); + queue_includes_from($file) if $opt_a; } } |