Ralph Corderoy <ra...@inputplus.co.uk> wrote:
 |> Unfortunately, this also means inventing a new syntax.  How should
 |> "\*", "\(", and "\[" be treated -- as groff escapes or as
 |> regular-expression magic?
 |
 |Exactly.  Taking an earlier suggestion for OR, it's valid now.
 |
 |    $ nroff | grep .
 |    .if 'a'a'b'c'
 |    b’c’
 |    $
 |
 |However, a new syntax is needed.  I'd guess something at the start that
 |is currently invalid would indicate a whole new style of expression is
 |present, one with typical precedence, and more string matching
 |possibilities.

A really really ugly way of extending the current syntax today,
which possibly would do no harm in real life?, would be to let
a doubling of the delimiter mean that further tests follow, as in

 .if 'abc'def''ghi''not this''abc' .tm matches

I have no idea, but the attached patch should do this pretty well.
Note i'm running groff(1) with my [file_case] extension and
without GNULib, but it applies somewhat:

  ?0[steffen@sherwood groff.git]$ gl1 15d0cd9 | s-patch  
  patching file src/roff/troff/input.cpp
  Hunk #1 succeeded at 5766 (offset 5 lines).
  ?0[steffen@sherwood groff.git]$ 

I'm not sure i like this approach, though.
Ciao,

--steffen
commit 15d0cd9 (HEAD, refs/heads/file_case)
Author: Steffen Nurpmeso <sdao...@users.sf.net>
Date:   2014-11-13 16:42:38 +0100

    Satisfy (hohe72 AT arcor DOT de): add ".if 'a'b''c''d''e'" pattern
---
 src/roff/troff/input.cpp | 67 +++++++++++++++++++++++++++++-------------------
 1 file changed, 40 insertions(+), 27 deletions(-)

diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index e8ef0b9..8feb269 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -5761,36 +5761,49 @@ int do_if_request()
   else if (tok.delimiter()) {
     token delim = tok;
     int delim_level = input_stack::get_level();
-    environment env1(curenv);
-    environment env2(curenv);
-    environment *oldenv = curenv;
-    curenv = &env1;
-    suppress_push = 1;
-    for (int i = 0; i < 2; i++) {
-      for (;;) {
-	tok.next();
-	if (tok.newline() || tok.eof()) {
-	  warning(WARN_DELIM, "missing closing delimiter");
-	  tok.next();
-	  curenv = oldenv;
-	  return 0;
-	}
-	if (tok == delim
-	    && (compatible_flag || input_stack::get_level() == delim_level))
-	  break;
-	tok.process();
+    environment *oldenv = curenv, env1(oldenv);
+    node *n1 = NULL;
+
+    result = 0;
+    for (bool any = false;;) {
+      suppress_push = 1;
+      environment env2(curenv = oldenv);
+jenv2:
+      for (curenv = any ? &env2 : &env1;;) {
+        tok.next();
+        if (tok.newline() || tok.eof()) {
+          warning(WARN_DELIM, "missing closing delimiter");
+          tok.next();
+          curenv = oldenv;
+          delete_node_list(n1);
+          return 0;
+        }
+        if (tok == delim &&
+            (compatible_flag || input_stack::get_level() == delim_level))
+          break;
+        tok.process();
       }
-      curenv = &env2;
+
+      if (!any) {
+        any = true;
+        n1 = env1.extract_output_line();
+	goto jenv2; // Cheaper than continue;
+      }
+      if (result == 0) {
+        node *n2 = env2.extract_output_line();
+        result = same_node_list(n1, n2);
+        delete_node_list(n2);
+      }
+
+      curenv = oldenv;
+      have_input = 0;
+      suppress_push = 0;
+      tok.next();
+      if (tok != delim)
+        break;
     }
-    node *n1 = env1.extract_output_line();
-    node *n2 = env2.extract_output_line();
-    result = same_node_list(n1, n2);
+
     delete_node_list(n1);
-    delete_node_list(n2);
-    curenv = oldenv;
-    have_input = 0;
-    suppress_push = 0;
-    tok.next();
   }
   else {
     units n;

Reply via email to