blob: 7fb75c9d65c03abf0b76a76a31293a5728766719 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright (c) 2020 Valve Corporation
# Copyright (c) 2020 LunarG, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Mike Schuchardt <mikes@lunarg.com>
# Scrub source code of "aliases" -- extension types and enums that have been promoted to core.
#
# Usage: antialias_source.py XML_PATH SOURCE_PATH...
#
# Notes:
# - Source code generators need to be re-run after this script due to
# inconsitencies in the registry with regard to alias usage
# - Clang-format needs to be re-run after this script
import sys
import os
import re
from xml.etree import ElementTree
SOURCE_EXTS = ['.h', '.c', '.cpp', '.inc', '.py']
def GetAliases(xml_path):
tree = ElementTree.parse(xml_path)
root = tree.getroot()
suffixes = [tag.get('name') for tag in root.findall('tags/tag')]
aliases = {}
alias_elements = []
alias_elements.extend(root.findall('types/type[@alias]'))
alias_elements.extend(root.findall('enums/enum[@alias]'))
# extension types are covered above in types/type
alias_elements.extend(root.findall('extensions/extension/require/enum[@alias]'))
# DON'T try to do commands, those aliases are not binary compatible and we still need to handle both
for alias_element in alias_elements:
alias = alias_element.get('alias')
name = alias_element.get('name')
# Look for un-suffixed alias (core)
if not any(alias.endswith(s) for s in suffixes):
aliases[name] = alias
return aliases
def UpdateFile(alias_map, filename):
with open(filename) as f:
file_contents = f.read()
sub_count = 0
for name, alias in alias_map.items():
if name in file_contents:
# Use regex with word break to match whole tokens only
file_contents, n = re.subn(r'\b{}\b'.format(name), alias, file_contents)
sub_count += n
if sub_count > 0:
print('{} {}'.format(filename, sub_count))
with open(filename, 'w') as f:
f.write(file_contents)
def UpdateDir(alias_map, path):
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
if any(filename.endswith(ext) for ext in SOURCE_EXTS):
UpdateFile(alias_map, os.path.join(dirpath, filename))
def Main():
if len(sys.argv) < 3 or not sys.argv[1].endswith('.xml'):
print('Usage: antialias_source.py XML_PATH SOURCE_PATH...')
sys.exit(1)
xml_path = sys.argv[1]
source_paths = sys.argv[2:]
aliases = GetAliases(xml_path)
for source_path in source_paths:
if os.path.isfile(source_path):
UpdateFile(aliases, source_path)
elif os.path.isdir(source_path):
UpdateDir(aliases, source_path)
if __name__ == '__main__':
Main()