gbranden pushed a commit to branch master in repository groff. commit d0886007a98ecb33857061f698c7801559c98b8c Author: G. Branden Robinson <g.branden.robin...@gmail.com> AuthorDate: Mon Mar 3 11:16:08 2025 -0600
[troff]: Implement recursive node dumping (7/9). Create new `struct container_node` for node types that contain a (possibly singleton) list of other nodes. * src/roff/troff/node.h (container_node): Do it. Declare constructors mirroring those of `struct node` (but with an extra argument for the contained node list); a destructor; and virtual member function `dump_node()`, overriding that of `struct node`. * src/roff/troff/node.cpp (dump_node_list): New function, a counterpart to `copy_node_list()` and `delete_node_list()`, walks a singly-linked list of nodes and directs each to dump itself. (container_node::container_node, container_node::~container_node) (container_node::dump_node): Define the foregoing. (container_node::~container_node): Destructor always calls `delete_node_list()` because some node types seem intended to contain only one other node, and others a list. Unifying the destruction procedure seems more likely to avoid memory leaks, at a cost per destroyed object derived from `container_node` of an additional function call and a test of a pointer for nullity--but only for objects of classes where this wasn't already happening. --- ChangeLog | 25 ++++++++++++++++++ src/roff/troff/node.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ src/roff/troff/node.h | 14 ++++++++++ 3 files changed, 108 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0f5f87dee..0caffdc20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2025-03-03 G. Branden Robinson <g.branden.robin...@gmail.com> + + [troff]: Create new `struct container_node` for node types that + contain a {possibly singleton} list of other nodes. + + * src/roff/troff/node.h (container_node): Do it. Declare + constructors mirroring those of `struct node` (but with an extra + argument for the contained node list); a destructor; and virtual + member function `dump_node()`, overriding that of `struct node`. + * src/roff/troff/node.cpp (dump_node_list): New function, a + counterpart to `copy_node_list()` and `delete_node_list()`, + walks a singly-linked list of nodes and directs each to dump + itself. + (container_node::container_node) + (container_node::~container_node, container_node::dump_node): + Define the foregoing. + (container_node::~container_node): Destructor always calls + `delete_node_list()` because some node types seem intended to + contain only one other node, and others a list. Unifying the + destruction procedure seems more likely to avoid memory leaks, + at a cost per destroyed object derived from `container_node` + of an additional function call and a test of a pointer for + nullity--but only for objects of classes where this wasn't + already happening. + 2025-03-03 G. Branden Robinson <g.branden.robin...@gmail.com> [troff]: The property of the environment that holds the pending diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp index d9f0e2a2d..a8e08f6c0 100644 --- a/src/roff/troff/node.cpp +++ b/src/roff/troff/node.cpp @@ -2450,6 +2450,25 @@ void delete_node_list(node *n) } } +void dump_node_list(node *n) +{ + bool need_comma = false; + fputs("\"contents\": [", stderr); + while (n != 0 /* nullptr */) { + if (need_comma) + fputs(", ", stderr); + n->dump_node(); + need_comma = true; + n = n->next; + } + // !need_comma implies that the list was empty. JSON convention is to + // put a space between an empty pair of square brackets. + if (!need_comma) + fputc(' ', stderr); + fputc(']', stderr); + fflush(stderr); +} + node *dbreak_node::copy() { dbreak_node *p = new dbreak_node(copy_node_list(none), @@ -2633,6 +2652,56 @@ void node::dump_node() fflush(stderr); } +container_node::container_node(node *contents) +: node(), nodes(contents) +{ +} + +container_node::container_node(node *nxt, node *contents) +: node(nxt), nodes(contents) +{ +} + +// `left_italic_corrected_node` uses an initially empty container. +container_node::container_node(node *nxt, statem *s, int divl) +: node(nxt, s, divl), nodes(0 /* nullptr */) +{ +} + +#if 0 +container_node::container_node(node *nxt, statem *s, node *contents) +: node(nxt, s), nodes(contents) +{ +} +#endif + +container_node::container_node(node *nxt, statem *s, int divl, + node *contents) +: node(nxt, s, divl), nodes(contents) +{ +} + +container_node::container_node(node *nxt, statem *s, int divl, + bool special, node *contents) +: node(nxt, s, divl, special), nodes(contents) +{ +} + +container_node::~container_node() +{ + delete_node_list(nodes); +} + +void container_node::dump_node() +{ + fputc('{', stderr); + dump_properties(); + fputs(", ", stderr); + dump_node_list(nodes); + fputc('}', stderr); + fflush(stderr); +} + // TODO: Move this into env.cpp. void dump_node_list_in_reverse(node *nlist) { diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h index 99d4f6c92..37fa68d8e 100644 --- a/src/roff/troff/node.h +++ b/src/roff/troff/node.h @@ -415,6 +415,20 @@ public: void dump_properties(); }; +struct container_node : public node { + node *nodes; + container_node(node * /* contents */); + container_node(node * /* next */, node * /* contents */); + container_node(node * /* next */, statem *, int); + //container_node(node * /* next */, statem *, node * /* contents */); + container_node(node * /* next */, statem *, int, + node * /* contents */); + container_node(node * /* next */, statem *, int, bool, + node * /* contents */); + ~container_node(); + virtual void dump_node(); +}; + // TODO: Derive from abstract class `container_node`. class hline_node : public node { hunits x; _______________________________________________ groff-commit mailing list groff-commit@gnu.org https://lists.gnu.org/mailman/listinfo/groff-commit