#!/usr/bin/env python3
#####
# findsym2.py
# Translated from findsym.pl
#
# This script scans through multiple C++ source files to find all occurrences
# of the SYM(symbol_name) macro. It collects these unique symbol names and
# generates a header file containing declarations for these symbols. The purpose
# is to ensure that each symbol is translated only once when creating the
# symbol table.
#####
import re
import sys
import textwrap
# Retrieve the first command-line argument, which should be the name of the
# output header file.
if len(sys.argv) < 2:
print(
"usage: ./findsym2.py out_symbols.h file1.cc file2.cc ...",
file=sys.stderr,
)
sys.exit(1)
_, outname, *innames = sys.argv
# Attempt to open the output file in write mode.
with open(outname, "w", encoding="utf-8") as header:
# Write a predefined header comment block to the output file.
header.write(
textwrap.dedent(
"""\
/*****
* This file is automatically generated by findsym.py
* Changes will be overwritten.
*****/
// If the ADDSYMBOL macro is not already defined, define it with the default
// purpose of referring to an external pre-translated symbol, such that
// SYM(name) also refers to that symbol.
#ifndef ADDSYMBOL
#define ADDSYMBOL(name) extern sym::symbol PRETRANSLATED_SYMBOL_##name
#define SYM(name) PRETRANSLATED_SYMBOL_##name
#endif
"""
)
)
# Initialize an empty set to store unique symbols.
symbols = set()
# Iterate over each remaining command-line argument, which should be the names
# of C++ source files to process.
for inname in innames:
# Attempt to open the current input file in read mode.
with open(inname, "r", encoding="utf-8") as infile:
# Read the input file line by line.
for line in infile:
# Use a regular expression to find all occurrences of the SYM macro
# with a valid symbol name inside parentheses.
matches = re.findall(r"SYM\(([_A-Za-z][_A-Za-z0-9]*)\)", line)
for match in matches:
# Add each matched symbol name to the symbols set.
symbols.add(match)
# After collecting all unique symbols, iterate over the sorted list of symbol
# names.
for symbol in sorted(symbols):
# Concatenate the ADDSYMBOL macro with the provided symbol name and a
# newline character, then write it to the header file.
header.write(f"ADDSYMBOL({symbol});\n")