# Status: ported.
# Base revision: 45462
# 
# 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 property
import bjam
from b2.exceptions import *
from b2.manager import get_manager

def reset ():
    """ Clear the module state. This is mainly for testing purposes.
    """
    global __scanners, __rv_cache, __scanner_cache

    # Maps registered scanner classes to relevant properties
    __scanners = {}
    
    # A cache of scanners.
    # The key is: class_name.properties_tag, where properties_tag is the concatenation 
    # of all relevant properties, separated by '-'
    __scanner_cache = {}
    
reset ()


def register(scanner_class, relevant_properties):
    """ 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.
    """
    __scanners[str(scanner_class)] = relevant_properties

def registered(scanner_class):
    """ Returns true iff a scanner of that class is registered
    """
    return __scanners.has_key(str(scanner_class))
    
def get(scanner_class, properties):
    """ Returns an instance of previously registered scanner
        with the specified properties.
    """
    scanner_name = str(scanner_class)
    
    if not registered(scanner_name):
        raise BaseException ("attempt to get unregisted scanner: %s" % scanner_name)

    relevant_properties = __scanners[scanner_name]
    r = property.select(relevant_properties, properties)

    scanner_id = scanner_name + '.' + '-'.join(r)
    
    if not __scanner_cache.has_key(scanner_name):
        __scanner_cache[scanner_name] = scanner_class(r)

    return __scanner_cache[scanner_name]

class Scanner:
    """ Base scanner class.
    """
    def __init__ (self):
        pass
    
    def pattern (self):
        """ Returns a pattern to use for scanning.
        """
        raise BaseException ("method must be overriden")

    def process (self, target, matches):
        """ Establish necessary relationship between targets,
            given actual target beeing scanned, and a list of
            pattern matches in that file.
        """
        raise BaseException ("method must be overriden")


# Common scanner class, which can be used when there's only one
# kind of includes (unlike C, where "" and <> includes have different
# search paths).
def CommonScanner(Scanner):

    def __init__ (self, includes):
        Scanner.__init__(self)
        self.includes = includes

    def process(self, target, matches, binding):

        target_path = os.path.normpath(os.path.dirname(binding[0]))
        bjam.call("mark-included", target, matches)

        engine.set_target_variable(matches, "SEARCH",
                                   [target_path] + self.includes_)
        get_manager().scanners().propagate(self, matches)

class ScannerRegistry:
    
    def __init__ (self, manager):
        self.manager_ = manager
        self.count_ = 0
        self.exported_scanners_ = {}

    def install (self, scanner, target, vtarget):
        """ Installs the specified scanner on actual target 'target'. 
            vtarget: virtual target from which 'target' was actualized.
        """
        engine = self.manager_.engine()
        engine.set_target_variable(target, "HDRSCAN", scanner.pattern())
        if not self.exported_scanners_.has_key(scanner):
            exported_name = "scanner_" + str(self.count_)
            self.count_ = self.count_ + 1
            self.exported_scanners_[scanner] = exported_name
            bjam.import_rule("", exported_name, scanner.process)
        else:
            exported_name = self.exported_scanners_[scanner]

        engine.set_target_variable(target, "HDRRULE", exported_name)
        
        # 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.
        engine.set_target_variable(target, "HDRGRIST", str(id(scanner)))
        pass

    def propagate(self, scanner, targets):
        engine = self.manager_.engine()
        engine.set_target_variable(targets, "HDRSCAN", scanner.pattern())
        engine.set_target_variable(targets, "HDRRULE",
                                   self.exported_scanners_[scanner])
        engine.set_target_variable(targets, "HDRGRIST", str(id(scanner)))

