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;