1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#!/usr/bin/python
2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Copyright (C) 2009 Google Inc. All rights reserved.
4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Redistribution and use in source and binary forms, with or without
6dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# modification, are permitted provided that the following conditions are
7dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# met:
8dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
9dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#     * Redistributions of source code must retain the above copyright
10dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# notice, this list of conditions and the following disclaimer.
11dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#     * Redistributions in binary form must reproduce the above
12dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# copyright notice, this list of conditions and the following disclaimer
13dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# in the documentation and/or other materials provided with the
14dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# distribution.
15dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#     * Neither the name of Google Inc. nor the names of its
16dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# contributors may be used to endorse or promote products derived from
17dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# this software without specific prior written permission.
18dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
19dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
31dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Copyright (c) 2009 The Chromium Authors. All rights reserved.
32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Use of this source code is governed by a BSD-style license that can be
33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# found in the LICENSE file.
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# action_derivedsourceslist.py generates a single cpp file that includes
36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# all v8 bindings cpp files generated from idls. Files can be assigned into
37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# multiple output files, to reduce maximum compilation unit size and allow
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# parallel compilation.
39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# usage: action_derivedsourceslist.py IDL_FILES_LIST -- OUTPUT_FILE1 OUTPUT_FILE2 ...
41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Note that IDL_FILES_LIST is a text file containing the IDL file paths.
43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockimport errno
45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockimport os
46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockimport os.path
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockimport re
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockimport subprocess
49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockimport sys
50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# A regexp for finding Conditional attributes in interface definitions.
5221939df44de1705786c545cd1bf519d47250322dBen MurdochconditionalPattern = re.compile('interface[\s]*\[[^\]]*Conditional=([\_0-9a-zA-Z&|]*)')
53dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockcopyrightTemplate = """/*
55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
56dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
57dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * This file was generated by the make_jni_lists.py script.
58dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2009 Google Inc.  All rights reserved.
60dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Redistribution and use in source and binary forms, with or without
62dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * modification, are permitted provided that the following conditions
63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * are met:
64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 1. Redistributions of source code must retain the above copyright
65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *    notice, this list of conditions and the following disclaimer.
66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 2. Redistributions in binary form must reproduce the above copyright
67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *    notice, this list of conditions and the following disclaimer in the
68dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *    documentation and/or other materials provided with the distribution.
69dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */
82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block"""
83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
8521939df44de1705786c545cd1bf519d47250322dBen Murdoch# Wraps conditional with ENABLE() and replace '&','|' with '&&','||' if more than one conditional is specified.
86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockdef formatConditional(conditional):
87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    def wrapWithEnable(s):
8821939df44de1705786c545cd1bf519d47250322dBen Murdoch        if re.match('[|&]$', s):
8921939df44de1705786c545cd1bf519d47250322dBen Murdoch            return s * 2
90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return 'ENABLE(' + s + ')'
9121939df44de1705786c545cd1bf519d47250322dBen Murdoch    return ' '.join(map(wrapWithEnable, conditional))
92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
94dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Find the conditional interface attribute.
95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockdef extractConditional(idlFilePath):
96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    conditional = None
97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    # Read file and look for "interface [ Conditional=XXX ]".
99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    idlFile = open(idlFilePath)
100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    idlContents = idlFile.read().replace('\n', '')
101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    idlFile.close()
102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    match = conditionalPattern.search(idlContents)
104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if match:
105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        conditional = match.group(1)
10621939df44de1705786c545cd1bf519d47250322dBen Murdoch        conditional = re.split('([|&])', conditional)
107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return conditional
109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block# Extracts conditional and interface name from each IDL file.
111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockdef extractMetaData(filePaths):
112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    metaDataList = []
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for f in filePaths:
115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        metaData = {}
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if len(f) == 0:
117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            continue
118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if not os.path.exists(f):
119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            print 'WARNING: file not found: "%s"' % f
120dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            continue
121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
122dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        # Extract type name from file name
123dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        (parentPath, fileName) = os.path.split(f)
124dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        (interfaceName, ext) = os.path.splitext(fileName)
125dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if not ext == '.idl':
127dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            continue
128dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
129dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        metaData = {
130dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            'conditional': extractConditional(f),
131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            'name': interfaceName,
132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
134dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        metaDataList.append(metaData)
135dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return metaDataList
137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
139dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockdef generateContent(filesMetaData, partition, totalPartitions):
140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    # Sort files by conditionals.
141dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    filesMetaData.sort()
142dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
143dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    output = []
144dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
145dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    # Add fixed content.
146dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    output.append(copyrightTemplate)
147dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    output.append('#define NO_IMPLICIT_ATOMICSTRING\n\n')
148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    # List all includes segmented by if and endif.
150dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    prevConditional = None
151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for metaData in filesMetaData:
152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        name = metaData['name']
153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (hash(name) % totalPartitions) != partition:
154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            continue
155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        conditional = metaData['conditional']
156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if prevConditional and prevConditional != conditional:
158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            output.append('#endif\n')
159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if conditional and prevConditional != conditional:
160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            output.append('\n#if %s\n' % formatConditional(conditional))
161dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
162dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        output.append('#include "bindings/V8%s.cpp"\n' % name)
163dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
164dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        prevConditional = conditional
165dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
166dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if prevConditional:
167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        output.append('#endif\n')
168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return ''.join(output)
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
171dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
172dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockdef writeContent(content, outputFileName):
173dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    (parentPath, fileName) = os.path.split(outputFileName)
174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if not os.path.exists(parentPath):
175dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        print parentPath
176dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        os.mkdir(parentPath)
177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    f = open(outputFileName, 'w')
178dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    f.write(content)
179dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    f.close()
180dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
181dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
182dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockdef main(args):
183dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    assert(len(args) > 3)
184dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inOutBreakIndex = args.index('--')
185dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inputFileName = args[1]
186dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    outputFileNames = args[inOutBreakIndex+1:]
187dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
188dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inputFile = open(inputFileName, 'r')
189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    idlFileNames = inputFile.read().split('\n')
190dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    inputFile.close()
191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
192dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    filesMetaData = extractMetaData(idlFileNames)
193dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for fileName in outputFileNames:
194dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        print 'Generating derived sources list into %s...' % fileName
195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        partition = outputFileNames.index(fileName)
196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        fileContents = generateContent(filesMetaData, partition, len(outputFileNames))
197dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        writeContent(fileContents, fileName)
198dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
199dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return 0
200dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
201dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
202dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockif __name__ == '__main__':
203dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    sys.exit(main(sys.argv))
204