Package pygccxml :: Package utils |

# Source Code for Package pygccxml.utils

      1  # Copyright 2004-2008 Roman Yakovenko.
      2  # Distributed under the Boost Software License, Version 1.0. (See
      3  # accompanying file LICENSE_1_0.txt or copy at
      4  # http://www.boost.org/LICENSE_1_0.txt)
      5
      6  """
      7  defines logger classes and few convinience methods, not related to the declarations
      8  tree
      9  """
     10
     11  import os
     12  import sys
     13  import logging
     14  import tempfile
     15  from fs_utils import files_walker
     16  from fs_utils import directories_walker
     17
     18 -def _create_logger_( name ):
     19      """implementation details"""
     20      logger = logging.getLogger(name)
     21      handler = logging.StreamHandler()
     22      #handler.setFormatter( logging.Formatter( os.linesep + '%(levelname)s %(message)s' ) )
     23      handler.setFormatter( logging.Formatter( '%(levelname)s %(message)s' ) )
     24      logger.addHandler(handler)
     25      logger.setLevel(logging.INFO)
     26      return logger
     27
     28 -class loggers:
     29      """class-namespace, defines few loggers classes, used in the project"""
     30
     31      cxx_parser = _create_logger_( 'pygccxml.cxx_parser' )
     32      """logger for C++ parser functionality
     33
     34      If you set this logger level to DEBUG, you will be able to see the exact
     35      command line, used to invoke GCC-XML  and errors that occures during XML parsing
     36      """
     37
     38      gccxml = cxx_parser #backward compatability
     39
     40      pdb_reader = _create_logger_( 'pygccxml.pdb_reader' )
     41      """logger for MS .pdb file reader functionality
     42      """
     43
     44
     45      queries_engine = _create_logger_( 'pygccxml.queries_engine' )
     46      """logger for query engine functionality.
     47
     48      If you set this logger level to DEBUG, you will be able to see what queries
     49      you do against declarations tree, measure performance and may be even to improve it.
     50      Query engine reports queries and whether they are optimized or not.
     51      """
     52
     53      declarations_cache = _create_logger_( 'pygccxml.declarations_cache' )
     54      """logger for declarations tree cache functionality
     55
     56      If you set this logger level to DEBUG, you will be able to see what is exactly
     57      happens, when you read the declarations from cache file. You will be able to
     58      decide, whether it worse for you to use this or that cache strategy.
     59      """
     60
     61      root = logging.getLogger( 'pygccxml' )
     62      """root logger exists for your convinience only"""
     63
     64      all = [ root, cxx_parser, queries_engine, declarations_cache, pdb_reader ]
     65      """contains all logger classes, defined by the class"""
     66
     67 -def remove_file_no_raise(file_name ):
     68      """removes file from disk, if exception is raised, it silently ignores it"""
     69      try:
     70          if os.path.exists(file_name):
     71              os.remove( file_name )
     72      except Exception, error:
     73          loggers.root.error( "Error ocured while removing temprorary created file('%s'): %s"
     74                              % ( file_name, str( error ) ) )
     75
     76 -def create_temp_file_name(suffix, prefix=None, dir=None):
     77      """small convinience function that creates temporal file.
     78
     79      This function is a wrapper aroung Python built-in function - tempfile.mkstemp
     80      """
     81      if not prefix:
     82          prefix = tempfile.template
     83      fd, name = tempfile.mkstemp( suffix=suffix, prefix=prefix, dir=dir )
     84      file_obj = os.fdopen( fd )
     85      file_obj.close()
     86      return name
     87
     88 -def normalize_path( some_path ):
     89      """return os.path.normpath( os.path.normcase( some_path ) )"""
     90      return os.path.normpath( os.path.normcase( some_path ) )
     91
     92 -def get_architecture():
     93      """returns computer architecture: 32 or 64.
     94
     95      The guess is based on maxint.
     96      """
     97      if sys.maxint == 2147483647:
     98          return 32
     99      elif sys.maxint == 9223372036854775807:
    100          return 64
    101      else:
    102          raise RuntimeError( "Unknown architecture" )
    103
    104
    105  #The following code is cut-and-paste from this post:
    106  #http://groups.google.com/group/comp.lang.python/browse_thread/thread/5b71896c06bd0f76/
    107  #Thanks to Michele Simionato, for it
    108 -class cached(property):
    109      'Convert a method into a cached attribute'
    110 -    def __init__(self, method):
    111          private = '_' + method.__name__
    112          def fget(s):
    113              try:
    114                  return getattr(s, private)
    115              except AttributeError:
    116                  value = method(s)
    117                  setattr(s, private, value)
    118                  return value
    119          def fdel(s):
    120              del s.__dict__[private]
    121          super(cached, self).__init__(fget, fdel=fdel)
    122
    123      @staticmethod
    124 -    def reset(self):
    125          cls = self.__class__
    126          for name in dir(cls):
    127              attr = getattr(cls, name)
    128              if isinstance(attr, cached):
    129                  delattr(self, name)
    130
    131 -class enum( object ):
    132      """Usage example:
    133          class fruits(enum):
    134              apple = 0
    135              orange = 1
    136
    137          fruits.has_value( 1 )
    138          fruits.name_of( 1 )
    139      """
    140
    141      @classmethod
    142 -    def has_value( cls, enum_numeric_value ):
    143          for name, value in cls.__dict__.iteritems():
    144              if enum_numeric_value == value:
    145                  return True
    146          else:
    147              return False
    148
    149      @classmethod
    150 -    def name_of( cls, enum_numeric_value ):
    151          for name, value in cls.__dict__.iteritems():
    152              if enum_numeric_value == value:
    153                  return name
    154          else:
    155              raise RuntimeError( 'Unable to find name for value(%d) in enumeration "%s"'
    156                                  % ( enum_numeric_value, cls.__name__ ) )
    157