groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[groff] 15/15: [troff]: Fix Savannah #64957 (`device`, `output`).


From: G. Branden Robinson
Subject: [groff] 15/15: [troff]: Fix Savannah #64957 (`device`, `output`).
Date: Fri, 1 Dec 2023 16:03:00 -0500 (EST)

gbranden pushed a commit to branch master
in repository groff.

commit 0b403f7971e7b7965f7853b05dec3ce1128f943e
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Fri Dec 1 13:57:47 2023 -0600

    [troff]: Fix Savannah #64957 (`device`, `output`).
    
    ...requests were broken.
    
    The GNU troff(1) internal function `has_arg()` has a side effect of
    advancing the token pointer (a sort of cursor into the input stream).
    So when I changed `device_request()` and `output_request()` to use
    `has_arg()` in commit 429723c3ec (10 November), the first character of
    the argument got stripped, making it unintelligible to the output
    driver.
    
    * src/roff/troff/input.cpp (device_request, output_request): Drop call
      of `has_arg()` in favor of `input_stack::peek()`.  Manually discard
      space characters until reaching something else; if that is a newline
      or EOF, bail out of request processing.  Otherwise, proceed with
      warning diagnostic as before.
    
    Also:
    * Annotate null pointers with `nullptr` comment to ease any future
      transition to C++11, which defines it as a keyword.
    * Reorder comparisons to avoid inadvertent lvalue assignment.
---
 ChangeLog                | 17 ++++++++++++
 src/roff/troff/input.cpp | 70 ++++++++++++++++++++++++++++--------------------
 2 files changed, 58 insertions(+), 29 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d654f0f58..249171ed3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2023-12-01  G. Branden Robinson <g.branden.robinson@gmail.com>
+
+       [troff]: Fix Savannah #64957 (`device`, `output` broken).
+
+       The GNU troff(1) internal function `has_arg()` has a side effect
+       of advancing the token pointer (a sort of cursor into the input
+       stream).  So when I changed `device_request()` and
+       `output_request()` to use `has_arg()` in commit 429723c3ec (10
+       November), the first character of the argument got stripped,
+       making it unintelligible to the output driver.
+
+       * src/roff/troff/input.cpp (device_request, output_request):
+       Drop call of `has_arg()` in favor of `input_stack::peek()`.
+       Manually discard space characters until reaching something else;
+       if that is a newline or EOF, bail out of request processing.
+       Otherwise, proceed with warning diagnostic as before.
+
 2023-12-01  G. Branden Robinson <g.branden.robinson@gmail.com>
 
        * doc/groff.texi: Fix typos.
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 1166e24b3..a9abd1905 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -5660,27 +5660,33 @@ static node *do_special()
 
 void device_request()
 {
-  if (!has_arg()) {
+  // We can't use `has_arg()` here because we want to read in copy mode.
+  int c;
+  for (;;) {
+    c = input_stack::peek();
+    if (' ' == c)
+      (void) get_copy(0 /* nullptr */);
+    else
+      break;
+  }
+  if (('\n' == c) || (EOF == c)) {
     warning(WARN_MISSING, "device control request expects arguments");
     skip_line();
     return;
   }
-  if (!tok.is_newline() && !tok.is_eof()) {
-    int c;
-    macro mac;
-    for (;;) {
-      c = get_copy(0);
-      if (c == '"') {
-       c = get_copy(0);
-       break;
-      }
-      if (c != ' ' && c != '\t')
-       break;
+  macro mac;
+  for (;;) {
+    c = get_copy(0 /* nullptr */);
+    if ('"' == c) {
+      c = get_copy(0 /* nullptr */);
+      break;
     }
-    for (; c != '\n' && c != EOF; c = get_copy(0))
-      mac.append(c);
-    curenv->add_node(new special_node(mac));
+    if (c != ' ' && c != '\t')
+      break;
   }
+  for (; c != '\n' && c != EOF; c = get_copy(0 /* nullptr */))
+    mac.append(c);
+  curenv->add_node(new special_node(mac));
   tok.next();
 }
 
@@ -5701,26 +5707,32 @@ void device_macro_request()
 
 void output_request()
 {
-  if (!has_arg()) {
+  // We can't use `has_arg()` here because we want to read in copy mode.
+  int c;
+  for (;;) {
+    c = input_stack::peek();
+    if (' ' == c)
+      (void) get_copy(0 /* nullptr */);
+    else
+      break;
+  }
+  if (('\n' == c) || (EOF == c)) {
     warning(WARN_MISSING, "output request expects arguments");
     skip_line();
     return;
   }
-  if (!tok.is_newline() && !tok.is_eof()) {
-    int c;
-    for (;;) {
-      c = get_copy(0);
-      if (c == '"') {
-       c = get_copy(0);
-       break;
-      }
-      if (c != ' ' && c != '\t')
-       break;
+  for (;;) {
+    c = get_copy(0 /* nullptr */);
+    if ('"' == c) {
+      c = get_copy(0 /* nullptr */);
+      break;
     }
-    for (; c != '\n' && c != EOF; c = get_copy(0))
-      topdiv->transparent_output(c);
-    topdiv->transparent_output('\n');
+    if (c != ' ' && c != '\t')
+      break;
   }
+  for (; c != '\n' && c != EOF; c = get_copy(0 /* nullptr */))
+    topdiv->transparent_output(c);
+  topdiv->transparent_output('\n');
   tok.next();
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]