From 720f2fad24076e0159ef9f853354ba31e0c2369c Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Mon, 5 Feb 2024 19:46:56 -0700 Subject: [PATCH] :sparkles: Add capabilities to gen_str_catalog.py - Properly handle multiple input libraries - Allow extra input JSON to be copied to output --- cmake/string_catalog.cmake | 28 ++++++----- test/CMakeLists.txt | 17 +++++-- .../log/{catalog_lib.cpp => catalog1_lib.cpp} | 0 test/log/catalog2_lib.cpp | 24 ++++++++++ test/log/catalog_extra.json | 3 ++ tools/gen_str_catalog.py | 46 +++++++++++++------ 6 files changed, 88 insertions(+), 30 deletions(-) rename test/log/{catalog_lib.cpp => catalog1_lib.cpp} (100%) create mode 100644 test/log/catalog2_lib.cpp create mode 100644 test/log/catalog_extra.json diff --git a/cmake/string_catalog.cmake b/cmake/string_catalog.cmake index 1f1657cc..09db54bc 100644 --- a/cmake/string_catalog.cmake +++ b/cmake/string_catalog.cmake @@ -2,27 +2,31 @@ function(gen_str_catalog) set(options "") set(oneValueArgs OUTPUT_CPP OUTPUT_XML OUTPUT_JSON GEN_STR_CATALOG OUTPUT_LIB) - set(multiValueArgs INPUT_LIBS) + set(multiValueArgs INPUT_JSON INPUT_LIBS) cmake_parse_arguments(SC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - foreach(X IN LISTS SC_INPUT_LIBS) + list(TRANSFORM SC_INPUT_LIBS + PREPEND "${CMAKE_CURRENT_BINARY_DIR}/undefined_symbols_" + OUTPUT_VARIABLE UNDEFS) + list(TRANSFORM UNDEFS APPEND ".txt") + + foreach(LIB UNDEF IN ZIP_LISTS SC_INPUT_LIBS UNDEFS) add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/undefined_symbols.txt - DEPENDS ${X} - COMMAND ${CMAKE_NM} -uC "lib${X}.a" > - ${CMAKE_CURRENT_BINARY_DIR}/undefined_symbols.txt) + OUTPUT ${UNDEF} + DEPENDS ${LIB} + COMMAND ${CMAKE_NM} -uC "$" > "${UNDEF}") endforeach() + list(TRANSFORM SC_INPUT_JSON PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/") + add_custom_command( OUTPUT ${SC_OUTPUT_CPP} ${SC_OUTPUT_JSON} ${SC_OUTPUT_XML} COMMAND - ${Python3_EXECUTABLE} ${SC_GEN_STR_CATALOG} --input - ${CMAKE_CURRENT_BINARY_DIR}/undefined_symbols.txt --cpp_output - ${SC_OUTPUT_CPP} --json_output ${SC_OUTPUT_JSON} --xml_output - ${SC_OUTPUT_XML} - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/undefined_symbols.txt - ${SC_GEN_STR_CATALOG}) + ${Python3_EXECUTABLE} ${SC_GEN_STR_CATALOG} --input ${UNDEFS} + --json_input ${SC_INPUT_JSON} --cpp_output ${SC_OUTPUT_CPP} + --json_output ${SC_OUTPUT_JSON} --xml_output ${SC_OUTPUT_XML} + DEPENDS ${UNDEFS} ${INPUT_JSON} ${SC_GEN_STR_CATALOG}) add_library(${SC_OUTPUT_LIB} STATIC ${SC_OUTPUT_CPP}) target_link_libraries(${SC_OUTPUT_LIB} PUBLIC cib) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3436cd62..8558d8d0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -73,9 +73,12 @@ add_tests( sc/string_constant seq/sequencer) -add_library(catalog_lib log/catalog_lib.cpp) -target_include_directories(catalog_lib PRIVATE ${CMAKE_SOURCE_DIR}/test/) -target_link_libraries(catalog_lib PRIVATE warnings cib) +add_library(catalog1_lib log/catalog1_lib.cpp) +add_library(catalog2_lib log/catalog2_lib.cpp) +target_include_directories(catalog1_lib PRIVATE ${CMAKE_SOURCE_DIR}/test/) +target_include_directories(catalog2_lib PRIVATE ${CMAKE_SOURCE_DIR}/test/) +target_link_libraries(catalog1_lib PRIVATE warnings cib) +target_link_libraries(catalog2_lib PRIVATE warnings cib) gen_str_catalog( GEN_STR_CATALOG ${CMAKE_SOURCE_DIR}/tools/gen_str_catalog.py @@ -88,7 +91,10 @@ gen_str_catalog( OUTPUT_LIB catalog_strings INPUT_LIBS - catalog_lib) + catalog1_lib + catalog2_lib + INPUT_JSON + log/catalog_extra.json) add_unit_test( log_catalog_test @@ -97,7 +103,8 @@ add_unit_test( log/catalog_app.cpp LIBRARIES warnings - catalog_lib + catalog1_lib + catalog2_lib catalog_strings) add_compile_fail_test(msg/fail/impossible_match_callback.cpp LIBRARIES warnings diff --git a/test/log/catalog_lib.cpp b/test/log/catalog1_lib.cpp similarity index 100% rename from test/log/catalog_lib.cpp rename to test/log/catalog1_lib.cpp diff --git a/test/log/catalog2_lib.cpp b/test/log/catalog2_lib.cpp new file mode 100644 index 00000000..63081e98 --- /dev/null +++ b/test/log/catalog2_lib.cpp @@ -0,0 +1,24 @@ +#include "catalog_concurrency.hpp" + +#include +#include + +#include + +template <> inline auto conc::injected_policy<> = test_conc_policy{}; + +extern int log_calls; + +namespace { +struct test_log_args_destination { + auto log_by_args(std::uint32_t, auto...) -> void { ++log_calls; } +}; +} // namespace + +auto log_two_rt_args() -> void; + +auto log_two_rt_args() -> void { + auto cfg = logging::mipi::config{test_log_args_destination{}}; + cfg.logger.log_msg( + format("D string with {} and {} placeholder"_sc, 1, 2)); +} diff --git a/test/log/catalog_extra.json b/test/log/catalog_extra.json new file mode 100644 index 00000000..770af1f6 --- /dev/null +++ b/test/log/catalog_extra.json @@ -0,0 +1,3 @@ +{ + "extra_key": "extra_value" +} diff --git a/tools/gen_str_catalog.py b/tools/gen_str_catalog.py index 04bbf5b3..72fd3aa5 100755 --- a/tools/gen_str_catalog.py +++ b/tools/gen_str_catalog.py @@ -1,9 +1,10 @@ #!/usr/bin/env python3 import argparse +import itertools +import json import re import sys -import json import xml.etree.ElementTree as et @@ -80,17 +81,23 @@ def extract_message(line_num, catalog_m): ) -def read_input(filename): +def read_input(filenames): catalog_re = re.compile("^.+?(unsigned int catalog<(.+?)>\(\))$") - with open(filename, "r") as f: - matching_lines = filter( - lambda p: p[1] is not None, - ((num + 1, catalog_re.match(line.strip())) for num, line in enumerate(f)), - ) - messages = (extract_message(*m) for m in matching_lines) - unique_messages = {i[0][0]: i for i in messages}.values() - return {item[0]: {**item[1], "id": i} for i, item in enumerate(unique_messages)} + def read_file(filename): + with open(filename, "r") as f: + matching_lines = filter( + lambda p: p[1] is not None, + ( + (num + 1, catalog_re.match(line.strip())) + for num, line in enumerate(f) + ), + ) + return [extract_message(*m) for m in matching_lines] + + messages = itertools.chain.from_iterable(read_file(f) for f in filenames) + unique_messages = {i[0][0]: i for i in messages}.values() + return {item[0]: {**item[1], "id": i} for i, item in enumerate(unique_messages)} def make_cpp_defn(types, msg): @@ -111,8 +118,11 @@ def write_cpp(messages, filename): f.write("\n".join(cpp_defns)) -def write_json(messages, filename): +def write_json(messages, extra_inputs, filename): str_catalog = dict(messages=list(messages.values())) + for extra in extra_inputs: + with open(extra, "r") as f: + str_catalog.update(json.load(f)) with open(filename, "w") as f: json.dump(str_catalog, f, indent=4) @@ -167,9 +177,10 @@ def parse_cmdline(): parser.add_argument( "--input", type=str, + nargs="+", required=True, help=( - "Input filename: a file of undefined symbols produced by running" + "Input filename(s): file(s) of undefined symbols produced by running" "`nm -uC `." ), ) @@ -182,6 +193,13 @@ def parse_cmdline(): parser.add_argument( "--xml_output", type=str, help="Output filename for generated XML." ) + parser.add_argument( + "--json_input", + type=str, + nargs="*", + default=[], + help="Extra JSON inputs to copy into the output.", + ) parser.add_argument( "--client_name", type=str, @@ -218,8 +236,10 @@ def main(): if args.cpp_output: write_cpp(messages, args.cpp_output) + if args.json_output: - write_json(messages, args.json_output) + write_json(messages, args.json_input, args.json_output) + if args.xml_output: write_xml( messages,