def prepare(self):
    # Shorthand for various objects
    config = self.config
    lib    = self.library
    
    # Parse the sources
    for fileName in config.get("apiheaders", []):
      Log.notice("Parsing functions from '%s'." % fileName)
      source = self.parserTool.readSource(fileName)
      newLib = Parser.parseSource(source)
      for f in newLib.functions.values():
        f.headerName = fileName
      for f in newLib.functions.values():
        Log.debug("%s %s(%s)" % (f.type, f.name, ", ".join(["%s %s" % (t.type, p) for p, t in f.parameters.items()])))
      if not newLib.functions:
        Log.warn("No new functions found.")
      else:
        Log.notice("%d functions found." % len(newLib.functions))
      lib.merge(newLib)

    # Load the hooks
    self.parserTool.loadHooks()

    def parseBool(s):
      return bool(int(s))

    # Read the typemap
    for typeDecl, mapping in self.config.types.items():
      attrs = self.config.types[typeDecl].attrs
      name, type = Parser.parseVariableDeclaration(typeDecl + " dummy")
      assert name == "dummy"
      # If this is a class mapping, create the class if it doesn't already exist
      if mapping == "object":
        if not mapping in self.library.classes:
          cls = Library.Class(type)
          if "namespace" in attrs:
            cls.namespacePath = attrs["namespace"].split(".")
          self.library.classes[type] = cls
      # Patch the default decoration hint into all matching types
      if "decorationhint" in attrs:
          for function in self.library.functions.values():
              for t in [p.type for p in function.parameters.values()] + [function.type]:
                  if t == type:
                      t.decorationHint = attrs["decorationhint"]
      self.library.typeMap[type] = str(mapping)

    # Patch in some function-specific attributes
    for function in config.functions.keys():
      if not function in lib.functions:
        self.fail("Attributes specified for non-existent function '%s'." % function)
      attrs = config.functions[function].attrs
      if "terminator" in attrs:
        lib.functions[function].isTerminator         = parseBool(attrs["terminator"])
      if "generate" in attrs:
        lib.functions[function].generate             = parseBool(attrs["generate"])
      if "runtimestate" in attrs:
        lib.functions[function].runtimeStateTracking = parseBool(attrs["runtimestate"])
      if "framemarker" in attrs:
        lib.functions[function].isFrameMarker        = parseBool(attrs["framemarker"])
      if "staticlinkage" in attrs:
        lib.functions[function].staticLinkage        = parseBool(attrs["staticlinkage"])
      if "rendercall" in attrs:
        lib.functions[function].isRenderCall         = parseBool(attrs["rendercall"])
      if "passthrough" in attrs:
        lib.functions[function].passthrough          = parseBool(attrs["passthrough"])
        
      if not isinstance(config.functions[function], Config.Group):
        self.fail("Syntax error: State map definition for function '%s' is missing braces." % function)
        
      # Argument to state mapping
      reservedNames = ["@return", "@modify", "@set", "@get", "@copy"]
      funcAttrs = attrs
      for arg, parameter in config.functions[function].items():
        # Check that this is a valid parameter
        if not arg in reservedNames and not arg in lib.functions[function].parameters:
          self.fail("State mapping for nonexistent parameter '%s' of function '%s' specified." % (arg, function))

        if arg in ["@copy"] and parseBool(funcAttrs.get("runtimestate", "0")):
          Log.warn("Function %s state relation %s not implemented for runtime state tracking." % (function, arg))
          
        # Read the parameter-specific attributes
        attrs = config.functions[function][arg].attrs
        if "decoration" in attrs:
          lib.functions[function].parameters[arg].decoration     = attrs["decoration"]
        if "decorationhint" in attrs:
          lib.functions[function].parameters[arg].decorationHint = attrs["decorationhint"]
        if "out" in attrs:
          lib.functions[function].parameters[arg].isOut          = parseBool(attrs["out"])
        if "object_class" in attrs:
          # Create a function-local type so that this parameter type is an object only for this function
          if arg == "@return":
            type = lib.functions[function].type
          else:
            type = lib.functions[function].parameters[arg].type
          # Override the type's name so that it will refer to the new object class
          # while still using the original C type under the hood
          newType = copy.deepcopy(type)
          newType.isObject = True
          newType.name = attrs["object_class"]
          if arg == "@return":
            lib.functions[function].type = newType
          else:
            lib.functions[function].parameters[arg].type = newType
          # Check that this class exists
          classType = Library.Type(attrs["object_class"])
          if not classType in self.library.classes:
            self.fail("Undefined object class '%s'." % classType)
          
        # Do we have a meta type?
        if "metatype" in config.functions[function][arg]:
          metaGroup = config.functions[function][arg].metatype
          
          try:
            metaType = Library.MetaType(metaGroup.attrs["class"])
          except KeyError:
            self.fail("Meta type for parameter '%s' does not define class." % arg)
            
          # Is this an array parameter?
          if metaType.name == "array":
            metaType.values["size"]       = Library.MetaValue("size",       metaGroup.attrs.get("size", 1))
            if "type" in metaGroup.attrs:
              metaType.values["type"]     = Library.MetaValue("type",       metaGroup.attrs["type"])
              if metaGroup.attrs["type"] == "object":
                if not "object_class" in metaGroup.attrs:
                  self.fail("Required metatype attribute object_class missing")
                metaType.values["object_class"] = Library.MetaValue("object_class", metaGroup.attrs["object_class"])
          # How about an image parameter?
          elif metaType.name == "image":
            metaType.values["stride"]     = Library.MetaValue("stride",     metaGroup.attrs.get("stride", "width"))
            metaType.values["height"]     = Library.MetaValue("height",     metaGroup.attrs.get("height", "height"))
            metaType.values["components"] = Library.MetaValue("components", metaGroup.attrs.get("components", "1"))
            metaType.values["type"]       = Library.MetaValue("type",       metaGroup.attrs.get("type", "byte"))
          else:
            self.fail("Unknown meta type class '%s'." % metaclass)
          
          Log.debug("Meta type: %s.%s: %s" % (function, arg, metaType.name))
            
          # Get the conditions for different meta values
          if isinstance(metaGroup, Config.List):
            for item in metaGroup:
              predicate      = item.attrs["condition"]
              predicateValue = item.attrs["value"]
              result         = item.attrs["result"]
              metaType.values[item].addPredicate(predicate, predicateValue, result)
              Log.debug("Meta type condition: If %s is %s, then %s = %s" % (predicate, predicateValue, item, result))
          elif isinstance(metaGroup, Config.Group):
            Log.error("Meta type variations for parameter '%s' represented in a group instead of a list." % arg)
              
          # Record the meta type
          lib.functions[function].parameters[arg].metaType = metaType
        
        # Is this a short-hand state mapping?
        try:
          path = parameter.split(".")
        except __HOLE__:
          # Try the expanded form of a nested attribute set
          try:
            path = (config.functions[function][arg].state).split(".")
          except AttributeError:
            path = []

        # Check that we even have a state structure
        if path and not "state" in config:
          Log.warn("State structure not defined.")
          continue
            
        # Parse special state mapping relations
        relation   = None
        checkPaths = []
        if arg == "@copy":
          relation   = Library.StateRelationCopy(attrs["src"].split("."), attrs["dest"].split("."))
          checkPaths = [relation.sourcePath, relation.destPath]
        elif arg == "@get":
          relation   = Library.StateRelationGet(path)
          checkPaths = [relation.path]
        elif arg == "@set":
          relation   = Library.StateRelationSet(path)
          checkPaths = [relation.path]
        elif arg == "@modify":
          relation   = Library.StateRelationModify(path)
          checkPaths = [relation.path]
        # Empty mapping?
        elif not "".join(path):
          continue
          
        if relation:
          for path in checkPaths:
            if traverseStatePath(config, path) is None:
              self.fail("Relation state path '%s' for function '%s' does not exist." % (".".join(path), function))
          Log.debug("State relation: %s %s" % (function, relation))
          lib.functions[function].stateRelations.append(relation)
          continue
          
        Log.debug("State mapping: %s.%s -> %s" % (function, arg, ".".join(path)))

        # Determine the parameter type
        type = None

        if arg == "@return":
          type = lib.functions[function].type
        else:
          type = lib.functions[function].parameters[arg].type      

        # If this is a runtime mapping, check that the parameter is of a supported type
        if lib.functions[function].runtimeStateTracking and type and \
           lib.getNativeType(type) in ["float", "double"]:
          self.fail("Values of type '%s' can not be saved to the runtime state tree" % type)
          continue
          
        node = traverseStatePath(config, path)
        if node is None:
          self.fail("State path '%s' for function '%s' does not exist." % (".".join(path), function))
          
        # Save the mapping
        if arg == "@return":
          lib.functions[function].retStateRelation = Library.StateRelationSet(path)
        else:
          lib.functions[function].parameters[arg].stateRelation = Library.StateRelationSet(path)
dataset/ETHPy150Open skyostil/tracy/src/generator/Target.py/CodeTarget.prepare