Update of bug #67746 (group groff):

                  Status:                    None => In Progress
             Assigned to:                    None => gbranden

    _______________________________________________________

Follow-up Comment #1:

This was simpler than I thought.

_read_size_() has a lot of custom logic.  Why?

Our Texinfo manual says:


5.6.4 Using Escape Sequences
----------------------------
...
   Escape sequences vary in length.  Some take an argument, and of
those, some have different syntactical forms for a one-character,
two-character, or arbitrary-length argument.  Others accept _only_ an
arbitrary-length argument.  In the former scheme, a one-character
argument follows the function character immediately, an opening
parenthesis '(' introduces a two-character argument (no closing
parenthesis is used), and an argument of arbitrary length is enclosed in
brackets '[]'.  In the latter scheme, the user selects a delimiter
character.  **A few escape sequences are idiosyncratic, and support both
of the foregoing conventions ('\s'),** designate their own termination
sequence ('\?'), consume input until the next newline ('\!', '\"',
'\#'), or support an additional modifier character ('\s' again, and
'\n').  In no case can an escape sequence parameter contain an unescaped
newline.  As with requests, use of some escape sequences in source
documents may interact poorly with a macro package you use; consult its
documentation to learn of "safe" sequences or alternative facilities it
provides to achieve the desired result.


(Emphasis added, but since that's a "verbatim" region you have to look for the
double asterisks.)

The bottom line is that the numeric expression evaluator bails out as soon as
it hits any character that isn't valid, leaving it on the input stream.
_read_size_() knows that when _read_measurement_() returns, the expression
(and the delimited expression) is "done", so it expects the next token on the
input stream to be the closing delimiter.

All we have to do to illuminate this is offer a little more information in the
diagnostic, reusing a pattern that I've employed in several other places
already.


diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 22d9112ae..e089b9959 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -6109,8 +6109,16 @@ static bool read_size(int *x) // \s
     if (!((s == int('[')) && (t == int(']'))) && (start != tok)) {
       if (s == int('['))
        error("missing ']' in type size escape sequence");
-      else
-       error("missing closing delimiter in type size escape sequence");
+      else {
+       // token::description() writes to static, class-wide storage, so
+       // we must allocate a copy of it before issuing the next
+       // diagnostic.
+       char *delimdesc = strdup(start.description());
+       if (s != t)
+         error("closing delimiter does not match; expected %1, got %2",
+               delimdesc, tok.description());
+       free(delimdesc);
+      }
       return false;
     }
   }




    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?67746>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/

Attachment: signature.asc
Description: PGP signature

Reply via email to