Public feed #528965

Something

public python v1 · immutable
Raw Edit
·published 2007-06-01 19:09 UTC
rendered paste body
import os, sys, string, tempfile, timeimport logginglog = logging.getLogger('')if sys.platform in ['win32', 'Cygwin']:    from SCons.Platform.win32 import piped_spawn    import scons.win32    import win32process    import win32event    import win32file    import win32com    import subprocess# This is used to comply with the SCons call backdef execute(sh, escape, cmd, args, env):    if 0:        log.debug(" ")        log.debug("execute: %s, %s, %s, %s" % ( sh, escape, cmd, [str(x) for x in args] ))        log.debug(os.getcwd())        log.debug(" ")    del args[0]    _spawn(cmd, args, env)def win_escape(args, env):    #Quote command-line arguments for DOS/Windows conventions: just    #wraps every argument which contains blanks in double quotes, and    #returns a new argument list.    args = [ (str(x)).encode('ascii', 'replace') for x in args]    for i in range(len(args)):        arg = args[i]        arg = arg.replace('#', '')        arg = unquote(arg)        # if it starts with a /? or -? and we're on windows, it's a switch as well        if arg[:8] == '/LIBPATH':            switch = arg[:9]            value = arg[9:]            arg = switch + quote(value)        elif arg[:3] == '/Fo':            switch = arg[:3]            value = arg[3:]            arg = switch + quote(value)        elif arg[:1] == '/':            switch = arg[:2]            value = arg[2:]            arg = switch + quote(value)        args[i] = arg                return argsdef quote(s):    if s.find(' ') != -1 or s[:2].lower() == 'c:':        s = '"' + s +'"'    return sdef unquote(s):    while s[0] in ["'", '"'] and s[-1] in ["'", '"']:        s = s[1:-1]    return s# This you can call directlydef _spawn(cmd, args, env):    debug = True    log.debug("platform: %s" % sys.platform)    if sys.platform in ['win32', 'Cygwin']:        path =  ['.', 'C:\WINDOWS\temp']        path += [ scons.win32.paths_vs8['bin'] ]        path += [ scons.win32.paths_vs8['swig'] ]        path += [ scons.win32.paths_vs8['gsoap_win'] ]        path += string.split(os.environ['PATH'], ";")        env['PATH'] = path        ret = launchWithoutConsole(cmd, args, env, debug)    return retdef launchWithoutConsole(cmd, args, env, debug=False):    """Launches 'command' windowless and waits until finished"""    filename = None    if not os.path.isabs(cmd):        cmd = findExecutable(cmd, env['PATH'])    args = win_escape(args, env)    #if " " in cmd:    #    cmd = quote(cmd.strip())    startupinfo = subprocess.STARTUPINFO()    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW    if os.path.basename(cmd.lower()) in ['cl', 'cl.exe', 'link', 'link.exe']:        filename, args = UseArgumentsFile(args)    log.debug(" ")    log.debug('='*80)    log.debug(" ")    log.debug("pwd: %s" % os.getcwd())    log.debug("cmd: %s" % string.join([cmd]+args, " "))    log.debug(" ")    log.debug(" ")    proc = subprocess.Popen([cmd] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,            stderr=subprocess.PIPE, startupinfo=startupinfo, shell = True)    data, err = proc.communicate()    rv = proc.wait()    if rv:        if err:            log.debug("retcode: %d" % rv)            if '  warning ' in err:                log.warn("error: %s" % str(err))            else:                log.error("error: %s" % str(err))            log.debug('='*80)            log.debug(' ')            log.debug(' ')    # output from the program    display_data( data.splitlines() )    display_data( err.splitlines() )    if filename:        os.unlink(filename)def display_data(lines):    import re    if not lines: return    rawstr = \        r"""(?P<file>.*?)[(](?P<lineno>.*?)[)]..?(?P<code>.*?)[:](?P<desc>.*)[:](?P<error>.*)$"""    pat = re.compile(rawstr,  re.IGNORECASE| re.DOTALL)    output = []    for line in lines:        line = line.strip()        match = pat.search(line)        if match:            # Retrieve group(s) by name            file   =    match.group('file')            lineno =    match.group('lineno')            code   =    match.group('code')            desc   =    match.group('desc')            error  =    match.group('error')                        text = "%s:%s: %s: %s: %s" % (file, lineno, code, desc, error)            output.append(text)        # skip the echo of the command line        elif line[:2] == 'cl' or \             line[:4] == 'link' or \             line[:9] == 'Microsoft' or \             line[:9] == 'Copyright' or \             line.strip() == "":            continue        else:            output.append(line.strip())    for line in output:        if line:            log.error( line )def UseArgumentsFile(args):    # compile arguments can get very lengthy and msdos can only handle 256 characters...    # so we need to put the arguments into a file and pass the file as an argument    # Use only for cl, and link    import tempfile    newargs = []    fileargs = []    for arg in args:        # if it's /c or /Fo, let's keep those on the commandline        if arg[:2] == '/c' or arg[:3] == '/Fo':            newargs.append( arg )        # if it's a switch, let's put it in the file        elif arg[:1] == '/' or arg[:1] == '-':            fileargs.append( arg )        # if it's an object file, put it on it's own line...        elif arg[-4:] == 'obj"':            fileargs.append( os.linesep+arg )        else:            newargs.append( arg )    log.debug( "*"*80 )    log.debug( "new args: " + str(newargs) )    log.debug( "*"*80 )    log.debug( "file args: " + str(fileargs) )    log.debug( "*"*80 )    # make it a string...    data = string.join( fileargs, " " )    log.debug("temp file data: %s" % data)    # write it out to a temp file    filename = tempfile.mktemp(dir='.')    log.debug("filename: %s" % filename)    file = open(filename, 'w')    file.write(data)    file.close()    # add this file as an argument to the compiler/linker    args.insert(0, "@%s" % filename)    return (filename, args)def findExecutable(cmd, paths):    tmp = cmd    if sys.platform in ['win32', 'Cygwin']:        if cmd[-4:] not in ['.exe', '.bat', '.cmd']:            cmd = cmd+'.exe'    for path in paths:        log.debug("looking for %s in %s" % (cmd, path))        tmp = os.path.join(str(path), cmd)        tmp = os.path.normpath( tmp )        if os.path.exists(tmp):            return tmp    log.error("Couldn't find the executable %s" % cmd)    return cmd