gbranden pushed a commit to branch master
in repository groff.

commit 1a38b319a23da6160bfc3009bc12717a01f2614b
Author: G. Branden Robinson <g.branden.robin...@gmail.com>
AuthorDate: Thu Sep 18 00:02:09 2025 -0500

    [troff]: Refactor `node` class hierarchy.
    
    Make `node` an abstract class.  The `asciify` feature had several bugs,
    and I think it's because the class design permitted derived classes to
    reuse the `node` base class's `asciify` member function, which
    robotically appended the `this` object to the macro pointed to in the
    function argument.  In most cases, the correct "asciification" of a node
    is to do nothing, discarding it.  Rather than making the member function
    empty in the base class, I prefer to make the base class abstract to
    force conscious consideration of how each derived class should be
    "asciified".
    
    * src/roff/troff/node.h: Mark `add_char()`, `asciify()`, and
      `add_italic_correction()` member functions as `virtual`.  Further mark
      `asciify` as _pure_ virtual (notation: "= 0").
    
    * src/roff/troff/node.cpp (node::asciify): Delete.
---
 ChangeLog               | 18 ++++++++++++++++++
 src/roff/troff/node.cpp |  6 ------
 src/roff/troff/node.h   |  6 +++---
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a2e7d9610..2815b0a4a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2025-09-17  G. Branden Robinson <g.branden.robin...@gmail.com>
+
+       [troff]: Refactor `node` class hierarchy.  Make `node` an
+       abstract class.  The `asciify` feature had several bugs, and I
+       think it's because the class design permitted derived classes to
+       reuse the `node` base class's `asciify` member function, which
+       robotically appended the `this` object to the macro pointed to
+       in the function argument.  In most cases, the correct
+       "asciification" of a node is to do nothing, discarding it.
+       Rather than making the member function empty in the base class,
+       I prefer to make the base class abstract to force conscious
+       consideration of how each derived class should be "asciified".
+
+       * src/roff/troff/node.h: Mark `add_char()`, `asciify()`, and
+       `add_italic_correction()` member functions as `virtual`.
+       Further mark `asciify` as _pure_ virtual (notation: "= 0").
+       * src/roff/troff/node.cpp (node::asciify): Delete.
+
 2025-09-17  G. Branden Robinson <g.branden.robin...@gmail.com>
 
        * src/roff/groff/tests/asciify-request-works.sh: Add test case
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 5da34ad05..4c2fde9d2 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3890,12 +3890,6 @@ void zero_width_node::ascii_print(ascii_output_file *out)
 // suitable for storage in a groff string or embedding in a device
 // extension command escape sequence (as for PDF metadata).
 
-void node::asciify(macro *m)
-{
-  if (!is_output_supressed)
-    m->append(this);
-}
-
 void glyph_node::asciify(macro *m)
 {
   if (!is_output_supressed) {
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 2c9e2d627..42fa96d97 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -60,7 +60,7 @@ struct node {
   node(node *);
   node(node *, statem *, int);
   node(node *, statem *, int, bool);
-  node *add_char(charinfo *, environment *, hunits *, int *,
+  virtual node *add_char(charinfo *, environment *, hunits *, int *,
                 node ** /* glyph_comp_np */ = 0 /* nullptr */);
 
   virtual ~node();
@@ -87,7 +87,7 @@ struct node {
   virtual node *add_self(node *, hyphen_list **);
   virtual hyphen_list *get_hyphen_list(hyphen_list *, int *);
   virtual void ascii_print(ascii_output_file *);
-  virtual void asciify(macro *);
+  virtual void asciify(macro *) = 0;
   virtual bool discardable();
   virtual void spread_space(int *, hunits *);
   virtual void freeze_space();
@@ -112,7 +112,7 @@ struct node {
   virtual void tprint(troff_output_file *);
   virtual void zero_width_tprint(troff_output_file *);
 
-  node *add_italic_correction(hunits *);
+  virtual node *add_italic_correction(hunits *);
 
   virtual bool is_same_as(node *) = 0;
   virtual const char *type() = 0;

_______________________________________________
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to