⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gen_base.py

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 PY
📖 第 1 页 / 共 3 页
字号:
  'lib' : TargetLib,  'doc' : TargetDoc,  'swig' : TargetSWIG,  'project' : TargetProject,  'swig_lib' : TargetSWIGLib,  'swig_project' : TargetSWIGProject,  'ra-module': TargetRaModule,  'fs-module': TargetFsModule,  'apache-mod': TargetApacheMod,  'javah' : TargetJavaHeaders,  'java' : TargetJavaClasses,  'i18n' : TargetI18N,  }class GenError(Exception):  pass# Path Handling Functions## Build paths specified in build.conf are assumed to be always separated# by forward slashes, regardless of the current running os.## Native paths are paths separated by os.sep.def native_path(path):  """Convert a build path to a native path"""  return string.replace(path, '/', os.sep)def build_path(path):  """Convert a native path to a build path"""  path = string.replace(path, os.sep, '/')  if os.altsep:    path = string.replace(path, os.altsep, '/')  return pathdef build_path_join(*path_parts):  """Join path components into a build path"""  return string.join(path_parts, '/')def build_path_split(path):  """Return list of components in a build path"""  return string.split(path, '/')def build_path_splitfile(path):  """Return the filename and directory portions of a file path"""  pos = string.rfind(path, '/')  if pos > 0:    return path[:pos], path[pos+1:]  elif pos == 0:    return path[0], path[1:]  else:    return "", pathdef build_path_dirname(path):  """Return the directory portion of a file path"""  return build_path_splitfile(path)[0]def build_path_basename(path):  """Return the filename portion of a file path"""  return build_path_splitfile(path)[1]def build_path_retreat(path):  "Given a relative directory, return ../ paths to retreat to the origin."  return ".." + "/.." * string.count(path, '/')def build_path_strip(path, files):  "Strip the given path from each file."  l = len(path)  result = [ ]  for file in files:    if len(file) > l and file[:l] == path and file[l] == '/':      result.append(file[l+1:])    else:      result.append(file)  return resultdef _collect_paths(pats, path=None):  """Find files matching a space separated list of globs    pats (string) is the list of glob patterns  path (string), if specified, is a path that will be prepended to each    glob pattern before it is evaluated      If path is none the return value is a list of filenames, otherwise  the return value is a list of 2-tuples. The first element in each tuple  is a matching filename and the second element is the portion of the  glob pattern which matched the file before its last forward slash (/)  """  result = [ ]  for base_pat in string.split(pats):    if path:      pattern = build_path_join(path, base_pat)    else:      pattern = base_pat    files = glob.glob(native_path(pattern)) or [pattern]    if path is None:      # just append the names to the result list      for file in files:        result.append(build_path(file))    else:      # if we have paths, then we need to record how each source is located      # relative to the specified path      reldir = build_path_dirname(base_pat)      for file in files:        result.append((build_path(file), reldir))  return result_re_public_include = re.compile(r'^subversion/include/(\w+)\.h$')def _is_public_include(fname):  return _re_public_include.match(build_path(fname))def _swig_include_wrapper(fname):  return native_path(_re_public_include.sub(    r"subversion/bindings/swig/proxy/\1_h.swg", build_path(fname)))class IncludeDependencyInfo:  """Finds all dependencies between a named set of headers, and computes  closure, so that individual C and SWIG source files can then be scanned, and  the stored dependency data used to return all directly and indirectly  referenced headers.  Note that where SWIG is concerned, there are two different kinds of include:  (1) those that include files in SWIG processing, and so matter to the      generation of .c files. (These are %include, %import).  (2) those that include references to C headers in the generated output,      and so are not required at .c generation, only at .o generation.      (These are %{ #include ... %}).  This class works exclusively in native-style paths."""  def __init__(self, filenames, fnames_nonexist):    """Operation of an IncludeDependencyInfo instance is restricted to a    'domain' - a set of header files which are considered interesting when    following and reporting dependencies.  This is done to avoid creating any    dependencies on system header files.  The domain is defined by three    factors:    (1) FILENAMES is a list of headers which are in the domain, and should be        scanned to discover how they inter-relate.    (2) FNAMES_NONEXIST is a list of headers which are in the domain, but will        be created by the build process, and so are not available to be        scanned - they will be assumed not to depend on any other interesting        headers.    (3) Files in subversion/bindings/swig/proxy/, which are based        autogenerated based on files in subversion/include/, will be added to        the domain when a file in subversion/include/ is processed, and        dependencies will be deduced by special-case logic.    """        # This defines the domain (i.e. set of files) in which dependencies are    # being located. Its structure is:    # { 'basename.h': [ 'path/to/something/named/basename.h',    #                   'path/to/another/named/basename.h', ] }    self._domain = {}    for fname in filenames + fnames_nonexist:      bname = os.path.basename(fname)      self._domain.setdefault(bname, []).append(fname)      if _is_public_include(fname):        swig_fname = _swig_include_wrapper(fname)        swig_bname = os.path.basename(swig_fname)        self._domain.setdefault(swig_bname, []).append(swig_fname)    # This data structure is:    # { 'full/path/to/header.h': { 'full/path/to/dependency.h': TYPECODE, } }    # TYPECODE is '#', denoting a C include, or '%' denoting a SWIG include.    self._deps = {}    for fname in filenames:      self._deps[fname] = self._scan_for_includes(fname)      if _is_public_include(fname):        hdrs = { self._domain["proxy.swg"][0]: '%',                 self._domain["apr.swg"][0]: '%',                 fname: '%' }        for h in self._deps[fname].keys():          if _is_public_include(h):            hdrs[_swig_include_wrapper(h)] = '%'          else:            raise RuntimeError, "Public include '%s' depends on '%s', " \                "which is not a public include! What's going on?" % (fname, h)        swig_fname = _swig_include_wrapper(fname)        swig_bname = os.path.basename(swig_fname)        self._deps[swig_fname] = hdrs    for fname in fnames_nonexist:      self._deps[fname] = {}    # Keep recomputing closures until we see no more changes    while 1:      changes = 0      for fname in self._deps.keys():        changes = self._include_closure(self._deps[fname]) or changes      if not changes:        break  def query_swig(self, fname):    """Scan the C or SWIG file FNAME, and return the full paths of each    include file that is a direct or indirect dependency, as a 2-tuple:      (C_INCLUDES, SWIG_INCLUDES)."""    if self._deps.has_key(fname):      hdrs = self._deps[fname]    else:      hdrs = self._scan_for_includes(fname)      self._include_closure(hdrs)    c_filenames = []    swig_filenames = []    for hdr, hdr_type in hdrs.items():      if hdr_type == '#':        c_filenames.append(hdr)      else: # hdr_type == '%'        swig_filenames.append(hdr)    # Be independent of hash ordering    c_filenames.sort()    swig_filenames.sort()    return (c_filenames, swig_filenames)  def query(self, fname):    """Same as SELF.QUERY_SWIG(FNAME), but assert that there are no SWIG    includes, and return only C includes as a single list."""    c_includes, swig_includes = self.query_swig(fname)    assert len(swig_includes) == 0    return c_includes  def _include_closure(self, hdrs):    """Mutate the passed dictionary HDRS, by performing a single pass    through the listed headers, adding the headers on which the first group    of headers depend, if not already present.    HDRS is of the form { 'path/to/header.h': TYPECODE, }        Return a boolean indicating whether any changes were made."""    items = hdrs.items()    for this_hdr, this_type in items:      for dependency_hdr, dependency_type in self._deps[this_hdr].items():        self._upd_dep_hash(hdrs, dependency_hdr, dependency_type)    return (len(items) != len(hdrs))  def _upd_dep_hash(self, hash, hdr, type):    """Mutate HASH (a data structure of the form    { 'path/to/header.h': TYPECODE, } ) to include additional info of a    dependency of type TYPE on the file HDR."""    # '%' (SWIG, .c: .i) has precedence over '#' (C, .o: .c)    if hash.get(hdr) != '%':      hash[hdr] = type      _re_include = \      re.compile(r'^\s*([#%])\s*(?:include|import)\s*([<"])?([^<">;\s]+)')  def _scan_for_includes(self, fname):    """Scan C source file FNAME and return the basenames of any headers    which are directly included, and within the set defined when this    IncludeDependencyProcessor was initialized.    Return a dictionary with included full file names as keys and None as    values."""    hdrs = { }    for line in fileinput.input(fname):      match = self._re_include.match(line)      if not match:        continue      include_param = native_path(match.group(3))      type_code = match.group(1)      direct_possibility_fname = os.path.normpath(os.path.join(        os.path.dirname(fname), include_param))      domain_fnames = self._domain.get(os.path.basename(include_param), [])      if direct_possibility_fname in domain_fnames:        self._upd_dep_hash(hdrs, direct_possibility_fname, type_code)      elif include_param.find(os.sep) == -1 and len(domain_fnames) == 1:        self._upd_dep_hash(hdrs, domain_fnames[0], type_code)      else:        # None found        if include_param.find(os.sep) == -1 and len(domain_fnames) > 1:          _error(              "Unable to determine which file is being included\n"              "  Include Parameter: '%s'\n"              "  Including File: '%s'\n"              "  Direct possibility: '%s'\n"              "  Other possibilities: %s\n"              % (include_param, fname, direct_possibility_fname,                domain_fnames))        if match.group(2) == '"':          _warning('"%s" header not found, file %s' % (include_param, fname))        continue      if match.group(2) == '<':        _warning('<%s> header *found*, file %s' % (include_param, fname))      # The above warnings help to avoid the following problems:      # - If header is uses the correct <> or "" convention, then the warnings      #   reveal if the build generator does/does not make dependencies for it       #   when it should not/should - e.g. might reveal changes needed to      #   build.conf.      #   ...and...      # - If the generator is correct, them the warnings reveal incorrect use      #   of <>/"" convention.    return hdrsdef _sorted_files(graph, area):  "Given a list of targets, sort them based on their dependencies."  # we're going to just go with a naive algorithm here. these lists are  # going to be so short, that we can use O(n^2) or whatever this is.  inst_targets = graph.get_sources(DT_INSTALL, area)  # first we need our own copy of the target list since we're going to  # munge it.  targets = inst_targets[:]  # the output list of the targets' files  files = [ ]  # loop while we have targets remaining:  while targets:    # find a target that has no dependencies in our current targets list.    for t in targets:      s = graph.get_sources(DT_LINK, t.name, Target) \          + graph.get_sources(DT_NONLIB, t.name, Target)      for d in s:        if d in targets:          break      else:        # no dependencies found in the targets list. this is a good "base"        # to add to the files list now.        if isinstance(t, TargetJava):          # Java targets have no filename, and we just ignore them.          pass        elif isinstance(t, TargetI18N):          # I18N targets have no filename, we recurse one level deeper, and          # get the filenames of their dependencies.          s = graph.get_sources(DT_LINK, t.name)          for d in s:            if d not in targets:              files.append(d.filename)        else:          files.append(t.filename)        # don't consider this target any more        targets.remove(t)        # break out of search through targets        break    else:      # we went through the entire target list and everything had at least      # one dependency on another target. thus, we have a circular dependency      # tree. somebody messed up the .conf file, or the app truly does have      # a loop (and if so, they're screwed; libtool can't relink a lib at      # install time if the dependent libs haven't been installed yet)      raise CircularDependencies()  return filesclass CircularDependencies(Exception):  passdef unique(seq):  "Eliminate duplicates from a sequence"  list = [ ]  dupes = { }  for e in seq:    if not dupes.has_key(e):      dupes[e] = None      list.append(e)  return list### End of file.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -