Hi,

attached to this mail you will find the Util.py with the corrected type (line 80).

Cheers,
Christoph
"""
General Util methods and classes for SConsAddons.

This should NOT be a final resting point for code, but more a place
to put things while refactoring and deciding where they should end
up long term.
"""

#
# __COPYRIGHT__
#
# This file is part of scons-addons.
#
# Scons-addons is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Scons-addons is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with scons-addons; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

from __future__ import generators
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

import os
import sys
import re
import distutils.util
import string
import SCons.Environment
import SCons
import SCons.Platform
from SCons.Util import WhereIs

pj = os.path.join

def GetPlatform():
   "Get a platform string"
   if string.find(sys.platform, 'irix') != -1:
      return 'irix'
   elif string.find(sys.platform, 'linux') != -1:
      return 'linux'
   elif string.find(sys.platform, 'freebsd') != -1:
      return 'freebsd'
   elif string.find(sys.platform, 'netbsd') != -1:
      return 'netbsd'
   elif string.find(sys.platform, 'openbsd') != -1:
      return 'openbsd'
   elif string.find(sys.platform, 'dragonfly') != -1:
      return 'dragonfly'
   elif string.find(sys.platform, 'cygwin') != -1:
      return 'win32'
   elif string.find(sys.platform, 'sunos') != -1:
      return 'sunos'
   elif string.find(sys.platform, 'darwin' ) != -1:
      return 'darwin'
   elif os.name == 'os2':
      return 'os2'
   else:
      return sys.platform

def GetArch():
   """ Return identifier for CPU architecture. """
   if not hasattr(os, 'uname'):
      platform = distutils.util.get_platform()
      arch = ""
      if re.search(r'i.86', platform) or platform == "win32":
         arch = 'ia32'
      # x86_64 (aka, x64, EM64T)
      elif re.search(r'x86_64', platform) or platform == "win64":
         arch = 'x64'
      # IA64, aka Itanium
      elif re.search(r'ia64', platform):
         arch = 'ia64'
         # PowerPC
      elif re.search(r'Power_Mac', platform):
         arch = 'ppc'
   else:
      arch_str = os.uname()[4]
      if re.search(r'i.86', arch_str):
         arch = 'ia32'
      # x86_64 (aka, x64, EM64T)
      elif re.search(r'x86_64', arch_str):
         arch = 'x64'
      # IA64, aka Itanium
      elif re.search(r'ia64', arch_str):
         arch = 'ia64'
      # PowerPC Macintosh
      elif re.search(r'Power Macintosh', arch_str):
         # XXX: Not sure if this actually works. -PH 7/24/2006
         if re.search(r'64', arch_str):
            arch = 'ppc64'
         else:
            arch = 'ppc'

   return arch

def GetCpuType():
   """ Return the type of cpu found in the system. 
       TODO: Extend this to support more OS's and CPUs
   """
   cpu_type = None

   if os.path.exists('/proc/cpuinfo'):
      cpu_info = file('/proc/cpuinfo').read().lower()
      if (cpu_info.count("ia-64") > 0):
         cpu_type = "itanium"
      elif (cpu_info.count("athlon") > 0):
         cpu_type = "athlon"

   if not cpu_type:
      platform = distutils.util.get_platform()
      if re.search(r'i.86', platform):
         cpu_type = 'i386'

   return cpu_type

def GetVersionFromHeader(name, header_file_path):
   """ Pulls PACKAGE_VERSION_MAJOR...etc from specified
       header file and returns as a tuple.
       Ex:
         res = GetVersionFromHeader('MY_PKG', '/path/to/my_pkg/Version.h')
   """
   if os.path.exists(header_file_path):
      ver_file_contents = file(header_file_path).read()
      major_ver_match = re.search(r'define\s+' + name + 
r'_VERSION_MAJOR\s+(\d+)',
                                  ver_file_contents)
      minor_ver_match = re.search(r'define\s+' + name + 
r'_VERSION_MINOR\s+(\d+)',
                                  ver_file_contents)
      patch_ver_match = re.search(r'define\s+' + name + 
r'_VERSION_PATCH\s+(\d+)',
                                  ver_file_contents)
      if not major_ver_match:
         print "WARNING: Could not find %s_VERSION_MAJOR in" % name, 
header_file_path
      else:
         major = int(major_ver_match.group(1))
         minor = int(minor_ver_match.group(1))
         patch = int(patch_ver_match.group(1))
         return (major, minor, patch)
   else:
      print str(header_file_path) + " does not exist!"

   return (0, 0, 0)


def hasHelpFlag():
   """ Return true if the help flag was passed to scons. """
   try:
      has_help_flag = SCons.Script.Main.options.help_msg
   except AttributeError:
      try:
         has_help_flag = SCons.Script.options.help_msg
      except AttributeError:
         has_help_flag = SCons.Script.GetOption("help")
   return has_help_flag


def symlinkInstallFunc(dest, source, env):
    """Install a source file into a destination by sym linking it.
       Ex:
         common_env['INSTALL'] = symlinkInstallFunc
    """
    rel_path = ""
    dirs = os.path.dirname(dest)
    for d in dirs.split(os.path.sep):
      rel_path = os.path.join(rel_path, "..")
    os.symlink(os.path.join(rel_path, source), dest)
    return 0

def absoluteSymlinkInstallFunc(dest, source, env):
    """Install a source file into a destination by sym linking it.
       Ex:
         common_env['INSTALL'] = symlinkInstallFunc
    """
    os.symlink(pj(os.getcwd(), source), dest)
    return 0

# ----------------------------------
# File extension retrieval methods
# -----------------------------------
def fileExtensionMatches(f, fexts):
   """ Returns true if f has an extension in the list fexts """
   for ext in fexts:
      if f.endswith(ext):
         return True
   return False

def getPredFilesRecursive(tree_root, predicateMethod):
   """ Return list of sources recursively.  Returned paths are related to the 
tree_root """
   def dir_method(f_list, dirpath, namelist):
      for f in namelist:
         if predicateMethod(f):
            f_list.append(os.path.normpath(pj(dirpath, f)))
   cur_dir = os.getcwd()
   os.chdir(tree_root)
   f_list = []
   os.path.walk('.', dir_method, f_list)
   os.chdir(cur_dir)
   return f_list


def getHeaders():
   """ get the headers in the current directory """
   exts = ['.h','.hpp']
   files = os.listdir('.')
   ret = []
   for x in files:
      for e in exts:
         if x.endswith(e):
            ret.append(x)
   return ret

def getSources():
   """ get the source files in the current directory"""
   exts = ['.cpp','.c','.C','.cxx']
   files = os.listdir('.')
   ret = []
   for x in files:
      print "checking if"+x+"is a source file"
      for e in exts:
         print "wither source suffix: "+e
         if x.endswith(e):
            ret.append(x)
   return ret


def getFilesRecursiveByExt(tree_root, fexts):
   def hasExtension(f):
      return fileExtensionMatches(f, fexts)
   return getPredFilesRecursive(tree_root, hasExtension)

def getSourcesRecursive(tree_root):
   """ Return list of sources recursively """
   return getFilesRecursiveByExt(tree_root, ['.cpp','.c','.C','.cxx'])

def getHeadersRecursive(tree_root):
   """ Return list of headers recursively """
   return getFilesRecursiveByExt(tree_root, ['.h','.hpp'])


class ConfigCmdParser:
   """
   Helper class for calling a given *-config command and extracting
   various paths and other information from it.
   """

   def __init__(self, configCmd, configScript=None):
      " configCmd: The config command to call (python/flagpoll/etc)"

      self.configCmd = configCmd
      self.valid = True
      # Ensure that command is valid.
      if not os.path.isfile(self.configCmd):
         self.valid = False
         raise ValueError("ConfigCmd not found: %s"%self.configCmd)

      if configScript and not os.path.isfile(configScript):
         self.valid = False
         raise ValueError("configScript not found: %s"%configScript)

      # If we have a config script, change the command to
      # contain both the interpreter command and script.
      if configScript:
         self.configCmd = configCmd + ' ' + configScript         

      # Initialize regular expressions
      # Res that when matched against config output should match the options we 
want
      # In future could try to use INCPREFIX and other platform neutral stuff

      if 'win32' == GetPlatform():
         self.inc_re = re.compile(r'(?: |^)/I(\S*)', re.MULTILINE)
         self.lib_re = re.compile(r'(?: |^)(\S*\.lib)', re.M | re.I)
         self.lib_path_re = re.compile(r'(?: |^)/LIBPATH:(\S*)', re.M | re.I)
         self.cxx_flags_re = re.compile(r'(?: |^)/D(\S*)', re.MULTILINE)
      else:
         self.inc_re = re.compile(r'(?: |^)-I(\S*)', re.MULTILINE)
         self.lib_re = re.compile(r'(?: |^)-l(\S*)', re.MULTILINE)
         self.lib_path_re = re.compile(r'(?: |^)-L(\S*)', re.MULTILINE)
         self.cxx_flags_re = re.compile(r'(?: |^)-D(\S*)', re.MULTILINE)

   def findLibs(self, arg="--libs"):
      if not self.valid:
         return ""

      args = self.lib_re.findall(os.popen(self.configCmd + " " + 
arg).read().strip())
      for i, arg in enumerate(args):
         args[i] = os.path.expandvars(arg)

      return args

   def findLibPaths(self, arg="--libs"):
      if not self.valid:
         return ""

      args = self.lib_path_re.findall(os.popen(self.configCmd + " " + 
arg).read().strip())
      for i, arg in enumerate(args):
         args[i] = os.path.expandvars(arg)

      return args

   def findIncludes(self, arg="--cflags"):
      if not self.valid:
         return ""

      args = self.inc_re.findall(os.popen(self.configCmd + " " + 
arg).read().strip()) 
      for i, arg in enumerate(args):
         args[i] = os.path.expandvars(arg)

      return args

   def findCXXFlags(self, arg="--cflags"):
      if not self.valid:
         return ""

      args = self.cxx_flags_re.findall(os.popen(self.configCmd + " " + 
arg).read().strip())
      for i, arg in enumerate(args):
         args[i] = os.path.expandvars(arg)

      return args

   def getVersion(self, arg="--version"):
      if not self.valid:
         return ""
      return os.popen(self.configCmd + " " + arg).read().strip()

class PythonScriptParser(ConfigCmdParser):
   def __init__(self, configScript):
      ConfigCmdParser.__init__(self, sys.executable, configScript)

class FlagPollParser:
   """
   Helper class for calling flagpoll and extracting
   various paths and other information from it.
   """

   def __init__(self, moduleName, fpcFile=None):
      " moduleName: The config command to call "
      self.moduleName = moduleName
      self.fpcFile = fpcFile
      if self.fpcFile is not None:
         self.fpcFile = self.fpcFile.strip()
      self.valid = True

      self.flagpoll_cmd = WhereIs('flagpoll')
      if None == self.flagpoll_cmd:
         print "FlagPollParser: Could not find flagpoll."
         self.valid = False
         return
      if self.fpcFile is not None and not os.path.isfile(self.fpcFile):
         print "FlagPollParser: Could not find fpc file:", self.fpcFile
         self.valid = False
         return

      # All calls to flagpoll need module name now.
      if 'win32' == GetPlatform():
         self.flagpoll_cmd = '"%s" %s' % (self.flagpoll_cmd, self.moduleName)
      else:
         self.flagpoll_cmd += " %s"%self.moduleName

      # Find out if the module exists.
      exists_resp = self.callFlagPoll("--exists")
      if "yes" != exists_resp.strip().lower():
         self.valid = False
         return

      # Initialize regular expressions
      # Res that when matched against config output should match the options we 
want
      # In future could try to use INCPREFIX and other platform neutral stuff
      self.inc_re = re.compile(r'(?: |^)[-/]I\s*("[^"]+"|\S+)', re.MULTILINE)
      self.framework_re = re.compile(r'(?: |^)-framework (\S+)', re.MULTILINE)
      self.link_flag_re = re.compile(r'(?: |^)([-/]\S*)', re.MULTILINE)

      if 'win32' == GetPlatform():
         self.lib_re = re.compile(r'(?: |^)(\S*\.lib)', re.MULTILINE)
         self.cxx_flags_re = re.compile(r'(?: |^)/D(\S*)', re.MULTILINE)
         #self.lib_path_re = re.compile(r'(?: |^)/LIBPATH:(\S*)', re.M | re.I)
         self.lib_path_re = re.compile(r'(?: |^)/LIBPATH:("[^"]+"|\S+)',
                                       re.M | re.I)
      else:
         self.lib_re = re.compile(r'(?: |^)-l(\S*)', re.MULTILINE)
         self.lib_path_re = re.compile(r'(?: |^)-L(\S*)', re.MULTILINE)
         self.cxx_flags_re = re.compile(r'(?: |^)-D(\S*)', re.MULTILINE)

   def findLibs(self, arg="--libs-only-l"):
      if not self.valid:
         return ""
      return self.lib_re.findall(self.callFlagPoll(arg))

   def findFrameworks(self, arg="--libs"):
      if not self.valid:
         return ""
      return self.framework_re.findall(self.callFlagPoll(arg))

   def findLibPaths(self, arg="--libs-only-L"):
      if not self.valid:
         return ""
      libs = self.lib_path_re.findall(self.callFlagPoll(arg))
      return [l.strip('"') for l in libs]

   def findLinkFlags(self, arg="--libs-only-other"):
      if not self.valid:
         return ""
      return self.link_flag_re.findall(self.callFlagPoll(arg))

   def findIncludes(self, arg="--cflags-only-I"):
      if not self.valid:
         return ""
      incs = self.inc_re.findall(self.callFlagPoll(arg))
      return [r.strip('"') for r in incs]

   def findCXXFlags(self, arg="--cflags"):
      if not self.valid:
         return ""
      return self.cxx_flags_re.findall(self.callFlagPoll(arg))

   def getVersion(self, arg="--modversion"):
      if not self.valid:
         return ""
      return self.callFlagPoll(arg)

   def callFlagPoll(self, cmdFlags):
      """ Return result of calling flagpoll.
          Checks for error state and outputs error and returns ''
      """
      if self.fpcFile is not None:
         cmdFlags = "--from-file=%s %s" % (self.fpcFile.strip(), cmdFlags)

      cur_cmd = "%s %s"%(self.flagpoll_cmd, cmdFlags)
      #print "Calling: ", cur_cmd
      cmd_call = os.popen(cur_cmd)
      cmd_str = cmd_call.read().strip()
      if None != cmd_call.close():
         self.valid = False 
         print "FlagPollParser: call failed: %s"%cur_cmd
      return cmd_str



# -------------------- #
# Path utils
# -------------------- #
def getFullSrcPath(env=SCons.Environment.Environment()):
   """ Return the full path to the local source directory we are in 
       (taking into account BuildDir) """
   # Get the local directory using Dir(.)
   # Then return the string rep of its src node
   ldir_node = env.Dir('.')                                   # .
   ldir_srcnode = ldir_node.srcnode()                     # 
/home/.../XXX/src/plx
   return str(ldir_srcnode)


def getRelativeSourcePath(env=SCons.Environment.Environment()):
   """ Return the local source path relative to the base build directory
       ie. Dir('#') """
   ldir_node = env.Dir('.')                                   # .
   ldir_srcnode = ldir_node.srcnode()                     # 
/home/.../XXX/src/plx
   root_dir_node = env.Dir('#')                               # /home/.../XXX
   ldir_src_rpath = ldir_srcnode.get_path(root_dir_node)  # src/plx
   return ldir_src_rpath

def getFullRootPath(env=SCons.Environment.Environment()):
   " Return the full path of the root build dir "
   return str(env.Dir('#'))

def createRelativePath(target, base=os.curdir):
   " Return the given path as a path relative to the given base. "

   if not os.path.exists(target):
      raise OSError, 'Target does not exist: '+target

   if not os.path.isdir(base):
      raise OSError, 'Base is not a directory or does not exist: '+base

   base_list = (os.path.abspath(base)).split(os.sep)
   target_list = (os.path.abspath(target)).split(os.sep)

   # On the windows platform the target may be on a completely different drive 
from the base.
   if os.name in ['nt','dos','os2'] and base_list[0] != target_list[0]:
      raise OSError, 'Target is on a different drive to base. Target: 
'+target_list[0].upper()+', base: '+base_list[0].upper()

   # Starting from the filepath root, work out how much of the filepath is
   # shared by base and target.
   for i in range(min(len(base_list), len(target_list))):
      if base_list[i] != target_list[i]: 
         break
   else:  # Loop finished normally (no break)
      # If we broke out of the loop, i is pointing to the first differing path 
elements.
      # If we didn't break out of the loop, i is pointing to identical path 
elements.
      # Increment i so that in all cases it points to the first differing path 
elements.
      i+=1

   rel_list = [os.pardir] * (len(base_list)-i) + target_list[i:]
   return os.path.join(*rel_list)





# ---------- Inprogress ---------- #
import SCons.Node.FS

import fnmatch
import glob

def Glob(match, env=SCons.Environment.Environment()):
    """Similar to glob.glob, except globs SCons nodes, and thus sees
    generated files and files from build directories.  Basically, it sees
    anything SCons knows about."""
    def fn_filter(node):
        fn = str(node)
        return fnmatch.fnmatch(os.path.basename(fn), match)

    from SCons.Scanner.Dir import DirScanner
    scanner = DirScanner()

    children = []
    def add(node):
        print "Adding: ", str(node)
        children.extend(node.all_children())
        children.extend(scanner(node, node.get_build_env()))

    here = env.Dir('.')
    add(here)
    while here.srcnode() != here:
        here = here.srcnode()
        add(here)

    print "children: ", [str(c) for c in children]

    nodes = map(env.File, filter(fn_filter, children))

    # Remove duplicates.  O(n2) :(
    rv = []
    for n in nodes:
        if n not in rv:
            rv.append(n)
    return rv 

def Globber( pattern = '*.*', dir = '.', env=SCons.Environment.Environment() ):
    import os, fnmatch
    files = []
    srcdir_abs_path = env.Dir(dir).srcnode().abspath
    #print "srcdir_abs: ", srcdir_abs_path
    for file in os.listdir( srcdir_abs_path ):
        if fnmatch.fnmatch(file, pattern) :
            files.append( os.path.join( dir, file ) )
    return files
   
def WalkBuildFromSourceOld(dir='.', env=SCons.Environment.Environment() ):
    """ Something similar to os.walk() but it is called
        in the build directory and walks over the stuff in the source
        but makes it look like it is relative to the build directory.
    """
    srcdir_abs_path = env.Dir(dir).srcnode().abspath
    #print "src dir abs: ", srcdir_abs_path

    # Each dirpath is going to start with the top of the walk
    for dirpath, dirs, filenames in os.walk(srcdir_abs_path):
       if dirpath.startswith(srcdir_abs_path):
          dirpath = dirpath[len(srcdir_abs_path)+1:]
       bdirpath = os.path.join(dir, dirpath)
       bfiles = filenames
       bdirs = dirs
       yield (bdirpath, bdirs, bfiles)

def WalkBuildFromSource(dir='.', env=SCons.Environment.Environment() ):
    """ Something similar to os.walk() but it is called
        in the build directory and walks over the stuff in the source
        but makes it look like it is relative to the build directory.
    """
    srcdir_abs_path = env.Dir(dir).srcnode().abspath
    #print "src dir abs: ", srcdir_abs_path
    ret_args = []

    def collect_args(junk, dir_path, name_list):
        dirs = []
        files = []
        for n in name_list:
            if os.path.isfile(os.path.join(dir_path, n)):
                files.append(n)
            else:
                dirs.append(n)
        ret_args.append( [dir_path, dirs, files] )

    os.path.walk(srcdir_abs_path, collect_args, None)

    # Each dirpath is going to start with the top of the walk
    for dirpath, dirs, filenames in ret_args:
       if dirpath.startswith(srcdir_abs_path):
          dirpath = dirpath[len(srcdir_abs_path)+1:]
       bdirpath = os.path.join(dir, dirpath)
       bfiles = filenames
       bdirs = dirs
       yield (bdirpath, bdirs, bfiles)

def GlobA(pathname):
    """Return a list of paths matching a pathname pattern.

    The pattern may contain simple shell-style wildcards a la fnmatch.

    """
    glob_magic_check = re.compile('[*?[]')
    fs = SCons.Node.FS.default_fs

    def glob_has_magic(s):
       " Does the glob string contain magic characters."
       return magic_check.search(s) is not None

    def find_node(node_name):
       """ Returns node if the given node names exists in the default file 
system.
           Otherwise returns 0.
       """
       try:
          node = fs.Entry(node_name, create=0)
       except SCons.Errors.UserError:
          return 0
       return node

    # If no magic, then just check for the specified file
    if not has_magic(pathname):
       node = find_node(pathname)
       if node != 0:
          return [node]
       else:
          return []

    dirname, basename = os.path.split(pathname)

    if not dirname:
        return Glob_FilesInDir(os.curdir, basename)
    elif has_magic(dirname):                 # If there is magic in dir name 
then recurse
        list = glob(dirname)
    else:
        list = [dirname]

    # Assert: list contains full list of directories to search for file
    if not has_magic(basename):
        result = []
        for dirname in list:
            if basename or os.path.isdir(dirname):
                name = os.path.join(dirname, basename)
                if os.path.exists(name):
                    result.append(name)
    else:
        result = []
        for dirname in list:
            sublist = Glob_FilesInDir(dirname, basename)
            for name in sublist:
                result.append(os.path.join(dirname, name))
    return result

def Glob_FilesInDir(dirnode, pattern):
   """ Return list of files in directory dirname that match the pattern. """
   children = dirnode.all_children()

   #if pattern[0]!='.':
   #   names=filter(lambda x: x[0]!='.',names)
   def fn_filter(node):
      filename = str(node)
      return fnmatch.fnmatch(filename, pattern)

   ret_list = [child for child in children if fn_filter(child)]
   return ret_list


def GlobB(match):
    """Similar to glob.glob, except globs SCons nodes, and thus sees
    generated files and files from build directories.  Basically, it sees
    anything SCons knows about."""
    def fn_filter(node):
        fn = str(node)
        return fnmatch.fnmatch(os.path.basename(fn), match)

    here = Dir('.')

    children = here.all_children()
    nodes = map(File, filter(fn_filter, children))
    node_srcs = [n.srcnode() for n in nodes]

    src = here.srcnode()
    if src is not here:
        src_children = map(File, filter(fn_filter, src.all_children()))
        for s in src_children:
            if s not in node_srcs:
                nodes.append(File(os.path.basename(str(s))))

    return nodes

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Opensg-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-core

Reply via email to