2
0
mirror of https://github.com/boostorg/json.git synced 2026-01-19 04:12:14 +00:00
Files
json/pretty_printers/generate-gdb-header.py
2024-12-26 15:06:34 +03:00

151 lines
4.2 KiB
Python
Executable File

#!/usr/bin/env python
#
# Copyright (c) 2024 Dmitry Arkhipov (grisumbras@yandex.ru)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Official repository: https://github.com/boostorg/json
#
import argparse
import os
import random
import re
import sys
_top = '''\
#if defined(__ELF__)
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Woverlength-strings"
#elif defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Woverlength-strings"
#endif
__asm__(
".pushsection \\\".debug_gdb_scripts\\\", \\\"MS\\\",%progbits,1\\n"
".ascii \\\"\\\\4gdb.inlined-script.{script_id}\\\\n\\\"\\n"
'''
_bottom = '''\
".byte 0\\n"
".popsection\\n");
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
#endif // defined(__ELF__)
'''
class Nullcontext():
def __init__(self):
pass
def __enter__(self):
pass
def __exit__(self, exc_type, exc_value, traceback):
pass
def parse_args(args):
parser = argparse.ArgumentParser(
prog=args[0],
description=(
'Converts a Python script into a C header '
'that pushes that script into .debug_gdb_scripts ELF section'))
parser.add_argument(
'input',
help='Input file')
parser.add_argument(
'output',
nargs='?',
help='Output file; STDOUT by default')
parser.add_argument(
'--header-guard',
help=(
'Header guard macro to use; '
'by default deduced from the output file name'))
parser.add_argument(
'--disable-macro',
default='BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS',
help=(
'Macro to disable pretty printer embedding; '
'by default BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS'))
return parser.parse_args(args[1:])
def write_front_matter(header, header_guard, disable_macro, source):
header.write(
'// Autogenerated from %s by boost-pretty-printers\n\n' % os.path.basename(source))
if header_guard:
header.write('#ifndef %s\n' % header_guard)
header.write('#define %s\n\n' % header_guard)
if disable_macro:
header.write('#ifndef %s\n\n' % disable_macro)
header.write(
_top.format(script_id=header_guard or str(random.random()) ))
def write_back_matter(header, header_guard, disable_macro):
header.write(_bottom)
if disable_macro:
header.write('\n#endif // %s\n' % disable_macro)
if header_guard:
header.write('\n#endif // %s\n' % header_guard)
def main(args, stdin, stdout):
args = parse_args(args)
header_guard = args.header_guard
if header_guard is None:
if args.output:
header_guard = os.path.basename(args.output).upper()
if args.output:
header = open(args.output, 'w', encoding='utf-8')
header_ctx = header
else:
header = stdout
header_ctx = Nullcontext()
not_whitespace = re.compile('\\S', re.U)
with open(args.input, 'r', encoding='utf-8') as script:
with header_ctx:
check_for_attribution = True
for line in script:
if not not_whitespace.search(line):
header.write('\n')
continue
if check_for_attribution:
if line.startswith('#!'): # shebang
continue
elif line.startswith('#'):
header.write('// ')
header.write(line[1:])
continue
else:
write_front_matter(
header,
header_guard,
args.disable_macro,
args.input)
check_for_attribution = False
header.write(' ".ascii \\"')
header.write(line[:-1])
header.write('\\\\n\\"\\n"\n')
write_back_matter(header, header_guard, args.disable_macro)
if __name__ == '__main__':
main(sys.argv, sys.stdin, sys.stdout)