1cb93a386Sopenharmony_ci#!/usr/bin/env python 2cb93a386Sopenharmony_ci# 3cb93a386Sopenharmony_ci# Copyright 2015 Google Inc. 4cb93a386Sopenharmony_ci# 5cb93a386Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 6cb93a386Sopenharmony_ci# found in the LICENSE file. 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci# This script does a very rough simulation of BUILD file expansion, 9cb93a386Sopenharmony_ci# mostly to see the effects of glob(). 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci# We start by adding some symbols to our namespace that BUILD.public calls. 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ciimport glob 14cb93a386Sopenharmony_ciimport os 15cb93a386Sopenharmony_ciimport pprint 16cb93a386Sopenharmony_ciimport re 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_cidef noop(*args, **kwargs): 19cb93a386Sopenharmony_ci pass 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_cidef select_simulator(d): 22cb93a386Sopenharmony_ci result = [] 23cb93a386Sopenharmony_ci for k in d: 24cb93a386Sopenharmony_ci result.append("*** BEGIN %s ***" % k) 25cb93a386Sopenharmony_ci result.extend(d[k]) 26cb93a386Sopenharmony_ci result.append("*** END %s ***" % k) 27cb93a386Sopenharmony_ci return result 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ciDOUBLE_STAR_RE = re.compile(r'/\*\*/') 30cb93a386Sopenharmony_ciSTAR_RE = re.compile(r'\*') 31cb93a386Sopenharmony_ciDOUBLE_STAR_PLACEHOLDER = "xxxdoublestarxxx" 32cb93a386Sopenharmony_ciSTAR_PLACEHOLDER = "xxxstarxxx" 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci# Returns a set of files that match pattern. 35cb93a386Sopenharmony_cidef BUILD_glob_single(pattern): 36cb93a386Sopenharmony_ci if pattern.find('**') < 0: 37cb93a386Sopenharmony_ci # If pattern doesn't include **, glob.glob more-or-less does the right 38cb93a386Sopenharmony_ci # thing. 39cb93a386Sopenharmony_ci return glob.glob(pattern) 40cb93a386Sopenharmony_ci # First transform pattern into a regexp. 41cb93a386Sopenharmony_ci # Temporarily remove ** and *. 42cb93a386Sopenharmony_ci pattern2 = DOUBLE_STAR_RE.sub(DOUBLE_STAR_PLACEHOLDER, pattern) 43cb93a386Sopenharmony_ci pattern3 = STAR_RE.sub(STAR_PLACEHOLDER, pattern2) 44cb93a386Sopenharmony_ci # Replace any regexp special characters. 45cb93a386Sopenharmony_ci pattern4 = re.escape(pattern3) 46cb93a386Sopenharmony_ci # Replace * with [^/]* and ** with .*. 47cb93a386Sopenharmony_ci pattern5 = pattern4.replace(STAR_PLACEHOLDER, '[^/]*') 48cb93a386Sopenharmony_ci pattern6 = pattern5.replace(DOUBLE_STAR_PLACEHOLDER, '.*/') 49cb93a386Sopenharmony_ci # Anchor the match at the beginning and end. 50cb93a386Sopenharmony_ci pattern7 = "^" + pattern6 + "$" 51cb93a386Sopenharmony_ci pattern_re = re.compile(pattern7) 52cb93a386Sopenharmony_ci matches = set() 53cb93a386Sopenharmony_ci for root, _, files in os.walk('.'): 54cb93a386Sopenharmony_ci for fname in files: 55cb93a386Sopenharmony_ci # Remove initial "./". 56cb93a386Sopenharmony_ci path = os.path.join(root, fname)[2:] 57cb93a386Sopenharmony_ci if pattern_re.match(path): 58cb93a386Sopenharmony_ci matches.add(path) 59cb93a386Sopenharmony_ci return matches 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci# Simulates BUILD file glob(). 62cb93a386Sopenharmony_cidef BUILD_glob(include, exclude=()): 63cb93a386Sopenharmony_ci files = set() 64cb93a386Sopenharmony_ci for pattern in include: 65cb93a386Sopenharmony_ci files.update(BUILD_glob_single(pattern)) 66cb93a386Sopenharmony_ci for pattern in exclude: 67cb93a386Sopenharmony_ci files.difference_update(BUILD_glob_single(pattern)) 68cb93a386Sopenharmony_ci return list(sorted(files)) 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci# With these namespaces, we can treat BUILD.public as if it were 71cb93a386Sopenharmony_ci# Python code. This pulls its variable definitions (SRCS, HDRS, 72cb93a386Sopenharmony_ci# DEFINES, etc.) into local_names. 73cb93a386Sopenharmony_ciglobal_names = { 74cb93a386Sopenharmony_ci 'cc_library': noop, 75cb93a386Sopenharmony_ci 'cc_test': noop, 76cb93a386Sopenharmony_ci 'exports_files': noop, 77cb93a386Sopenharmony_ci 'glob': BUILD_glob, 78cb93a386Sopenharmony_ci 'select': select_simulator, 79cb93a386Sopenharmony_ci 'BASE_DIR': '', 80cb93a386Sopenharmony_ci 'BASE_EXTERNAL_DEPS_ANDROID': [], 81cb93a386Sopenharmony_ci 'BASE_EXTERNAL_DEPS_IOS': [], 82cb93a386Sopenharmony_ci 'BASE_EXTERNAL_DEPS_UNIX': [], 83cb93a386Sopenharmony_ci 'CONDITION_ANDROID': 'CONDITION_ANDROID', 84cb93a386Sopenharmony_ci 'CONDITION_IOS': 'CONDITION_IOS', 85cb93a386Sopenharmony_ci 'DM_EXTERNAL_DEPS': [], 86cb93a386Sopenharmony_ci 'EXTERNAL_DEPS_ALL': [], 87cb93a386Sopenharmony_ci 'EXTERNAL_INCLUDES': [], 88cb93a386Sopenharmony_ci} 89cb93a386Sopenharmony_cilocal_names = {} 90cb93a386Sopenharmony_ciexecfile('BUILD.public', global_names, local_names) 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ciwith open('tools/BUILD.public.expected', 'w') as out: 93cb93a386Sopenharmony_ci print >>out, "This file is auto-generated by tools/BUILD_simulator.py." 94cb93a386Sopenharmony_ci print >>out, "It expands BUILD.public to make it easy to see changes." 95cb93a386Sopenharmony_ci for name, value in sorted(local_names.items()): 96cb93a386Sopenharmony_ci print >>out, name, '= ', 97cb93a386Sopenharmony_ci pprint.pprint(value, out) 98