mercurial/util.py
changeset 1082 ce96e316278a
parent 1081 8b7d63489db3
child 1090 1bca39b85615
equal deleted inserted replaced
1081:8b7d63489db3 1082:ce96e316278a
     1 # util.py - utility functions and platform specfic implementations
     1 """
     2 #
     2 util.py - Mercurial utility functions and platform specfic implementations
     3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com>
     3 
     4 #
     4  Copyright 2005 K. Thananchayan <thananck@yahoo.com>
     5 # This software may be used and distributed according to the terms
     5 
     6 # of the GNU General Public License, incorporated herein by reference.
     6 This software may be used and distributed according to the terms
       
     7 of the GNU General Public License, incorporated herein by reference.
       
     8 
       
     9 This contains helper routines that are independent of the SCM core and hide
       
    10 platform-specific details from the core.
       
    11 """
     7 
    12 
     8 import os, errno
    13 import os, errno
     9 from demandload import *
    14 from demandload import *
    10 demandload(globals(), "re")
    15 demandload(globals(), "re")
    11 
    16 
    12 def binary(s):
    17 def binary(s):
       
    18     """return true if a string is binary data using diff's heuristic"""
    13     if s and '\0' in s[:4096]:
    19     if s and '\0' in s[:4096]:
    14         return True
    20         return True
    15     return False
    21     return False
    16 
    22 
    17 def unique(g):
    23 def unique(g):
       
    24     """return the uniq elements of iterable g"""
    18     seen = {}
    25     seen = {}
    19     for f in g:
    26     for f in g:
    20         if f not in seen:
    27         if f not in seen:
    21             seen[f] = 1
    28             seen[f] = 1
    22             yield f
    29             yield f
    84         a.pop(), b.pop()
    91         a.pop(), b.pop()
    85     b.reverse()
    92     b.reverse()
    86     return os.sep.join((['..'] * len(a)) + b)
    93     return os.sep.join((['..'] * len(a)) + b)
    87 
    94 
    88 def canonpath(root, cwd, myname):
    95 def canonpath(root, cwd, myname):
       
    96     """return the canonical path of myname, given cwd and root"""
    89     rootsep = root + os.sep
    97     rootsep = root + os.sep
    90     name = myname
    98     name = myname
    91     if not name.startswith(os.sep):
    99     if not name.startswith(os.sep):
    92         name = os.path.join(root, cwd, name)
   100         name = os.path.join(root, cwd, name)
    93     name = os.path.normpath(name)
   101     name = os.path.normpath(name)
    97         return ''
   105         return ''
    98     else:
   106     else:
    99         raise Abort('%s not under root' % myname)
   107         raise Abort('%s not under root' % myname)
   100 
   108 
   101 def matcher(canonroot, cwd, names, inc, exc, head=''):
   109 def matcher(canonroot, cwd, names, inc, exc, head=''):
       
   110     """build a function to match a set of file patterns
       
   111 
       
   112     arguments:
       
   113     canonroot - the canonical root of the tree you're matching against
       
   114     cwd - the current working directory, if relevant
       
   115     names - patterns to find
       
   116     inc - patterns to include
       
   117     exc - patterns to exclude
       
   118     head - a regex to prepend to patterns to control whether a match is rooted
       
   119 
       
   120     a pattern is one of:
       
   121     're:<regex>'
       
   122     'glob:<shellglob>'
       
   123     'path:<explicit path>'
       
   124     'relpath:<relative path>'
       
   125     '<relative path>'
       
   126 
       
   127     returns:
       
   128     a 3-tuple containing
       
   129     - list of explicit non-pattern names passed in
       
   130     - a bool match(filename) function
       
   131     - a bool indicating if any patterns were passed in
       
   132 
       
   133     todo:
       
   134     make head regex a rooted bool
       
   135     """
       
   136 
   102     def patkind(name):
   137     def patkind(name):
   103         for prefix in 're:', 'glob:', 'path:', 'relpath:':
   138         for prefix in 're:', 'glob:', 'path:', 'relpath:':
   104             if name.startswith(prefix): return name.split(':', 1)
   139             if name.startswith(prefix): return name.split(':', 1)
   105         for c in name:
   140         for c in name:
   106             if c in _globchars: return 'glob', name
   141             if c in _globchars: return 'glob', name
   173         if errprefix:
   208         if errprefix:
   174             errmsg = "%s: %s" % (errprefix, errmsg)
   209             errmsg = "%s: %s" % (errprefix, errmsg)
   175         raise Abort(errmsg)
   210         raise Abort(errmsg)
   176 
   211 
   177 def rename(src, dst):
   212 def rename(src, dst):
       
   213     """forcibly rename a file"""
   178     try:
   214     try:
   179         os.rename(src, dst)
   215         os.rename(src, dst)
   180     except:
   216     except:
   181         os.unlink(dst)
   217         os.unlink(dst)
   182         os.rename(src, dst)
   218         os.rename(src, dst)
   202     os.close(ld)
   238     os.close(ld)
   203 
   239 
   204 def _readlock_file(pathname):
   240 def _readlock_file(pathname):
   205     return file(pathname).read()
   241     return file(pathname).read()
   206 
   242 
   207 # Platfor specific varients
   243 # Platform specific variants
   208 if os.name == 'nt':
   244 if os.name == 'nt':
   209     nulldev = 'NUL:'
   245     nulldev = 'NUL:'
   210 
   246 
   211     def is_exec(f, last):
   247     def is_exec(f, last):
   212         return last
   248         return last
   231 
   267 
   232 else:
   268 else:
   233     nulldev = '/dev/null'
   269     nulldev = '/dev/null'
   234 
   270 
   235     def is_exec(f, last):
   271     def is_exec(f, last):
       
   272         """check whether a file is executable"""
   236         return (os.stat(f).st_mode & 0100 != 0)
   273         return (os.stat(f).st_mode & 0100 != 0)
   237 
   274 
   238     def set_exec(f, mode):
   275     def set_exec(f, mode):
   239         s = os.stat(f).st_mode
   276         s = os.stat(f).st_mode
   240         if (s & 0100 != 0) == mode:
   277         if (s & 0100 != 0) == mode: