1643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#!/usr/bin/python
2643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#
3643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# Copyright (C) 2009 Google Inc. All rights reserved.
4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#
5643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# Redistribution and use in source and binary forms, with or without
6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# modification, are permitted provided that the following conditions are
7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# met:
8643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#
9643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#     * Redistributions of source code must retain the above copyright
10643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# notice, this list of conditions and the following disclaimer.
11643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#     * Redistributions in binary form must reproduce the above
12643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# copyright notice, this list of conditions and the following disclaimer
13643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# in the documentation and/or other materials provided with the
14643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# distribution.
15643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#     * Neither the name of Google Inc. nor the names of its
16643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# contributors may be used to endorse or promote products derived from
17643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# this software without specific prior written permission.
18643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#
19643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#
31643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# Copyright (c) 2009 The Chromium Authors. All rights reserved.
32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# Use of this source code is governed by a BSD-style license that can be
33643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# found in the LICENSE file.
34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
35643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# usage: rule_binding.py INPUT CPPDIR HDIR -- INPUTS -- OPTIONS
36643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# INPUT is an IDL file, such as Whatever.idl.
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# CPPDIR is the directory into which V8Whatever.cpp will be placed. HDIR is
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# the directory into which V8Whatever.h will be placed.
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#
42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# The first item in INPUTS is the path to generate-bindings.pl. Remaining
43643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# items in INPUTS are used to build the Perl module include path.
44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#
45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block# OPTIONS are passed as-is to generate-bindings.pl as additional arguments.
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
48643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockimport errno
49643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockimport os
50643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockimport shlex
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockimport shutil
52643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockimport subprocess
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockimport sys
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
55643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockdef SplitArgsIntoSections(args):
57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    sections = []
58643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    while len(args) > 0:
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if not '--' in args:
60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            # If there is no '--' left, everything remaining is an entire section.
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            dashes = len(args)
62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        else:
63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            dashes = args.index('--')
64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        sections.append(args[:dashes])
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        # Next time through the loop, look at everything after this '--'.
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if dashes + 1 == len(args):
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            # If the '--' is at the end of the list, we won't come back through the
70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            # loop again. Add an empty section now corresponding to the nothingness
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            # following the final '--'.
72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            args = []
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            sections.append(args)
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        else:
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            args = args[dashes + 1:]
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return sections
78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
80643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockdef main(args):
81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    sections = SplitArgsIntoSections(args[1:])
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    assert len(sections) == 3, sections
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    (base, inputs, options) = sections
84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    assert len(base) == 3, base
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    (input, cppdir, hdir) = base
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    assert len(inputs) > 1, inputs
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    generateBindings = inputs[0]
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    perlModules = inputs[1:]
91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    includeDirs = []
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for perlModule in perlModules:
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        includeDir = os.path.dirname(perlModule)
95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if not includeDir in includeDirs:
96643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            includeDirs.append(includeDir)
97643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
98e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if '--prefix' in options:
99e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        prefixIndex = options.index('--prefix')
100e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    else:
101e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        prefixIndex = options.index('--generator')
102e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
103967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    fileName = ''
104967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if '--filename' in options:
105967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        fileName = options[options.index('--filename') + 1]
106967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
107e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if prefixIndex + 1 < len(options):
108e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        prefix = options[prefixIndex + 1]
109e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    # The defines come in as one flat string. Split it up into distinct arguments.
111643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if '--defines' in options:
112643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        definesIndex = options.index('--defines')
113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if definesIndex + 1 < len(options):
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            splitOptions = shlex.split(options[definesIndex + 1])
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if splitOptions:
116643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                options[definesIndex + 1] = ' '.join(splitOptions)
117643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
118643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    # Build up the command.
119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    command = ['perl', '-w']
120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    for includeDir in includeDirs:
121643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        command.extend(['-I', includeDir])
122643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    command.append(generateBindings)
123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    command.extend(options)
124967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    command.extend(['--outputHeadersDir', hdir])
125643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    command.extend(['--outputDir', cppdir, input])
126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    # Do it. check_call is new in 2.5, so simulate its behavior with call and
128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    # assert.
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    returnCode = subprocess.call(command)
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    assert returnCode == 0
131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
132643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return returnCode
133643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
134643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
135643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockif __name__ == '__main__':
136643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    sys.exit(main(sys.argv))
137