FOREACH_ARG() hands the position of each argument as the expression
"count - N", which can be used as a value but cannot be pasted into an
identifier, because "##" pastes a single token. Hand it out as a
literal instead, so that an action macro can build a symbol name out of
it, which is what a subsystem needs when the link order of its objects
has to follow the declaration order.
The list is reversed through REVERSE_ARG() so that the position becomes
the level of the chain, and each step emits the recursion before its own
action so that the actions still come out in the order the arguments
were given. This is how the same problem is solved upstream in Zephyr,
whose FOR_EACH_IDX() also reverses the list before walking a per arity
chain.
The index values are unchanged, so the arithmetic use keeps working:
NOTE_PRINTF_TYPES(), the only user in tree, produces the same tags for
every argument count. It now supplies the leading zero itself, because
FOREACH_ARG() no longer expands to "0" when the list is empty. An empty
list expanding to nothing is what lets an action expanding to
declarations be used at file scope.
Assisted-by: Claude Code
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
Add generic support for link-time registration of struct instances,
modeled after the Zephyr STRUCT_SECTION_* mechanism:
- include/nuttx/iterable_sections.h: STRUCT_SECTION_ITERABLE/DECLARE/
FOREACH/GET/COUNT macros placing instances in name-sorted linker
sections delimited by _<type>_list_start/_end symbols (attributes
through the nuttx/compiler.h macros; FOREACH takes a caller-declared
iterator, like list_for_every_entry).
- include/nuttx/linker/iterable_sections.ld: ITERABLE_SECTION() macro
emitting the KEEP + SORT_BY_NAME collection statements (linker
scripts in ARCHSCRIPT are CPP-preprocessed).
- include/nuttx/linker/common-rom.ld / common-ram.ld: central
aggregators meant to be included by board linker scripts (inside
.text and .data respectively); subsystems register their sections
here guarded by their Kconfig options, so the fragments expand to
nothing on configurations that do not use them.
- CONFIG_ITERABLE_SECTIONS_LINKER_INSERT + include/nuttx/linker/
common-insert.ld (added before the board script by tools/Config.mk and
by the top-level CMakeLists.txt): optional zero-touch mode that
supplements the board script through GNU ld INSERT AFTER, collecting
the subsystems' ITERABLE_SECTION blocks in one output section; the
common-rom.ld/common-ram.ld fragments expand to nothing in that mode.
See the option help for the constraints.
- Documentation/components/iterable_sections.rst.
First user: the Zephyr zbus message bus port (apps/system/zbus in
nuttx-apps); its board integration comes in a companion PR.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>