File: rename_api.py

package info (click to toggle)
sdl2-compat 2.32.54%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 52,892 kB
  • sloc: ansic: 93,277; python: 1,549; sh: 569; makefile: 45; javascript: 21; cpp: 11
file content (158 lines) | stat: -rwxr-xr-x 4,562 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env python3
#
# 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
import sys
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_ttf"
SDL_BUILD_SCRIPTS = SDL_ROOT / "build-scripts"


def main():
    if len(args.args) == 0 or (len(args.args) % 2) != 0:
        print("Usage: %s [-h] [--skip-header-check] {enum,function,hint,structure,symbol} [old new ...]" % sys.argv[0])
        exit(1)

    # Check whether we can still modify the ABI
    header_text = pathlib.Path( SDL_INCLUDE_DIR / "SDL_ttf.h" ).read_text()
    if not re.search(r"SDL_TTF_MINOR_VERSION\s+[01]\s", header_text):
        raise Exception("ABI is frozen, symbols cannot be renamed")

    # Replace the symbols in source code
    replacements = {}
    i = 0
    while i < len(args.args):
        oldname = args.args[i + 0]
        newname = args.args[i + 1]

        if not args.skip_header_check and not re.search((r"\b%s\b" % oldname), header_text):
            raise Exception("Couldn't find %s in %s" % (oldname, header))

        replacements[ oldname ] = newname
        i += 2

    regex = create_regex_from_replacements(replacements)
    for dir in ["src", "examples", "include", "cmake/test"]:
        replace_symbols_in_path(SDL_ROOT / dir, regex, replacements)

    # Replace the symbols in documentation
    i = 0
    while i < len(args.args):
        oldname = args.args[i + 0]
        newname = args.args[i + 1]

        add_symbol_to_migration(args.type, oldname, newname)
        add_symbol_to_coccinelle(args.type, oldname, newname)
        i += 2


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_coccinelle(symbol_type, oldname, newname):
    file = open(SDL_BUILD_SCRIPTS / "SDL_migration.cocci", "a")
    # Append-adds at last

    if symbol_type == "function":
        file.write("@@\n")
        file.write("@@\n")
        file.write("- %s\n" % oldname)
        file.write("+ %s\n" % newname)
        file.write("  (...)\n")

    if symbol_type == "symbol":
        file.write("@@\n")
        file.write("@@\n")
        file.write("- %s\n" % oldname)
        file.write("+ %s\n" % newname)

    # double check ?
    if symbol_type == "hint":
        file.write("@@\n")
        file.write("@@\n")
        file.write("- %s\n" % oldname)
        file.write("+ %s\n" % newname)

    if symbol_type == "enum" or symbol_type == "structure":
        file.write("@@\n")
        file.write("typedef %s, %s;\n" % (oldname, newname))
        file.write("@@\n")
        file.write("- %s\n" % oldname)
        file.write("+ %s\n" % newname)

    file.close()


def add_symbol_to_migration(symbol_type, oldname, newname):
    file = (SDL_ROOT / "docs/README-migration.md")
    lines = file.read_text().splitlines()
    note = ("The following %ss have been renamed:" % symbol_type)
    note_added = False
    if symbol_type == "function":
        content = ("* %s() => %s()" % (oldname, newname))
    else:
        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 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 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")


if __name__ == "__main__":

    parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
    parser.add_argument("--skip-header-check", action="store_true")
    parser.add_argument("type", choices=["enum", "function", "hint", "structure", "symbol"])
    parser.add_argument("args", nargs="*")
    args = parser.parse_args()

    try:
        main()
    except Exception as e:
        print(e)
        exit(-1)

    exit(0)