summaryrefslogtreecommitdiffstats
path: root/tools/convert-glib-types.py
blob: aa714d7d8a8fbf03c8e41ee8f46641cab26ed71d (plain)
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
#!/usr/bin/env python3
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 1998 Gerald Combs
#
# SPDX-License-Identifier: GPL-2.0-or-later
'''\
convert-glib-types.py - Convert glib types to their C and C99 eqivalents.
'''

# Imports

import argparse
import glob
import platform
import re
import sys

padded_type_map = {}

type_map = {
    'gboolean': 'bool',
    'gchar': 'char',
    'guchar': 'unsigned char',
    'gint': 'int',
    'guint': 'unsigned', # Matches README.developer
    'glong': 'long',
    'gulong': 'unsigned long',
    'gint8': 'int8_t',
    'gint16': 'int16_t',
    'gint32': 'int32_t',
    'gint64': 'int64_t',
    'guint8': 'uint8_t',
    'guint16': 'uint16_t',
    'guint32': 'uint32_t',
    'guint64': 'uint64_t',
    'gfloat': 'float',
    'gdouble': 'double',
    'gpointer ': 'void *', # 'void *foo' instead of 'void * foo'
    'gpointer': 'void *',
    # Is gsize the same as size_t on the platforms we support?
    # https://gitlab.gnome.org/GNOME/glib/-/issues/2493
    'gsize': 'size_t',
    'gssize': 'ssize_t',
}

definition_map = {
    'TRUE': 'true',
    'FALSE': 'false',
    'G_MAXINT8': 'INT8_MAX',
    'G_MAXINT16': 'INT16_MAX',
    'G_MAXINT32': 'INT32_MAX',
    'G_MAXINT64': 'INT64_MAX',
    'G_MAXINT': 'INT_MAX',
    'G_MAXUINT8': 'UINT8_MAX',
    'G_MAXUINT16': 'UINT16_MAX',
    'G_MAXUINT32': 'UINT32_MAX',
    'G_MAXUINT64': 'UINT64_MAX',
    'G_MAXUINT': 'UINT_MAX',
    'G_MININT8': 'INT8_MIN',
    'G_MININT16': 'INT16_MIN',
    'G_MININT32': 'INT32_MIN',
    'G_MININT64': 'INT64_MIN',
    'G_MININT': 'INT_MIN',
}

format_spec_map = {
    'G_GINT64_FORMAT': 'PRId64',
    'G_GUINT64_FORMAT': 'PRIu64',
}

def convert_file(file):
    lines = ''
    try:
        with open(file, 'r') as f:
            lines = f.read()
            for glib_type, c99_type in padded_type_map.items():
                lines = lines.replace(glib_type, c99_type)
            for glib_type, c99_type in type_map.items():
                lines = re.sub(rf'([^"])\b{glib_type}\b([^"])', rf'\1{c99_type}\2', lines, flags=re.MULTILINE)
            for glib_define, c99_define in definition_map.items():
                lines = re.sub(rf'\b{glib_define}\b', rf'{c99_define}', lines, flags=re.MULTILINE)
            for glib_fmt_spec, c99_fmt_spec in format_spec_map.items():
                lines = re.sub(rf'\b{glib_fmt_spec}\b', rf'{c99_fmt_spec}', lines, flags=re.MULTILINE)
    except IsADirectoryError:
        sys.stderr.write(f'{file} is a directory.\n')
        return
    except UnicodeDecodeError:
        sys.stderr.write(f"{file} isn't valid UTF-8.\n")
        return
    except:
        sys.stderr.write(f'Unable to open {file}.\n')
        return

    with open(file, 'w') as f:
        f.write(lines)
    print(f'Converted {file}')

def main():
    parser = argparse.ArgumentParser(description='Convert glib types to their C and C99 eqivalents.')
    parser.add_argument('files', metavar='FILE', nargs='*')
    args = parser.parse_args()

    # Build a padded version of type_map which attempts to preseve alignment
    for glib_type, c99_type in type_map.items():
        pg_type = glib_type + '  '
        pc_type = c99_type + ' '
        pad_len = max(len(pg_type), len(pc_type))
        padded_type_map[f'{pg_type:{pad_len}s}'] = f'{pc_type:{pad_len}s}'

    files = []
    if platform.system() == 'Windows':
        for arg in args.files:
            files += glob.glob(arg)
    else:
        files = args.files

    for file in files:
        convert_file(file)

# On with the show

if __name__ == "__main__":
    sys.exit(main())