diff options
Diffstat (limited to 'jam-files/boost-build/build/scanner.jam')
-rw-r--r-- | jam-files/boost-build/build/scanner.jam | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/jam-files/boost-build/build/scanner.jam b/jam-files/boost-build/build/scanner.jam new file mode 100644 index 000000000..d6042ea2c --- /dev/null +++ b/jam-files/boost-build/build/scanner.jam @@ -0,0 +1,153 @@ +# Copyright 2003 Dave Abrahams +# Copyright 2002, 2003, 2004, 2005 Vladimir Prus +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +# Implements scanners: objects that compute implicit dependencies for +# files, such as includes in C++. +# +# Scanner has a regular expression used to find dependencies, some +# data needed to interpret those dependencies (for example, include +# paths), and a code which actually established needed relationship +# between actual jam targets. +# +# Scanner objects are created by actions, when they try to actualize +# virtual targets, passed to 'virtual-target.actualize' method and are +# then associated with actual targets. It is possible to use +# several scanners for a virtual-target. For example, a single source +# might be used by to compile actions, with different include paths. +# In this case, two different actual targets will be created, each +# having scanner of its own. +# +# Typically, scanners are created from target type and action's +# properties, using the rule 'get' in this module. Directly creating +# scanners is not recommended, because it might create many equvivalent +# but different instances, and lead in unneeded duplication of +# actual targets. However, actions can also create scanners in a special +# way, instead of relying on just target type. + +import "class" : new ; +import property virtual-target property-set ; +import errors : error ; + +# Base scanner class. +class scanner +{ + rule __init__ ( ) + { + } + + # Returns a pattern to use for scanning + rule pattern ( ) + { + error "method must be overriden" ; + } + + # Establish necessary relationship between targets, + # given actual target beeing scanned, and a list of + # pattern matches in that file. + rule process ( target : matches * ) + { + error "method must be overriden" ; + } +} + +# Registers a new generator class, specifying a set of +# properties relevant to this scanner. Ctor for that class +# should have one parameter: list of properties. +rule register ( scanner-class : relevant-properties * ) +{ + .registered += $(scanner-class) ; + .relevant-properties.$(scanner-class) = $(relevant-properties) ; +} + +# Common scanner class, which can be used when there's only one +# kind of includes (unlike C, where "" and <> includes have different +# search paths). +class common-scanner : scanner +{ + import scanner ; + rule __init__ ( includes * ) + { + scanner.__init__ ; + self.includes = $(includes) ; + } + + rule process ( target : matches * : binding ) + { + local target_path = [ NORMALIZE_PATH $(binding:D) ] ; + + NOCARE $(matches) ; + INCLUDES $(target) : $(matches) ; + SEARCH on $(matches) = $(target_path) $(self.includes:G=) ; + ISFILE $(matches) ; + + scanner.propagate $(__name__) : $(matches) : $(target) ; + } +} + + +# Returns an instance of previously registered scanner, +# with the specified properties. +rule get ( scanner-class : property-set ) +{ + if ! $(scanner-class) in $(.registered) + { + error "attempt to get unregisted scanner" ; + } + + local r = $(.rv-cache.$(property-set)) ; + if ! $(r) + { + r = [ property-set.create + [ property.select $(.relevant-properties.$(scanner-class)) : + [ $(property-set).raw ] ] ] ; + .rv-cache.$(property-set) = $(r) ; + } + + if ! $(scanner.$(scanner-class).$(r:J=-)) + { + scanner.$(scanner-class).$(r:J=-) = [ new $(scanner-class) [ $(r).raw ] ] ; + } + return $(scanner.$(scanner-class).$(r:J=-)) ; +} + + +# Installs the specified scanner on actual target 'target'. +rule install ( scanner : target + vtarget # virtual target from which 'target' was actualized +) +{ + HDRSCAN on $(target) = [ $(scanner).pattern ] ; + SCANNER on $(target) = $(scanner) ; + HDRRULE on $(target) = scanner.hdrrule ; + + # scanner reflects difference in properties affecting + # binding of 'target', which will be known when processing + # includes for it, will give information on how to + # interpret quoted includes. + HDRGRIST on $(target) = $(scanner) ; +} + +# Propagate scanner setting from 'including-target' to 'targets'. +rule propagate ( scanner : targets * : including-target ) +{ + HDRSCAN on $(targets) = [ on $(including-target) return $(HDRSCAN) ] ; + SCANNER on $(targets) = $(scanner) ; + HDRRULE on $(targets) = scanner.hdrrule ; + HDRGRIST on $(targets) = [ on $(including-target) return $(HDRGRIST) ] ; +} + + +rule hdrrule ( target : matches * : binding ) +{ + local scanner = [ on $(target) return $(SCANNER) ] ; + $(scanner).process $(target) : $(matches) : $(binding) ; +} +# hdrrule must be available at global scope so that it can be invoked +# by header scanning +IMPORT scanner : hdrrule : : scanner.hdrrule ; + + + + |