From 8923fea943dd862f13944085698b83493a590bd3 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Mon, 11 May 2015 11:08:13 +0900 Subject: [PATCH] [clang] extract source files from argument to clang using the following rules: * does not start with `-` * is not a succeeding argument of `-o` * the file exists * the suffix is either of: .c, .m, .mm, .M, .cc, .cp, .cxx, .cpp, .CPP, .c++, .C relates to #16 --- bin/qrintf | 63 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/bin/qrintf b/bin/qrintf index 197c86e..1caf94a 100755 --- a/bin/qrintf +++ b/bin/qrintf @@ -2,10 +2,18 @@ use strict; use warnings; +use Digest::SHA qw(sha1_hex); use File::Basename qw(basename dirname); use File::Temp qw(tempdir); use POSIX qw(WIFEXITED WEXITSTATUS WTERMSIG); +my %EXT = ( + c => 'i', + m => 'mi', + (map { $_ => 'mii' } qw(mm M)), + (map { $_ => 'ii' } qw(cc cp cxx cpp CPP c++ C)), +); + if (@ARGV < 2 || grep { $_ =~ /^(-h|--help)$/s } @ARGV) { print "Usage: $0 compiler [compiler-options...] filename\n"; exit 0; @@ -22,6 +30,9 @@ if (basename($cc) =~ m{^g(?:cc|\+\+)}) { } else { # mimic GCC's "-no-integrated-cpp -wrapper" + # create temporary directory + my $tempdir = tempdir(CLEANUP => 1); + # suppress warnings like: `argument unused during compilation: '-I include'` unshift @ARGV, "-Qunused-arguments" if basename($cc) =~ m{^clang}; @@ -36,30 +47,36 @@ if (basename($cc) =~ m{^g(?:cc|\+\+)}) { ++$i; } } - # and take the last argument as the source fn - my $fn = pop @ARGV; - # create temporary directory - my $tempdir = tempdir(CLEANUP => 1); - my $tempfn = basename($fn); - $tempfn =~ s{\.c(.*)$}{.i@{[$1 ? 'i' : '']}}s - or $tempfn = "$tempfn.i"; - $tempfn = "$tempdir/$tempfn"; - - # invoke cpp - run_cmd( - "$pwd/../share/qrintf/gcc-wrapper", - $cc, '-E', - (grep { $_ ne '-c' } @ARGV), - $fn, - '-o', $tempfn, - ); + # splice the filenames from ARGV + my @files; + for (my $i = 0; $i < @ARGV;) { + if ($ARGV[$i] !~ /^-/s # does not start with '-' + && -e $ARGV[$i] # is a file + && get_preprocessed_fn($ARGV[$i]) # is a file that is recognized as a source file + ) { + push @files, splice @ARGV, $i, 1; + } else { + ++$i; + } + } + + # preprocess the source files + for my $fn (@files) { + run_cmd( + "$pwd/../share/qrintf/gcc-wrapper", + $cc, '-E', + (grep { $_ ne '-c' } @ARGV), + $fn, + '-o', get_preprocessed_fn($fn), + ); + } exit 0 if grep { $_ eq '-E' } @ARGV; # invoke cc - push @ARGV, $tempfn; + push @ARGV, map { get_preprocessed_fn($_) } @files; push @ARGV, '-o', $output_fn if defined $output_fn; run_cmd($cc, @ARGV); @@ -78,3 +95,13 @@ sub run_cmd { die "$argv[0] exitted due to signal @{[WTERMSIG($?)]}\n"; } } + +sub get_preprocessed_fn { + my $fn = shift; + $fn =~ /\.([^\.]+)$/s + or return; + my $ext = $1; + return + unless $EXT{$ext}; + return substr(sha1_hex($fn), 0, 12) . ".$EXT{$ext}"; +}