gbranden pushed a commit to branch master
in repository groff.

commit 6d32f2492ef3db455bd6306cdf7bd7c0a0e2d340
Author: G. Branden Robinson <[email protected]>
AuthorDate: Fri Sep 13 07:13:42 2024 -0500

    [troff]: Retype stream objects.
    
    Make them objects of new `grostream` class, so we can conveniently store
    more state in them.
    
    * src/roff/troff/input.cpp (class grostream): Declare.
    
      (grostream::grostream): Declare constructor.
    
      (grostream::~grostream): Declare (trivial) destructor.
    
      (print_streams): Report mode in which the stream was opened.
    
      (open_file, close_stream, do_write_request, write_macro_request):
      Migrate to expect an object of type `grostream` from a
      `stream_dictionary.lookup()` instead of a pointer to `FILE`.
---
 ChangeLog                | 14 +++++++++++
 src/roff/troff/input.cpp | 63 ++++++++++++++++++++++++++++++++++++------------
 2 files changed, 62 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index addfc34ee..3961d0c29 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2024-09-13  G. Branden Robinson <[email protected]>
+
+       [troff]: Make groff streams objects of new `grostream` class, so
+       we can conveniently store more state in them.
+
+       * src/roff/troff/input.cpp (class grostream): Declare.
+       (grostream::grostream): Declare constructor.
+       (grostream::~grostream): Declare (trivial) destructor.
+       (print_streams): Report mode in which the stream was opened.
+       (open_file, close_stream, do_write_request)
+       (write_macro_request): Migrate to expect an object of type
+       `grostream` from a `stream_dictionary.lookup()` instead of a
+       pointer to `FILE`.
+
 2024-09-13  G. Branden Robinson <[email protected]>
 
        * src/roff/troff/input.cpp (close_request): Move stream-closing
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index d13c89d5f..729f1038e 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -7215,17 +7215,40 @@ void terminal_continue()
   do_terminal(0, 1);
 }
 
+struct grostream {
+  string filename;
+  string mode;
+  FILE *file;
+  grostream(const string &fn, string m, FILE *fp);
+  ~grostream();
+};
+
+grostream::grostream(const string &fn, string m, FILE *fp)
+: filename(fn), mode(m), file(fp)
+{
+  filename += '\0'; // Don't leak garbage in print_streams().
+}
+
+// XXX: Maybe we should try to close the libc FILE stream here.
+// Resource Release Is Destruction?
+grostream::~grostream()
+{
+}
+
 object_dictionary stream_dictionary(20);
 
 void print_streams()
 {
   object_dictionary_iterator iter(stream_dictionary);
-  FILE *filestream;
-  symbol stream;
-  while (iter.get(&stream, (object **)&filestream)) {
-    assert(!stream.is_null());
-    if (stream != 0 /* nullptr */)
-      errprint("%1\n", stream.contents());
+  symbol stream_name;
+  grostream *grost;
+  while (iter.get(&stream_name, (object **)&grost)) {
+    assert(!stream_name.is_null());
+    if (stream_name != 0 /* nullptr */) {
+      errprint("%1\t", stream_name.contents());
+      errprint("%1\t%2\n", grost->filename.contents(),
+              grost->mode.contents());
+    }
   }
   fflush(stderr);
   skip_line();
@@ -7235,8 +7258,10 @@ static void open_file(bool appending)
 {
   symbol stream = get_name(true /* required */);
   if (!stream.is_null()) {
-    symbol filename = get_long_name(true /* required */);
-    if (!filename.is_null()) {
+    symbol fnarg = get_long_name(true /* required */);
+    if (!fnarg.is_null()) {
+      const string mode = appending ? "appending" : "writing";
+      string filename = fnarg.contents();
       errno = 0;
       FILE *fp = fopen(filename.contents(), appending ? "a" : "w");
       if (0 /* nullptr */ == fp) {
@@ -7249,12 +7274,17 @@ static void open_file(bool appending)
        stream_dictionary.remove(stream);
       }
       else {
-       FILE *oldfp = (FILE *)stream_dictionary.lookup(stream);
-       if (oldfp != 0 /* nullptr */ && (fclose(oldfp) != 0))
+       grostream *oldgrost
+         = (grostream *)stream_dictionary.lookup(stream);
+       FILE *oldfp = oldgrost->file;
+       if (oldfp != 0 /* nullptr */ && (fclose(oldfp) != 0)) {
          error("cannot close file '%1' already associated with stream"
                " '%2': %3", filename.contents(), strerror(errno));
-       else
-         stream_dictionary.define(stream, (object *)fp);
+         return;
+       }
+       grostream *grost = new grostream(filename.contents(), mode,
+                                        &*fp);
+       stream_dictionary.define(stream, (object *)grost);
       }
     }
   }
@@ -7295,7 +7325,8 @@ static void opena_request() // .opena
 static void close_stream(symbol &stream)
 {
   assert(!stream.is_null());
-  FILE *fp = (FILE *)stream_dictionary.lookup(stream);
+  grostream *grost = (grostream *)stream_dictionary.lookup(stream);
+  FILE *fp = grost->file;
   if (0 /* nullptr */ == fp) {
     error("cannot close nonexistent stream '%1'", stream.contents());
     return;
@@ -7351,7 +7382,8 @@ void do_write_request(int newline)
     skip_line();
     return;
   }
-  FILE *fp = (FILE *)stream_dictionary.lookup(stream);
+  grostream *grost = (grostream *)stream_dictionary.lookup(stream);
+  FILE *fp = grost->file;
   if (0 /* nullptr */ == fp) {
     error("cannot write to nonexistent stream '%1'", stream.contents());
     skip_line();
@@ -7387,7 +7419,8 @@ void write_macro_request()
     skip_line();
     return;
   }
-  FILE *fp = (FILE *)stream_dictionary.lookup(stream);
+  grostream *grost = (grostream *)stream_dictionary.lookup(stream);
+  FILE *fp = grost->file;
   if (0 /* nullptr */ == fp) {
     error("no stream named '%1'", stream.contents());
     skip_line();

_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to