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

Reply via email to