Hello again, and however..

i wrote
 |Ralph Corderoy <ra...@inputplus.co.uk> wrote:
 ||Exactly.  Taking an earlier suggestion for OR, it's valid now.

which makes the former a backward-compatibility no-go, even though
i don't want to imagine a case where it would cause a problem.
But anyway, i wonder what you all think about instead introducing

  .if $'a'b'c'd'e'f'g'a'$ .tm matches

i.e., by enclosing the expression in a pair of dollars the normal
delimiters can be used all through the case..esac string
comparison series.
It is always hairy using a dollar, but most normal letters are
taken and groff has so many special cases for character usage that
i'll take a long time to dig into this.  And another one is needed
for regular expression matching.

 |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:

Same is true, but it is a standalone patch, not "on-top".

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

I would like this approach much more.

 |Ciao,

--steffen
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index e8ef0b9..c124e7d 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -5756,41 +5756,72 @@ int do_if_request()
     }
     result = check_style(nm);
   }
+  else if (c == '$') {
+    tok.next();
+    if (!tok.delimiter()) // warns as appropriate
+      return 0;
+    goto jstrtest;
+  }
   else if (tok.space())
     result = 0;
   else if (tok.delimiter()) {
+    enum {_NONE = 0, _MULTI = 1<<0, _PEEKED = 1<<1, _TICKED = 1<<2};
+jstrtest:
+    c = (c == '$') ? _MULTI : _NONE; // $''['...]'$ "case switch"?
     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;
+
+    for (result = 0;;) {
+      suppress_push = 1;
+      environment env2(curenv = oldenv);
+j_strtest_env2:
+      for (curenv = (c & _TICKED) ? &env2 : &env1;;) {
+        if (!(c & _PEEKED))
+          tok.next();
+	c &= ~_PEEKED;
+
+        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 (!(c & _TICKED)) {
+        c |= _TICKED;
+        n1 = env1.extract_output_line();
+        goto j_strtest_env2; // Cheaper than continue;
+      }
+      if (result == 0) {
+        node *n2 = env2.extract_output_line();
+        result = same_node_list(n1, n2);
+        delete_node_list(n2);
+      }
+
+j_strtest_done:
+      curenv = oldenv;
+      have_input = 0;
+      suppress_push = 0;
+
+      tok.next();
+      if (c & _MULTI) {
+        c |= _PEEKED;
+        if (tok.ch() != '$')
+          continue;
+        tok.next();
+      }
+      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