Exemple #1
0
 def loadHooks(self):
   target   = self.target
   config   = self.target.config
   lib      = self.target.library
   platform = self.target.project.platform
   
   # Collect hooks in various locations
   for fileName in config.get("hooks", []):
     Log.notice("Parsing hooks from '%s'." % fileName)
     source = self.readSource(fileName)
     functions = Parser.parseSource(source).functions.values()
     if not functions:
       Log.warn("No hooks found.")
     for f in functions:
       Log.debug("%s %s(%s)" % (f.type, f.name, ", ".join(["%s %s" % (t.type, p) for p, t in f.parameters.items()])))
     for function in functions:
       if not function.body:
         Log.warn("Hook function '%s' has no body." % function.name)
         continue
       if function.name.startswith("@"):
         lib.hooks[function.name] = function.body
         continue
       else:
         try:
           name, hookName = function.name.split(".", 1)
           if not name in lib.functions:
             target.fail("Function '%s' referred by hook function '%s' does not exist." % (name, function.name))
           if not hookName.startswith("@") and not hookName in lib.functions[name].parameters:
             target.fail("Parameter '%s' referred by hook function '%s' does not exist." % (hookName, function.name))
           lib.functions[name].hooks[hookName] = function.body
         except ValueError:
           target.fail("Hook function name '%s' is not valid." % function.name)
Exemple #2
0
  def validate(self):
    lib = self.library

    # Validate the target
    for function in lib.functions.values():
      if function.ordinal is None and function.staticLinkage and self.project.platform.requireOrdinals:
        Log.warn("Function '%s' does not have a valid ordinal." % function.name)
Exemple #3
0
 def readEvents(self):
   tokenHandlers = {
     DefineToken:      self._handleDefineToken,
     EventToken:       self._handleEventToken,
     ValueToken:       self._handleValueToken,
     DurationToken:    self._handleDurationToken,
     ApiToken:         self._handleApiToken,
     BeginObjectToken: self._handleBeginObjectToken,
     EndObjectToken:   self._handleEndObjectToken,
   }
   
   while 1:
     try:
       token = Token.read(self.file)
     except ValueError, e:
       Log.warn("Error reading token: %s" % e)
       continue
     
     if not token:
       break
   
     try:
       event = tokenHandlers[token.__class__](token)
     except Exception, e:
       Log.warn("Error decoding token %s: %s" % (token.__class__.__name__, e))
       continue
Exemple #4
0
  def __init__(self, project, options):
    Analyzer.__init__(self, project)
    self.commands             = {}
    self.commandHelp          = {}
    self.options              = options
    self.parser               = ScriptParser()
    self.done                 = False
    self.colorizer            = Console.colorizer
    self.taskMonitor          = Task.RateLimitedTaskMonitor(self)
    self.profiling            = False
    self.plugins              = []
    self.traceFiles           = {}
    self.customSyntaxCommands = set()
    
    if not self.project.targets:
      Log.warn("Using empty project file.")
      
    if not self.projectHasApiDescription():
      Log.warn("Project file does not contain an API description.")
  
    # Register internal commands  
    self.registerCommand("quit", self.quit)

    # Start receiving task notifications
    Task.setMonitor(self.taskMonitor)

    # Load all plugins
    self._loadPlugins()
Exemple #5
0
 def readEvents(self):
   tokenHandlers = {
     DefineToken:      self._handleDefineToken,
     EventToken:       self._handleEventToken,
     ValueToken:       self._handleValueToken,
     DurationToken:    self._handleDurationToken,
     ApiToken:         self._handleApiToken,
     BeginObjectToken: self._handleBeginObjectToken,
     EndObjectToken:   self._handleEndObjectToken,
   }
   
   while 1:
     try:
       token = Token.read(self.file)
     except ValueError, e:
       Log.warn("Error reading token: %s" % e)
       break
     
     if not token:
       break
       
     event = tokenHandlers[token.__class__](token)
     
     if event:
       yield event
Exemple #6
0
    def readEvents(self):
        tokenHandlers = {
            DefineToken: self._handleDefineToken,
            EventToken: self._handleEventToken,
            ValueToken: self._handleValueToken,
            DurationToken: self._handleDurationToken,
            ApiToken: self._handleApiToken,
            BeginObjectToken: self._handleBeginObjectToken,
            EndObjectToken: self._handleEndObjectToken,
        }

        while 1:
            try:
                token = Token.read(self.file)
            except ValueError, e:
                Log.warn("Error reading token: %s" % e)
                break

            if not token:
                break

            event = tokenHandlers[token.__class__](token)

            if event:
                yield event
Exemple #7
0
def parseConfig(config, template = None):
  """
  Parses the given tracer configuration and returns a tree of configuration
  symbols.
      
  @param config     Config file text
  @param template   Optional configuration to use a template.
  
  @return: A dictionary tree of configuration values
  """
  if not template:
    template = Config.Config()
  items = template

  for itemName, item in configFile.parseString(config):
    if not item:
      Log.warn("Empty top-level item '%s'." % itemName)
    if itemName in items and isinstance(item, Config.Group):
      items[itemName].update(item)
    elif itemName in items and isinstance(item, Config.List):
      items[itemName] += item
    else:
      items[itemName] = item

  return items
Exemple #8
0
 def generate(self, projectName, targetPath):
   tempPath = tempfile.mkdtemp()
   try:
     # Create a build
     build = self.project.platform.createBuild(self.config, self.library, projectName, self.name)
     
     # If there is at least one C++ function, generate only C++ code
     if "c++" in self.getLanguages() or self.config.get("language", "c") == "c++":
       playerSourceName       = "player_gen.cpp"
     else:
       playerSourceName       = "player_gen.c"
       self.library.language  = "c"
     
     # Generate the player
     playerSourcePath = os.path.join(tempPath, playerSourceName)
     g = Generator.CSourcePlayerGenerator(self.config, self.project.platform, [self.library],
                                          templatePath = Resource.getPath("templates"))
     output = open(playerSourcePath, "w")
     g.generate(outputFile = output)
     output.close()
 
     # Add the generated source file to the configuration
     self.addSourceFile(playerSourcePath)
     
     # Finalize the build
     build.compile(targetPath = targetPath)
   finally:
     try:
       shutil.rmtree(tempPath)
     except:
       Log.warn("Unable to clean up temporary directory '%s'" % tempPath)
Exemple #9
0
def parseConfig(config, template=None):
    """
  Parses the given tracer configuration and returns a tree of configuration
  symbols.
      
  @param config     Config file text
  @param template   Optional configuration to use a template.
  
  @return: A dictionary tree of configuration values
  """
    if not template:
        template = Config.Config()
    items = template

    for itemName, item in configFile.parseString(config):
        if not item:
            Log.warn("Empty top-level item '%s'." % itemName)
        if itemName in items and isinstance(item, Config.Group):
            items[itemName].update(item)
        elif itemName in items and isinstance(item, Config.List):
            items[itemName] += item
        else:
            items[itemName] = item

    return items
Exemple #10
0
    def validate(self):
        lib = self.library

        # Validate the target
        for function in lib.functions.values():
            if function.ordinal is None and function.staticLinkage and self.project.platform.requireOrdinals:
                Log.warn("Function '%s' does not have a valid ordinal." %
                         function.name)
Exemple #11
0
  def validate(self):
    lib = self.library

    # Validate the target
    for function in lib.functions.values():
      if function.ordinal is None and function.staticLinkage and self.project.platform.requireOrdinals:
        Log.warn("Function '%s' does not have a valid ordinal." % function.name)
      for parameter in function.parameters.values():
        if lib.getNativeType(parameter.type) == "pointer" \
           and not parameter.name in lib.functions[function.name].hooks \
           and not parameter.metaType \
           and lib.functions[function.name].generate:
          Log.warn("Saving naked pointer '%s' of type '%s' in function '%s'." % (parameter.name, parameter.type, function.name))
Exemple #12
0
def getPath(*name, **args):
    """
  Get a path to an existing resource.
  
  @param *name      Resource path segments
  @param required   If True, a warning is logged if the resource is not found.
  """
    for path in paths:
        p = os.path.join(path, *name)
        if os.path.exists(p):
            return p
    if args.get("required", True) == True:
        Log.warn("Resource '%s' not found." % os.sep.join(name))
Exemple #13
0
def getPath(*name, **args):
  """
  Get a path to an existing resource.
  
  @param *name      Resource path segments
  @param required   If True, a warning is logged if the resource is not found.
  """
  for path in paths:
    p = os.path.join(path, *name)
    if os.path.exists(p):
      return p
  if args.get("required", True) == True:
    Log.warn("Resource '%s' not found." % os.sep.join(name))
Exemple #14
0
  def load(self):
    # Determine the trace file size
    try:
      self.file.seek(0, 2)
      fileSize = self.file.tell()
      self.file.seek(0)
    except:
      fileSize = 0
    
    task = Task.startTask("load", "Loading trace", steps = fileSize)

    # Read and verify version magic
    version = self.file.read(4)
    if version != FORMAT_VERSION:
      raise RuntimeError("Unsupported file format version: %s (%s)" % (version, binascii.hexlify(version)))

    # First pass: read all the events
    for i, event in enumerate(self.readEvents()):
      self.trace.events.append(event)
      if fileSize:
        task.updateProgress(self.file.tell())
      elif (i & 0xff) == 0:
        task.step()

    task.finish()
    task = Task.startTask("resolve", "Resolving data", len(self.trace.events))
      
    # Second pass: resolve any unknown phrases
    for event in self.trace.events:
      if isinstance(event.name, Trace.UnknownPhrase):
        Log.warn("Event %d name is undefined, trace is probably corrupted." % event.seq)
        self.trace.events.remove(event)
        continue

      for key, value in event.values.items():
        if isinstance(key, Trace.UnknownPhrase):
          Log.warn("Event %d parameter name is undefined, trace is probably corrupted." % event.seq)
          self.trace.events.remove(event)
          continue

        if isinstance(value, Trace.UnknownPhrase):
          v2 = value
          value = self.decoder.getPhrase(value.id)
          if isinstance(value, Trace.UnknownPhrase):
            #Log.warn("Unable to resolve unknown phrase %s.%s = %s." % (event.name, key, value))
            pass
          else:
            event.values[key] = value
            if not value in event.modifiedArrays:
              event.modifiedArrays.append(value)
      task.step()
Exemple #15
0
 def getNativeType(self, library, type):
   """
   Get the native equivalent of a Type instance.
   
   @param library:   Library from which the type is searched
   @param type:      Type instance to convert to native type
   @returns the name of the matching native type or None
   """
   t = library.getNativeType(type)
   
   if not t:
     Log.warn("Type '%s' has no mapping to a native equivalent; defaulting to 'int'." % type.declaration)
     t = "int"
   return t
Exemple #16
0
 def setPhrase(self, id, data):
   # Check that this definition is really necessary
   if verbose and name in self.phrasebook:
     oldData = self.phrasebook[name]
     if data == oldData:
       Log.warn("%d bytes of redundant phrase data for phrase 0x%x" % (len(data), name))
     elif len(oldData) < len(data):
       for v1, v2 in zip(oldData, data):
         if v1 != v2:
           break
       else:
         Log.warn("%d bytes of partially redundant phrase data for phrase 0x%x" % (len(data), name))
     
   self.phrasebook[id] = data
Exemple #17
0
    def validate(self):
        lib = self.library

        # Validate the target
        for function in lib.functions.values():
            if function.ordinal is None and function.staticLinkage and self.project.platform.requireOrdinals:
                Log.warn("Function '%s' does not have a valid ordinal." %
                         function.name)
            for parameter in function.parameters.values():
                if lib.getNativeType(parameter.type) == "pointer" \
                   and not parameter.name in lib.functions[function.name].hooks \
                   and not parameter.metaType \
                   and lib.functions[function.name].generate:
                    Log.warn(
                        "Saving naked pointer '%s' of type '%s' in function '%s'."
                        % (parameter.name, parameter.type, function.name))
Exemple #18
0
    def getNativeType(self, library, type):
        """
    Get the native equivalent of a Type instance.
    
    @param library:   Library from which the type is searched
    @param type:      Type instance to convert to native type
    @returns the name of the matching native type or None
    """
        t = library.getNativeType(type)

        if not t:
            Log.warn(
                "Type '%s' has no mapping to a native equivalent; defaulting to 'int'."
                % type.declaration)
            t = "int"
        return t
Exemple #19
0
 def image_upload(cls, file, width=0, height=0, thumbnail=False):
     if not cls.allowed_file(file.filename):
         Log.warn("Filename's suffix was not allowed.")
         raise Exception("Filename's suffix was not allowed.")
     if file:
         filename, url = cls.generate_image_path_info(file.filename)
         file.save(filename)
         pillow_image = PillowImage.open(filename).convert('RGB')
         if width != 0 and height != 0:
             if width != pillow_image.width or height != pillow_image.height:
                 Log.warn("Invalid image size.")
                 os.remove(filename)
                 raise Exception('Invalid image size.')
         if pillow_image:
             if thumbnail:
                 # 生成缩略图
                 if pillow_image.height > pillow_image.width:
                     # 竖图
                     pos = (pillow_image.height - pillow_image.width) // 2
                     crop_image = pillow_image.crop(
                         (0, pos, pillow_image.width,
                          pillow_image.height - pos))
                     thumb_img = crop_image.resize(
                         (current_app.config['APP']['thumb_height'],
                          current_app.config['APP']['thumb_width']),
                         PillowImage.ANTIALIAS)
                 elif pillow_image.height < pillow_image.width:
                     # 横图
                     pos = (pillow_image.width - pillow_image.height) // 2
                     crop_image = pillow_image.crop(
                         (pos, 0, pillow_image.width - pos,
                          pillow_image.height))
                     thumb_img = crop_image.resize(
                         (current_app.config['APP']['thumb_height'],
                          current_app.config['APP']['thumb_width']),
                         PillowImage.ANTIALIAS)
                 else:
                     thumb_img = pillow_image.resize(
                         (current_app.config['APP']['thumb_height'],
                          current_app.config['APP']['thumb_width']),
                         PillowImage.ANTIALIAS)
                 thumb_img.save(filename + '_thumb.jpg',
                                format='jpeg',
                                quality=80)
             image = Image(filename=filename,
                           url=url,
                           size=op.getsize(filename),
                           height=pillow_image.height,
                           width=pillow_image.width).save()
             Log.info('Success upload file: {}.'.format(filename))
             return image
         else:
             Log.warn('Can not open image file.')
             raise Exception('Can not open image file.')
     else:
         Log.warn('Invalid file data.')
         raise Exception('Invalid file data.')
Exemple #20
0
    def setPhrase(self, id, type, data):
        newData = self._decodeValueArray(id, type, data)

        # Check that this definition is really necessary
        if verbose and name in self.phrasebook:
            oldData = self.phrasebook[name]
            if newData == oldData:
                Log.warn("%d bytes of redundant phrase data for phrase 0x%x" %
                         (len(data), name))
            elif len(oldData) < len(newData):
                for v1, v2 in zip(oldData, newData):
                    if v1 != v2:
                        break
                else:
                    Log.warn(
                        "%d bytes of partially redundant phrase data for phrase 0x%x"
                        % (len(data), name))

        self.phrasebook[id] = newData
Exemple #21
0
    def loadHooks(self):
        target = self.target
        config = self.target.config
        lib = self.target.library
        platform = self.target.project.platform

        # Collect hooks in various locations
        for fileName in config.get("hooks", []):
            Log.notice("Parsing hooks from '%s'." % fileName)
            source = self.readSource(fileName)
            functions = Parser.parseSource(source).functions.values()
            if not functions:
                Log.warn("No hooks found.")
            for f in functions:
                Log.debug("%s %s(%s)" % (f.type, f.name, ", ".join(
                    ["%s %s" % (t.type, p) for p, t in f.parameters.items()])))
            for function in functions:
                if not function.body:
                    Log.warn("Hook function '%s' has no body." % function.name)
                    continue
                if function.name.startswith("@"):
                    lib.hooks[function.name] = function.body
                    continue
                else:
                    try:
                        name, hookName = function.name.split(".", 1)
                        if not name in lib.functions:
                            target.fail(
                                "Function '%s' referred by hook function '%s' does not exist."
                                % (name, function.name))
                        if not hookName.startswith(
                                "@"
                        ) and not hookName in lib.functions[name].parameters:
                            target.fail(
                                "Parameter '%s' referred by hook function '%s' does not exist."
                                % (hookName, function.name))
                        lib.functions[name].hooks[hookName] = function.body
                    except ValueError:
                        target.fail("Hook function name '%s' is not valid." %
                                    function.name)
Exemple #22
0
    def generate(self, projectName, targetPath):
        tempPath = tempfile.mkdtemp()
        try:
            # Create a build
            build = self.project.platform.createBuild(self.config,
                                                      self.library,
                                                      projectName, self.name)

            # If there is at least one C++ function, generate only C++ code
            if "c++" in self.getLanguages() or self.config.get(
                    "language", "c") == "c++":
                playerSourceName = "player_gen.cpp"
            else:
                playerSourceName = "player_gen.c"
                self.library.language = "c"

            # Generate the player
            playerSourcePath = os.path.join(tempPath, playerSourceName)
            g = Generator.CSourcePlayerGenerator(
                self.config,
                self.project.platform, [self.library],
                templatePath=Resource.getPath("templates"))
            output = open(playerSourcePath, "w")
            g.generate(outputFile=output)
            output.close()

            # Add the generated source file to the configuration
            self.addSourceFile(playerSourcePath)

            # Finalize the build
            build.compile(targetPath=targetPath)
        finally:
            try:
                shutil.rmtree(tempPath)
            except:
                Log.warn("Unable to clean up temporary directory '%s'" %
                         tempPath)
Exemple #23
0
 def reportWarning(self, msg):
   for line in str(msg).rstrip().split("\n"):
     Log.warn(line)
Exemple #24
0
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import Common
from common import Log

# Try to import matplotlib for charting
try:
    import matplotlib
    matplotlib.use("Agg")
    import pylab
except ImportError, e:
    matplotlib = None
    pylab = None
    Log.warn(
        "Matplotlib or one of it's dependencies not found (%s). Charts will not be generated."
        % e)


def slicePlot(x, y, sliceLength=100, style="line", *args, **kwargs):
    assert len(x) == len(y)

    if style == "line":
        plotFunc = pylab.plot
    elif style == "bar":
        plotFunc = pylab.bar
    else:
        raise RuntimeError("Unknown plotting style: %s" % style)

    if len(x) < sliceLength:
        plotFunc(x, y, *args, **kwargs)
Exemple #25
0
  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 AttributeError:
          # 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)
Exemple #26
0
    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 AttributeError:
                    # 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)
Exemple #27
0
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import Common
from common import Log

# Try to import matplotlib for charting
try:
  import matplotlib
  matplotlib.use("Agg")
  import pylab
except ImportError, e:
  matplotlib = None
  pylab      = None
  Log.warn("Matplotlib or one of it's dependencies not found (%s). Charts will not be generated." % e)
  
def slicePlot(x, y, sliceLength = 100, style = "line", *args, **kwargs):
  assert len(x) == len(y)
  
  if style == "line":
    plotFunc = pylab.plot
  elif style == "bar":
    plotFunc = pylab.bar
  else:
    raise RuntimeError("Unknown plotting style: %s" % style)
  
  if len(x) < sliceLength:
    plotFunc(x, y, *args, **kwargs)
    return