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 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
#!/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 equivalents.
'''
# Imports
import argparse
import glob
import platform
import re
import sys
padded_type_map = {}
type_map = {
'gboolean': 'bool',
'gchar': 'char',
'guchar': 'unsigned char',
'gshort': 'int16_t',
'gushort': 'uint16_t',
'gint': 'int',
'guint': 'unsigned', # Matches README.developer
# Our remaining glong instances probably shouldn't be converted, e.g.
# sequence_analysis.c:350
# '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 *',
'gconstpointer ': 'const void *', # 'void *foo' instead of 'void * foo'
'gconstpointer': 'const void *',
'gintptr': 'intptr_t',
'guintptr': 'uintptr_t',
# 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 = {
'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',
'G_MINFLOAT': 'FLT_MIN',
'G_MAXFLOAT': 'FLT_MAX',
'G_MINDOUBLE': 'DBL_MIN',
'G_MAXDOUBLE': 'DBL_MAX',
'G_GINT64_CONSTANT': 'INT64_C',
'G_GUINT64_CONSTANT': 'UINT64_C',
}
tf_definition_map = {
'TRUE': 'true',
'FALSE': 'false',
}
format_spec_map = {
'G_GINT64_FORMAT': 'PRId64',
'G_GUINT64_FORMAT': 'PRIu64',
}
api_map = {
'tvb_get_guint8': 'tvb_get_uint8',
'tvb_get_gint8': 'tvb_get_int8',
'tvb_get_guint16': 'tvb_get_uint16',
'tvb_get_gint16': 'tvb_get_int16',
'tvb_get_guint24': 'tvb_get_uint24',
'tvb_get_gint24': 'tvb_get_int24',
'tvb_get_guint32': 'tvb_get_uint32',
'tvb_get_gint32': 'tvb_get_int32',
'tvb_get_guint40': 'tvb_get_uint40',
'tvb_get_gint40': 'tvb_get_int40',
'tvb_get_guint48': 'tvb_get_uint48',
'tvb_get_gint48': 'tvb_get_int48',
'tvb_get_guint56': 'tvb_get_uint56',
'tvb_get_gint56': 'tvb_get_int56',
'tvb_get_guint64': 'tvb_get_uint64',
'tvb_get_gint64': 'tvb_get_int64',
'tvb_find_guint8': 'tvb_find_uint8',
'tvb_find_guint16': 'tvb_find_uint16',
'tvb_ws_mempbrk_pattern_guint8': 'tvb_ws_mempbrk_pattern_uint8',
'guint32_to_str_buf': 'uint32_to_str_buf',
'guint64_to_str_buf': 'uint64_to_str_buf',
'get_nonzero_guint32': 'get_nonzero_uint32',
'get_guint32': 'get_uint32',
'guint8_to_hex': 'uint8_to_hex',
}
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_tf_define, c99_define in tf_definition_map.items():
lines = re.sub(rf'\b{glib_tf_define}\b([^\'"])', rf'{c99_define}\1', 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)
for glib_api, c99_api in api_map.items():
lines = re.sub(rf'\b{glib_api}\b', rf'{c99_api}', 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 Exception:
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 equivalents.')
parser.add_argument('files', metavar='FILE', nargs='*')
args = parser.parse_args()
# Build a padded version of type_map which attempts to preserve 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())
|