geany/scripts/dynamicsymbols.py
Matthew Brush a40ab0a4d9 Explicitly list symbols to dynamically export
Uses a Python script to generate a listing used by the linker to
determine which symbols to dynamically export. This provides finer
grained control of which symbols are dynamically exported, limiting
only to the ones needed for GtkBuilder signal connections.

The build system integration could probably be done a little cleaner.
2015-03-10 22:06:18 +01:00

74 lines
2.0 KiB
Python
Executable File

#!/usr/bin/env python
"""
Script to parse GtkBuilder XML file for signal handler references and list
them in a linker file for which symbols to dynamically export.
"""
import optparse
import os
import re
import sys
from xml.etree import ElementTree as ET
def find_handlers(xml_filename, excludes=[]):
def is_excluded(name, excludes):
for exclude in excludes:
m = re.match(exclude, name)
if m:
return True
return False
tree = ET.parse(xml_filename)
root = tree.getroot()
handlers = []
signals = root.findall(".//signal")
for signal in signals:
handler = signal.attrib["handler"]
if not is_excluded(handler, excludes):
handlers.append(handler)
return sorted(handlers)
def write_dynamic_list(handlers, output_file):
output_file.write("""\
/* This file was auto-generated by the `%s' script, do not edit. */
{
""" % os.path.basename(__file__))
for handler in handlers:
output_file.write("\t%s;\n" % handler)
output_file.write("};\n")
def main(args):
p = optparse.OptionParser(usage="%prog [-o FILE] XMLFILE")
p.add_option("-o", "--output", metavar="FILE", dest="output_file",
default="-", help="write the output to this file (default `-' for stdin)")
opts, args = p.parse_args(args)
output_file = None
try:
if opts.output_file == "-":
output_file = sys.stdout
else:
output_file = open(opts.output_file, 'w')
args = args[1:]
if len(args) == 0:
p.error("invalid XMLFILE argument, expecting a filename, got none")
elif len(args) > 1:
p.error("too many XMLFILE arguments, expecting a single filename")
handlers = find_handlers(args[0], ["gtk_.+"])
write_dynamic_list(handlers, output_file)
finally:
if output_file is not None and output_file is not sys.stdout:
output_file.close()
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))