mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-10-26 12:27:44 +00:00 
			
		
		
		
	Added rename_symbols.py to mass rename symbols in an SDL2 codebase
This commit is contained in:
		
							
								
								
									
										224
									
								
								build-scripts/rename_api.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										224
									
								
								build-scripts/rename_api.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,224 @@ | ||||
| #!/usr/bin/env python3 | ||||
|  | ||||
| # WHAT IS THIS? | ||||
| #  This script renames symbols in the API, updating SDL_oldnames.h and | ||||
| #  adding documentation for the change. | ||||
|  | ||||
| import argparse | ||||
| import os | ||||
| import pathlib | ||||
| import pprint | ||||
| import re | ||||
| from rename_symbols import create_regex_from_replacements, replace_symbols_in_path | ||||
|  | ||||
| SDL_ROOT = pathlib.Path(__file__).resolve().parents[1] | ||||
|  | ||||
| SDL_INCLUDE_DIR = SDL_ROOT / "include/SDL3" | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|     # Check whether we can still modify the ABI | ||||
|     version_header = pathlib.Path( SDL_INCLUDE_DIR / "SDL_version.h" ).read_text() | ||||
|     if not re.search("SDL_MINOR_VERSION\s+[01]\s", version_header): | ||||
|         raise Exception("ABI is frozen, symbols cannot be renamed") | ||||
|  | ||||
|     pattern = re.compile(r"\b%s\b" % args.oldname) | ||||
|  | ||||
|     # Find the symbol in the headers | ||||
|     if pathlib.Path(args.header).is_file(): | ||||
|         header = pathlib.Path(args.header) | ||||
|     else: | ||||
|         header = pathlib.Path(SDL_INCLUDE_DIR / args.header) | ||||
|  | ||||
|     if not header.exists(): | ||||
|         raise Exception("Couldn't find header %s" % header) | ||||
|  | ||||
|     if not args.skip_header_check and not pattern.search(header.read_text()): | ||||
|         raise Exception("Couldn't find %s in %s" % (args.oldname, header)) | ||||
|  | ||||
|     # Replace the symbol in source code and documentation | ||||
|     replacements = { args.oldname: args.newname } | ||||
|     regex = create_regex_from_replacements(replacements) | ||||
|     for dir in ['src', 'test', 'include', 'docs']: | ||||
|         replace_symbols_in_path(SDL_ROOT / dir, regex, replacements) | ||||
|  | ||||
|     add_symbol_to_oldnames(header.name, args.oldname, args.newname) | ||||
|     add_symbol_to_migration(header.name, args.type, args.oldname, args.newname) | ||||
|     add_symbol_to_whatsnew(args.type, args.oldname, args.newname) | ||||
|  | ||||
|  | ||||
| def add_line(lines, i, section): | ||||
|     lines.insert(i, section) | ||||
|     i += 1 | ||||
|     return i | ||||
|  | ||||
|  | ||||
| def add_content(lines, i, content, add_trailing_line): | ||||
|     if lines[i - 1] == "": | ||||
|         lines[i - 1] = content | ||||
|     else: | ||||
|         i = add_line(lines, i, content) | ||||
|  | ||||
|     if add_trailing_line: | ||||
|         i = add_line(lines, i, "") | ||||
|     return i | ||||
|  | ||||
|  | ||||
| def add_symbol_to_oldnames(header, oldname, newname): | ||||
|     file = (SDL_INCLUDE_DIR / "SDL_oldnames.h") | ||||
|     lines = file.read_text().splitlines() | ||||
|     mode = 0 | ||||
|     i = 0 | ||||
|     while i < len(lines): | ||||
|         line = lines[i] | ||||
|         if line == "#ifdef SDL_ENABLE_OLD_NAMES": | ||||
|             if mode == 0: | ||||
|                 mode = 1 | ||||
|                 section = ("/* ##%s */" % header) | ||||
|                 section_added = False | ||||
|                 content = ("#define %s %s" % (oldname, newname)) | ||||
|                 content_added = False | ||||
|             else: | ||||
|                 raise Exception("add_symbol_to_oldnames(): expected mode 0") | ||||
|         elif line == "#else /* !SDL_ENABLE_OLD_NAMES */": | ||||
|             if mode == 1: | ||||
|                 if not section_added: | ||||
|                     i = add_line(lines, i, section) | ||||
|  | ||||
|                 if not content_added: | ||||
|                     i = add_content(lines, i, content, True) | ||||
|  | ||||
|                 mode = 2 | ||||
|                 section = ("/* ##%s */" % header) | ||||
|                 section_added = False | ||||
|                 content = ("#define %s %s_renamed_%s" % (oldname, oldname, newname)) | ||||
|                 content_added = False | ||||
|             else: | ||||
|                 raise Exception("add_symbol_to_oldnames(): expected mode 1") | ||||
|         elif line == "#endif /* SDL_ENABLE_OLD_NAMES */": | ||||
|             if mode == 2: | ||||
|                 if not section_added: | ||||
|                     i = add_line(lines, i, section) | ||||
|  | ||||
|                 if not content_added: | ||||
|                     i = add_content(lines, i, content, True) | ||||
|  | ||||
|                 mode = 3 | ||||
|             else: | ||||
|                 raise Exception("add_symbol_to_oldnames(): expected mode 2") | ||||
|         elif line != "" and (mode == 1 or mode == 2): | ||||
|             if line.startswith("/* ##"): | ||||
|                 if section_added: | ||||
|                     if not content_added: | ||||
|                         i = add_content(lines, i, content, True) | ||||
|                         content_added = True | ||||
|                 elif line == section: | ||||
|                     section_added = True | ||||
|                 elif section < line: | ||||
|                     i = add_line(lines, i, section) | ||||
|                     section_added = True | ||||
|                     i = add_content(lines, i, content, True) | ||||
|                     content_added = True | ||||
|             elif line != "" and section_added and not content_added: | ||||
|                 if content == line: | ||||
|                     content_added = True | ||||
|                 elif content < line: | ||||
|                     i = add_content(lines, i, content, False) | ||||
|                     content_added = True | ||||
|         i += 1 | ||||
|  | ||||
|     file.write_text("\n".join(lines) + "\n") | ||||
|  | ||||
|  | ||||
| def add_symbol_to_migration(header, symbol_type, oldname, newname): | ||||
|     file = (SDL_ROOT / "docs/README-migration.md") | ||||
|     lines = file.read_text().splitlines() | ||||
|     section = ("## %s" % header) | ||||
|     section_added = False | ||||
|     note = ("The following %ss have been renamed:" % symbol_type) | ||||
|     note_added = False | ||||
|     content = ("* %s => %s" % (oldname, newname)) | ||||
|     content_added = False | ||||
|     mode = 0 | ||||
|     i = 0 | ||||
|     while i < len(lines): | ||||
|         line = lines[i] | ||||
|         if line.startswith("##") and line.endswith(".h"): | ||||
|             if line == section: | ||||
|                 section_added = True | ||||
|             elif section < line: | ||||
|                 break | ||||
|  | ||||
|         elif section_added and not note_added: | ||||
|             if note == line: | ||||
|                 note_added = True | ||||
|         elif note_added and not content_added: | ||||
|             if content == line: | ||||
|                 content_added = True | ||||
|             elif line == "" or content < line: | ||||
|                 i = add_line(lines, i, content) | ||||
|                 content_added = True | ||||
|         i += 1 | ||||
|  | ||||
|     if not section_added: | ||||
|         i = add_line(lines, i, section) | ||||
|         i = add_line(lines, i, "") | ||||
|  | ||||
|     if not note_added: | ||||
|         i = add_line(lines, i, note) | ||||
|  | ||||
|     if not content_added: | ||||
|         i = add_content(lines, i, content, True) | ||||
|  | ||||
|     file.write_text("\n".join(lines) + "\n") | ||||
|  | ||||
|  | ||||
| def add_symbol_to_whatsnew(symbol_type, oldname, newname): | ||||
|     file = (SDL_ROOT / "WhatsNew.txt") | ||||
|     lines = file.read_text().splitlines() | ||||
|     note = ("* The following %ss have been renamed:" % symbol_type) | ||||
|     note_added = False | ||||
|     content = ("    * %s => %s" % (oldname, newname)) | ||||
|     content_added = False | ||||
|     mode = 0 | ||||
|     i = 0 | ||||
|     while i < len(lines): | ||||
|         line = lines[i] | ||||
|         if not note_added: | ||||
|             if note == line: | ||||
|                 note_added = True | ||||
|         elif not content_added: | ||||
|             if content == line: | ||||
|                 content_added = True | ||||
|             elif not line.startswith("    *") or content < line: | ||||
|                 i = add_line(lines, i, content) | ||||
|                 content_added = True | ||||
|         i += 1 | ||||
|  | ||||
|     if not note_added: | ||||
|         i = add_line(lines, i, note) | ||||
|  | ||||
|     if not content_added: | ||||
|         i = add_line(lines, i, content) | ||||
|  | ||||
|     file.write_text("\r\n".join(lines) + "\r\n") | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|  | ||||
|     parser = argparse.ArgumentParser() | ||||
|     parser.add_argument('--skip-header-check', action='store_true') | ||||
|     parser.add_argument('header'); | ||||
|     parser.add_argument('type', choices=['enum', 'function', 'macro', 'structure']); | ||||
|     parser.add_argument('oldname'); | ||||
|     parser.add_argument('newname'); | ||||
|     args = parser.parse_args() | ||||
|  | ||||
|     try: | ||||
|         main() | ||||
|     except Exception as e: | ||||
|         print(e) | ||||
|         exit(-1) | ||||
|  | ||||
|     exit(0) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Sam Lantinga
					Sam Lantinga