1# Copyright 2004 David Abrahams 2# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus 3# Copyright 2010 Rene Rivera 4# Distributed under the Boost Software License, Version 1.0. 5# (See accompanying file LICENSE_1_0.txt or copy at 6# http://www.boost.org/LICENSE_1_0.txt) 7 8import scanner ; 9import type ; 10 11 12class c-scanner : scanner 13{ 14 import path ; 15 import regex ; 16 import scanner ; 17 import sequence ; 18 import toolset ; 19 import virtual-target ; 20 21 rule __init__ ( includes * ) 22 { 23 scanner.__init__ ; 24 25 # toolset.handle-flag-value is a bit of overkill, but it 26 # does correctly handle the topological sort of && separated 27 # include paths 28 self.includes = [ toolset.handle-flag-value <include> : $(includes) ] ; 29 } 30 31 rule pattern ( ) 32 { 33 return "#[ \t]*include[ \t]*(<(.*)>|\"(.*)\")" ; 34 } 35 36 rule process ( target : matches * : binding ) 37 { 38 local angle = [ regex.transform $(matches) : "<(.*)>" ] ; 39 angle = [ sequence.transform path.native : $(angle) ] ; 40 local quoted = [ regex.transform $(matches) : "\"(.*)\"" ] ; 41 quoted = [ sequence.transform path.native : $(quoted) ] ; 42 43 # CONSIDER: the new scoping rules seem to defeat "on target" variables. 44 local g = [ on $(target) return $(HDRGRIST) ] ; 45 local b = [ NORMALIZE_PATH $(binding:D) ] ; 46 47 # Attach binding of including file to included targets. When a target is 48 # directly created from a virtual target this extra information is 49 # unnecessary. But in other cases, it allows us to distinguish between 50 # two headers of the same name included from different places. We do not 51 # need this extra information for angle includes, since they should not 52 # depend on the including file (we can not get literal "." in the 53 # include path). 54 local g2 = $(g)"#"$(b) ; 55 56 angle = $(angle:G=$(g)) ; 57 quoted = $(quoted:G=$(g2)) ; 58 59 local all = $(angle) $(quoted) ; 60 61 INCLUDES $(target) : $(all) ; 62 NOCARE $(all) ; 63 SEARCH on $(angle) = $(self.includes:G=) ; 64 SEARCH on $(quoted) = $(b) $(self.includes:G=) ; 65 66 # Just propagate the current scanner to includes, in hope that includes 67 # do not change scanners. 68 scanner.propagate $(__name__) : $(all) : $(target) ; 69 70 ISFILE $(all) ; 71 } 72} 73 74scanner.register c-scanner : include ; 75 76type.register CPP : cpp cxx cc ; 77type.register H : h ; 78type.register HPP : hpp : H ; 79type.register C : c ; 80 81# It most cases where a CPP file or a H file is a source of some action, we 82# should rebuild the result if any of files included by CPP/H are changed. One 83# case when this is not needed is installation, which is handled specifically. 84type.set-scanner CPP : c-scanner ; 85type.set-scanner C : c-scanner ; 86# One case where scanning of H/HPP files is necessary is PCH generation -- if 87# any header included by HPP being precompiled changes, we need to recompile the 88# header. 89type.set-scanner H : c-scanner ; 90type.set-scanner HPP : c-scanner ; 91