1# 2# Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org> 3# Copyright (C) 2011 Google Inc. 4# 5# This library is free software; you can redistribute it and/or 6# modify it under the terms of the GNU Library General Public 7# License as published by the Free Software Foundation; either 8# version 2 of the License, or (at your option) any later version. 9# 10# This library is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# Library General Public License for more details. 14# 15# You should have received a copy of the GNU Library General Public License 16# along with this library; see the file COPYING.LIB. If not, write to 17# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18# Boston, MA 02110-1301, USA. 19# 20 21use strict; 22use warnings; 23 24use Config; 25use IPC::Open2; 26use IPC::Open3; 27 28BEGIN { 29 use Exporter (); 30 our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); 31 $VERSION = 1.00; 32 @ISA = qw(Exporter); 33 @EXPORT = qw(&applyPreprocessor); 34 %EXPORT_TAGS = ( ); 35 @EXPORT_OK = (); 36} 37 38# Returns an array of lines. 39sub applyPreprocessor 40{ 41 my $fileName = shift; 42 my $defines = shift; 43 my $preprocessor = shift; 44 45 my @args = (); 46 if (!$preprocessor) { 47 require Config; 48 if ($ENV{CC}) { 49 $preprocessor = $ENV{CC}; 50 } elsif (($Config::Config{'osname'}) =~ /solaris/i) { 51 $preprocessor = "/usr/sfw/bin/gcc"; 52 } elsif (-x "/usr/bin/clang") { 53 $preprocessor = "/usr/bin/clang"; 54 } else { 55 $preprocessor = "/usr/bin/gcc"; 56 } 57 push(@args, qw(-E -P -x c++)); 58 } 59 60 # Remove double quotations from $defines and extract macros. 61 # For example, if $defines is ' "A=1" "B=1" C=1 "" D ', 62 # then it is converted into four macros -DA=1, -DB=1, -DC=1 and -DD. 63 $defines =~ s/\"//g; 64 my @macros = grep { $_ } split(/\s+/, $defines); # grep skips empty macros. 65 @macros = map { "-D$_" } @macros; 66 67 my $pid = 0; 68 if ($Config{osname} eq "cygwin" || $Config{osname} eq 'MSWin32') { 69 # This call can fail if Windows rebases cygwin, so retry a few times until it succeeds. 70 for (my $tries = 0; !$pid && ($tries < 20); $tries++) { 71 eval { 72 # Suppress STDERR so that if we're using cl.exe, the output 73 # name isn't needlessly echoed. 74 use Symbol 'gensym'; my $err = gensym; 75 $pid = open3(\*PP_IN, \*PP_OUT, $err, split(' ', $preprocessor), @args, @macros, $fileName); 76 1; 77 } or do { 78 sleep 1; 79 } 80 }; 81 } else { 82 $pid = open2(\*PP_OUT, \*PP_IN, split(' ', $preprocessor), @args, @macros, $fileName); 83 } 84 close PP_IN; 85 my @documentContent = <PP_OUT>; 86 close PP_OUT; 87 waitpid($pid, 0); 88 return @documentContent; 89} 90 911; 92