10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Copyright (C) 2009 Kevin Ollivier  All rights reserved.
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Redistribution and use in source and binary forms, with or without
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# modification, are permitted provided that the following conditions
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# are met:
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 1. Redistributions of source code must retain the above copyright
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#    notice, this list of conditions and the following disclaimer.
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# 2. Redistributions in binary form must reproduce the above copyright
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#    notice, this list of conditions and the following disclaimer in the
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#    documentation and/or other materials provided with the distribution.
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# This module is for code where we override waf's default behavior or extend waf
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport os
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport subprocess
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport sys
290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport Utils
310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# version of exec_command that handles Windows command lines longer than 32000 chars
330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef exec_command(s, **kw):
340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    filename = ''
350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if sys.platform.startswith('win') and len(' '.join(s)) > 32000:
360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        import tempfile
37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        (fd, filename) = tempfile.mkstemp()
38f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        t = []
39f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        for i in s:
40f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if i.find(" ") != -1:
41f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                i = '"%s"' % i
42f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            t.append(i)
432bde8e466a4451c7319e3a072d118917957d6554Steve Block
442bde8e466a4451c7319e3a072d118917957d6554Steve Block        t1 = t[1:]
452bde8e466a4451c7319e3a072d118917957d6554Steve Block        # Fix for LNK1170 error
462bde8e466a4451c7319e3a072d118917957d6554Steve Block        filename_str = '@' + filename
472bde8e466a4451c7319e3a072d118917957d6554Steve Block        filename2_str = None
482bde8e466a4451c7319e3a072d118917957d6554Steve Block        if len(' '.join(s)) > 131070:
492bde8e466a4451c7319e3a072d118917957d6554Steve Block            t2 = t[len(t) / 2:]
502bde8e466a4451c7319e3a072d118917957d6554Steve Block            t1 = t[1:len(t) / 2]
512bde8e466a4451c7319e3a072d118917957d6554Steve Block            (fd2, filename2) = tempfile.mkstemp()
522bde8e466a4451c7319e3a072d118917957d6554Steve Block            os.write(fd2, ' '.join(t2))
532bde8e466a4451c7319e3a072d118917957d6554Steve Block            os.close(fd2)
542bde8e466a4451c7319e3a072d118917957d6554Steve Block            filename2_str = '@' + filename2
552bde8e466a4451c7319e3a072d118917957d6554Steve Block        os.write(fd, ' '.join(t1))
56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        os.close(fd)
570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
582bde8e466a4451c7319e3a072d118917957d6554Steve Block        s = [s[0]]
592bde8e466a4451c7319e3a072d118917957d6554Steve Block        s.append(filename_str)
602bde8e466a4451c7319e3a072d118917957d6554Steve Block        if filename2_str:
612bde8e466a4451c7319e3a072d118917957d6554Steve Block            s.append(filename2_str)
620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if 'log' in kw:
640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        kw['stdout'] = kw['stderr'] = kw['log']
650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        del(kw['log'])
660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    kw['shell'] = isinstance(s, str)
670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    def cleanup():
690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        try:
700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if os.path.exists(filename):
710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                os.remove(filename)
720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        except:
730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            pass
740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    try:
760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        proc = subprocess.Popen(s, **kw)
770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        result = proc.wait()
780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        cleanup()
790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return result
800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    except OSError:
820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        cleanup()
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        raise
840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochUtils.exec_command = exec_command
860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch# Better performing h_file to keep hashing from consuming lots of time
880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport stat
890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdef h_file(filename):
900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    st = os.stat(filename)
910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m = Utils.md5()
930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m.update(str(st.st_mtime))
940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m.update(str(st.st_size))
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m.update(filename)
960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return m.digest()
970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochUtils.h_file = h_file
99