| #!/usr/bin/perl -w |
| |
| =head1 NAME |
| |
| import.pl |
| |
| =head1 SYNOPSIS |
| |
| import.pl [options] /path/to/xen |
| |
| Options: |
| |
| -h,--help Display brief help message |
| -v,--verbose Increase verbosity |
| -q,--quiet Decrease verbosity |
| |
| =cut |
| |
| use File::Spec::Functions qw ( :ALL ); |
| use File::Find; |
| use File::Path; |
| use Getopt::Long; |
| use Pod::Usage; |
| use FindBin; |
| use strict; |
| use warnings; |
| |
| my $verbosity = 0; |
| |
| sub try_import_file { |
| my $ipxedir = shift; |
| my $xendir = shift; |
| my $filename = shift; |
| |
| # Skip everything except headers |
| return unless $filename =~ /\.h$/; |
| |
| # Search for importable header |
| ( undef, my $subdir, undef ) = splitpath ( $filename ); |
| my $outfile = catfile ( $ipxedir, $filename ); |
| my $infile = catfile ( $xendir, "xen/include/public", $filename ); |
| die "$infile does not exist\n" unless -e $infile; |
| |
| # Import header file |
| print "$filename <- ".catfile ( $xendir, $filename )."\n" |
| if $verbosity >= 1; |
| open my $infh, "<", $infile or die "Could not open $infile: $!\n"; |
| mkpath ( catdir ( $xendir, $subdir ) ); |
| open my $outfh, ">", $outfile or die "Could not open $outfile: $!\n"; |
| my @dependencies = (); |
| my $maybe_guard; |
| my $guard; |
| while ( <$infh> ) { |
| # Strip CR and trailing whitespace |
| s/\r//g; |
| s/\s*$//g; |
| chomp; |
| # Update include lines, and record included files |
| if ( /^\#include\s+[<\"](\S+)[>\"]/ ) { |
| push @dependencies, catfile ( $subdir, $1 ); |
| } |
| # Patch "Unsupported architecture" line |
| if ( /^\#error\s+"Unsupported\sarchitecture"/ ) { |
| $_ = "#include <bits/xen.h>" |
| } |
| # Write out line |
| print $outfh "$_\n"; |
| # Apply FILE_LICENCE() immediately after include guard |
| if ( defined $maybe_guard ) { |
| if ( /^\#define\s+_+${maybe_guard}_H_*$/ ) { |
| die "Duplicate header guard detected in $infile\n" if $guard; |
| $guard = $maybe_guard; |
| print $outfh "\nFILE_LICENCE ( MIT );\n"; |
| } |
| undef $maybe_guard; |
| } |
| if ( /^#ifndef\s+_+(\S+)_H_*$/ ) { |
| $maybe_guard = $1; |
| } |
| } |
| close $outfh; |
| close $infh; |
| # Warn if no header guard was detected |
| warn "Cannot detect header guard in $infile\n" unless $guard; |
| # Recurse to handle any included files that we don't already have |
| foreach my $dependency ( @dependencies ) { |
| if ( ! -e catfile ( $ipxedir, $dependency ) ) { |
| print "...following dependency on $dependency\n" if $verbosity >= 1; |
| try_import_file ( $ipxedir, $xendir, $dependency ); |
| } |
| } |
| return; |
| } |
| |
| # Parse command-line options |
| Getopt::Long::Configure ( 'bundling', 'auto_abbrev' ); |
| GetOptions ( |
| 'verbose|v+' => sub { $verbosity++; }, |
| 'quiet|q+' => sub { $verbosity--; }, |
| 'help|h' => sub { pod2usage ( 1 ); }, |
| ) or die "Could not parse command-line options\n"; |
| pod2usage ( 1 ) unless @ARGV == 1; |
| my $xendir = shift; |
| |
| # Identify Xen import directory |
| die "Directory \"$xendir\" does not appear to contain the Xen source tree\n" |
| unless -e catfile ( $xendir, "xen/include/public/xen.h" ); |
| |
| # Identify iPXE Xen includes directory |
| my $ipxedir = $FindBin::Bin; |
| die "Directory \"$ipxedir\" does not appear to contain the iPXE Xen includes\n" |
| unless -e catfile ( $ipxedir, "../../include/ipxe" ); |
| |
| print "Importing Xen headers into $ipxedir\nfrom $xendir\n" |
| if $verbosity >= 1; |
| |
| # Import headers |
| find ( { wanted => sub { |
| try_import_file ( $ipxedir, $xendir, abs2rel ( $_, $ipxedir ) ); |
| }, no_chdir => 1 }, $ipxedir ); |