gbranden pushed a commit to branch master
in repository groff.
commit d0886007a98ecb33857061f698c7801559c98b8c
Author: G. Branden Robinson <[email protected]>
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 <[email protected]>
+
+ [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 <[email protected]>
[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
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit