| #!/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 "\n"; | |
| print $outfh "FILE_LICENCE ( MIT );\n"; | |
| print $outfh "FILE_SECBOOT ( PERMITTED );\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 ); |