Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cmake/string_catalog.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ function(gen_str_catalog)
GUID_ID
GUID_MASK
MODULE_ID_MAX
RESERVED_IDS
OUTPUTS_TARGET)
set(multiValueArgs INPUT_JSON INPUT_LIBS INPUT_HEADERS STABLE_JSON)
cmake_parse_arguments(SC "${options}" "${oneValueArgs}" "${multiValueArgs}"
Expand Down Expand Up @@ -68,6 +69,9 @@ function(gen_str_catalog)
if(SC_MODULE_ID_MAX)
set(MODULE_ID_MAX_ARG --module_id_max ${SC_MODULE_ID_MAX})
endif()
if(SC_RESERVED_IDS)
set(RESERVED_IDS_ARG --reserved_ids ${SC_RESERVED_IDS})
endif()
if(NOT SC_GEN_STR_CATALOG)
set(SC_GEN_STR_CATALOG ${GEN_STR_CATALOG})
endif()
Expand All @@ -80,7 +84,7 @@ function(gen_str_catalog)
--cpp_output ${SC_OUTPUT_CPP} --json_output ${SC_OUTPUT_JSON}
--xml_output ${SC_OUTPUT_XML} --stable_json ${STABLE_JSON}
${FORGET_ARG} ${CLIENT_NAME_ARG} ${VERSION_ARG} ${GUID_ID_ARG}
${GUID_MASK_ARG} ${MODULE_ID_MAX_ARG}
${GUID_MASK_ARG} ${MODULE_ID_MAX_ARG} ${RESERVED_IDS_ARG}
DEPENDS ${UNDEFS} ${INPUT_JSON} ${SC_GEN_STR_CATALOG} ${STABLE_JSON}
COMMAND_EXPAND_LISTS)

Expand Down
2 changes: 2 additions & 0 deletions test/log/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ gen_str_catalog(
"01234567-89ab-cdef-0123-456789abcdef"
GUID_MASK
"ffffffff-ffff-ffff-ffff-ffffffffffff"
RESERVED_IDS
"1,1000-1005,1010"
OUTPUTS_TARGET
test_catalog_json)

Expand Down
44 changes: 39 additions & 5 deletions tools/gen_str_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,31 @@ def split_args(s: str) -> list[str]:
return args


class Intervals:
def __init__(self, text: str):
self.intervals = []
for i in text.split(","):
rng = i.split("-")
if rng != [""]:
start = int(rng[0], 0)
self.intervals.append(
(start, int(rng[1], 0) if len(rng) == 2 else start)
)

def contains(self, v: int) -> bool:
return any(map(lambda x: v >= x[0] and v <= x[1], self.intervals))

def __str__(self):
rngs = map(
lambda x: f"{x[0]}-{x[1]}" if x[0] != x[1] else f"{x[0]}",
self.intervals,
)
return ",".join(rngs)

def __repr__(self):
return f'Intervals("{self}")'


class Message:
cpp_prefix: str = "sc::message<sc::undefined"

Expand Down Expand Up @@ -152,7 +177,7 @@ def assign_ids_with(items, id_fn):
return list(sorted_items)


def assign_ids(messages, modules, stable_data):
def assign_ids(messages, modules, stable_data, reserved_ids):
def get_id(stables, gen, obj):
key = obj.key()
if key in stables:
Expand All @@ -167,7 +192,10 @@ def get_id(stables, gen, obj):
stable_modules[module.key()] = module

old_msg_ids = set(m.id for m in stable_msgs.values())
msg_id_gen = itertools.filterfalse(old_msg_ids.__contains__, itertools.count(0))
msg_id_gen = itertools.filterfalse(
lambda x: old_msg_ids.__contains__(x) or reserved_ids.contains(x),
itertools.count(0),
)
get_msg_id = partial(get_id, stable_msgs, msg_id_gen)

old_module_ids = set(m.id for m in stable_modules.values())
Expand All @@ -182,7 +210,7 @@ def get_id(stables, gen, obj):
)


def read_input(filenames: list[str], stable_data):
def read_input(filenames: list[str], stable_data, reserved_ids):
line_re = re.compile(r"^.*unsigned (?:int|long) (catalog|module)<(.+?)>\(\)$")

def read_file(filename):
Expand All @@ -199,7 +227,7 @@ def read_file(filename):
modules = filter(lambda x: isinstance(x, Module), items)
unique_modules = {m.key(): m for m in modules}.values()

return assign_ids(unique_messages, unique_modules, stable_data)
return assign_ids(unique_messages, unique_modules, stable_data, reserved_ids)


def make_cpp_scoped_enum_decl(e: str, ut: str) -> str:
Expand Down Expand Up @@ -542,6 +570,12 @@ def parse_cmdline():
default=127,
help="The maximum value of a module ID.",
)
parser.add_argument(
"--reserved_ids",
type=lambda x: Intervals(x),
default="",
help="A list of (inclusive) ranges of string IDs that should be reserved and not used. e.g. '1-5,10-15,20'",
)
return parser.parse_args()


Expand All @@ -565,7 +599,7 @@ def main():

stable_data = read_stable(args.stable_json)
try:
messages, modules = read_input(args.input, stable_data)
messages, modules = read_input(args.input, stable_data, args.reserved_ids)
except Exception as e:
raise Exception(f"{str(e)} from file {args.input}")

Expand Down
24 changes: 24 additions & 0 deletions tools/gen_str_catalog_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,27 @@ def test_module_cpp_type():
def test_module_json():
m = gen.Module("abc", 42)
assert m.to_json() == {"string": "abc", "id": 42}


test_ints = "1-5,8-10,15"


def test_intervals():
m = gen.Intervals(test_ints)
assert m.contains(1)
assert m.contains(5)
assert not m.contains(6)
assert m.contains(8)
assert m.contains(10)
assert m.contains(15)


def test_empty_intervals():
m = gen.Intervals("")
assert not m.contains(1)


def test_intervals_repr():
m = gen.Intervals(test_ints)
assert f"{m}" == "1-5,8-10,15"
assert repr(m) == 'Intervals("1-5,8-10,15")'
Loading