mercurial/util.py
changeset 1293 a6ffcebd3315
parent 1292 141951276ba1
child 1312 c9cf171f30dd
equal deleted inserted replaced
1292:141951276ba1 1293:a6ffcebd3315
    10 platform-specific details from the core.
    10 platform-specific details from the core.
    11 """
    11 """
    12 
    12 
    13 import os, errno
    13 import os, errno
    14 from demandload import *
    14 from demandload import *
    15 demandload(globals(), "re cStringIO shutil popen2 threading")
    15 demandload(globals(), "re cStringIO shutil popen2 tempfile threading")
    16 
    16 
    17 def filter(s, cmd):
    17 def pipefilter(s, cmd):
    18     "filter a string through a command that transforms its input to its output"
    18     '''filter string S through command CMD, returning its output'''
    19     (pout, pin) = popen2.popen2(cmd, -1, 'b')
    19     (pout, pin) = popen2.popen2(cmd, -1, 'b')
    20     def writer():
    20     def writer():
    21         pin.write(s)
    21         pin.write(s)
    22         pin.close()
    22         pin.close()
    23 
    23 
    27     w.start()
    27     w.start()
    28     f = pout.read()
    28     f = pout.read()
    29     pout.close()
    29     pout.close()
    30     w.join()
    30     w.join()
    31     return f
    31     return f
       
    32 
       
    33 def tempfilter(s, cmd):
       
    34     '''filter string S through a pair of temporary files with CMD.
       
    35     CMD is used as a template to create the real command to be run,
       
    36     with the strings INFILE and OUTFILE replaced by the real names of
       
    37     the temporary files generated.'''
       
    38     inname, outname = None, None
       
    39     try:
       
    40         infd, inname = tempfile.mkstemp(prefix='hgfin')
       
    41         fp = os.fdopen(infd, 'wb')
       
    42         fp.write(s)
       
    43         fp.close()
       
    44         outfd, outname = tempfile.mkstemp(prefix='hgfout')
       
    45         os.close(outfd)
       
    46         cmd = cmd.replace('INFILE', inname)
       
    47         cmd = cmd.replace('OUTFILE', outname)
       
    48         code = os.system(cmd)
       
    49         if code: raise Abort("command '%s' failed: %s" %
       
    50                              (cmd, explain_exit(code)))
       
    51         return open(outname, 'rb').read()
       
    52     finally:
       
    53         try:
       
    54             if inname: os.unlink(inname)
       
    55         except: pass
       
    56         try:
       
    57             if outname: os.unlink(outname)
       
    58         except: pass
       
    59 
       
    60 filtertable = {
       
    61     'tempfile:': tempfilter,
       
    62     'pipe:': pipefilter,
       
    63     }
       
    64 
       
    65 def filter(s, cmd):
       
    66     "filter a string through a command that transforms its input to its output"
       
    67     for name, fn in filtertable.iteritems():
       
    68         if cmd.startswith(name):
       
    69             return fn(s, cmd[len(name):].lstrip())
       
    70     return pipefilter(s, cmd)
    32 
    71 
    33 def patch(strip, patchname, ui):
    72 def patch(strip, patchname, ui):
    34     """apply the patch <patchname> to the working directory.
    73     """apply the patch <patchname> to the working directory.
    35     a list of patched files is returned"""
    74     a list of patched files is returned"""
    36     fp = os.popen('patch -p%d < "%s"' % (strip, patchname))
    75     fp = os.popen('patch -p%d < "%s"' % (strip, patchname))
    41         if line.startswith('patching file '):
    80         if line.startswith('patching file '):
    42             pf = parse_patch_output(line)
    81             pf = parse_patch_output(line)
    43             files.setdefault(pf, 1)
    82             files.setdefault(pf, 1)
    44     code = fp.close()
    83     code = fp.close()
    45     if code:
    84     if code:
    46         raise Abort("patch command failed: exit status %s " % code)
    85         raise Abort("patch command failed: %s" % explain_exit(code))
    47     return files.keys()
    86     return files.keys()
    48 
    87 
    49 def binary(s):
    88 def binary(s):
    50     """return true if a string is binary data using diff's heuristic"""
    89     """return true if a string is binary data using diff's heuristic"""
    51     if s and '\0' in s[:4096]:
    90     if s and '\0' in s[:4096]: