groff
[Top][All Lists]
Advanced

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

[Groff] bug in troff?


From: Gaius Mulley
Subject: [Groff] bug in troff?
Date: Tue, 16 Oct 2001 10:20:04 +0100

Hi,

I think I've found a bug in troff which manifests itself when
using refer.

Here is some input code:

.LP
As Pike
.[
Plan 9 from Bell Labs
.]
reported

which when processed via: refer -sA+T -p ../bibliography/refs  -e -P t.n
produces:

.lf 1 t.n
.LP
As Pike\*([.1\*(.]
.lf 8 t.n
reported
.]<
.\"pikerpresottodthompsonktrickeyhplan 9 from bell labs
.ds [F 1
.]-
.ds [A R. Pike, D. Presotto, K. Thompson, and H. Trickey
.ds [C London
.ds [D July 1990
.ds [J Proceedings of the Summer 1990 UKUUG Conference
.ds [K mylib
.ds [P 1-9
.nr [P 1
.ds [T Plan 9 from Bell Labs
.nr [T 0
.nr [A 0
.][ 1 journal-article
.]>

when processed further by: groff -Tascii -ms (and also -Tps)
it yields:

       +.7m'1+.9m' reported
As Pike

it should read

       1
As Pike reported

if I copy the troff binary from 2001 Aug 01 into /usr/local/bin all is fine
(using the same /usr/local/share/groff/1.17.3 of course)
but the troff dated 2001 Sept 01 (onwards) causes the failure above.
I've traced the changed to src/roff/troff/input.cc (using cvs)
but I don't pretend to understand exactly what these changes do..

However the input that is causing this problem is:

As Pike\*([.1\*(.]

which use 2 two character strings [. and .]
which are defined in s.tmac as

.\" start of reference number
.ds [. address@hidden
.\" end of reference number
.ds .] address@hidden

these in turn are defined as:

.ds address@hidden \v'-.7m\s0+.9m'
.ds address@hidden \v'-.9m\s'\En[.s]*7u/10u'+.7m'

any way, can anyone see what is wrong?

Thanks Gaius



--- working/2001-08-01/groff/src/roff/troff/input.cc    Mon Jul  2 19:35:00 2001
***************
*** 872,889 ****
        }
      case 'g':
        {
!       (void)input_stack::get(NULL);
!       symbol s = read_escape_name();
        if (!s.is_null())
          interpolate_number_format(s);
!       break;
        }
      case 't':
        (void)input_stack::get(NULL);
        return '\t';
      case 'V':
        {
!       (void)input_stack::get(NULL);
        symbol s = read_escape_name();
        if (!s.is_null())
          interpolate_environment_variable(s);
--- 872,889 ----
        }
      case 'g':
        {
!         (void)input_stack::get(NULL);
!         symbol s = read_escape_name();
        if (!s.is_null())
          interpolate_number_format(s);
!         break;
        }
      case 't':
        (void)input_stack::get(NULL);
        return '\t';
      case 'V':
        {
!         (void)input_stack::get(NULL);
        symbol s = read_escape_name();
        if (!s.is_null())
          interpolate_environment_variable(s);
***************
*** 1576,1585 ****
            curenv->set_font(s);
          else
            curenv->set_font(atoi(s.contents()));
!         if (compatible_flag)
!           break;
!         type = TOKEN_OPAQUE_ESCAPE;
!         return;
        }
        case 'g':
        {
--- 1576,1582 ----
            curenv->set_font(s);
          else
            curenv->set_font(atoi(s.contents()));
!         break;
        }
        case 'g':
        {
***************
*** 1597,1606 ****
        case 'H':
        if (get_delim_number(&x, 'z', curenv->get_requested_point_size()))
          curenv->set_char_height(x);
!       if (compatible_flag)
!         break;
!       type = TOKEN_OPAQUE_ESCAPE;
!       return;
        case 'k':
        nm = read_escape_name();
        if (nm.is_null())
--- 1594,1600 ----
        case 'H':
        if (get_delim_number(&x, 'z', curenv->get_requested_point_size()))
          curenv->set_char_height(x);
!       break;
        case 'k':
        nm = read_escape_name();
        if (nm.is_null())
***************
*** 1655,1678 ****
        return;
        case 'R':
        do_register();
!       if (compatible_flag)
!         break;
!       type = TOKEN_OPAQUE_ESCAPE;
!       return;
        case 's':
        if (read_size(&x))
          curenv->set_size(x);
!       if (compatible_flag)
!         break;
!       type = TOKEN_OPAQUE_ESCAPE;
!       return;
        case 'S':
        if (get_delim_number(&x, 0))
          curenv->set_char_slant(x);
!       if (compatible_flag)
!         break;
!       type = TOKEN_OPAQUE_ESCAPE;
!       return;
        case 't':
        type = TOKEN_NODE;
        nd = new non_interpreted_char_node('\t');
--- 1649,1663 ----
        return;
        case 'R':
        do_register();
!       break;
        case 's':
        if (read_size(&x))
          curenv->set_size(x);
!       break;
        case 'S':
        if (get_delim_number(&x, 0))
          curenv->set_char_slant(x);
!       break;
        case 't':
        type = TOKEN_NODE;
        nd = new non_interpreted_char_node('\t');
***************
*** 1688,1694 ****
        nd = new vmotion_node(x);
        return;
        case 'V':
!       {
          symbol nm = read_escape_name();
          if (!nm.is_null())
            interpolate_environment_variable(nm);
--- 1673,1679 ----
        nd = new vmotion_node(x);
        return;
        case 'V':
!         {
          symbol nm = read_escape_name();
          if (!nm.is_null())
            interpolate_environment_variable(nm);
***************
*** 1727,1735 ****
        case 'z':
        {
          next();
!         if (type == TOKEN_NODE)
!         nd = new zero_width_node(nd);
!         else {
            charinfo *ci = get_char(1);
            if (ci == 0)
              break;
--- 1712,1720 ----
        case 'z':
        {
          next();
!           if (type == TOKEN_NODE)
!             nd = new zero_width_node(nd);
!           else {
            charinfo *ci = get_char(1);
            if (ci == 0)
              break;
***************
*** 1738,1744 ****
              break;
            nd = new zero_width_node(gn);
            type = TOKEN_NODE;
!         }
          return;
        }
        case 'Z':
--- 1723,1729 ----
              break;
            nd = new zero_width_node(gn);
            type = TOKEN_NODE;
!           }
          return;
        }
        case 'Z':
***************
*** 1876,1883 ****
      return "a node";
    case TOKEN_NUMBERED_CHAR:
      return "`\\N'";
-   case TOKEN_OPAQUE_ESCAPE:
-     return "a transparent escape (`\\f', `\\H', `\\R', `\\s', `\\S')";
    case TOKEN_RIGHT_BRACE:
      return "`\\}'";
    case TOKEN_SPACE:
--- 1861,1866 ----
***************
*** 2301,2309 ****
        }
        break;
        }
-     case token::TOKEN_OPAQUE_ESCAPE:
-       bol = 0;
-       break;
      case token::TOKEN_NEWLINE:
        {
        if (bol && !curenv->get_prev_line_interrupted())
--- 2284,2289 ----
***************
*** 2408,2416 ****
          way to do it.  Doing an output_pending_lines() whenever a
          TOKEN_END_TRAP is detected doesn't work: for example,
  
!         .wh -1i x
!         .de x
!         'bp
          ..
          .wh -.5i y
          .de y
--- 2388,2396 ----
          way to do it.  Doing an output_pending_lines() whenever a
          TOKEN_END_TRAP is detected doesn't work: for example,
  
!           .wh -1i x
!           .de x
!           'bp
          ..
          .wh -.5i y
          .de y
***************
*** 2421,2428 ****
          .sp |\n(.pu-1i-.5v
          a\%very\%very\%long\%word
  
!         will print all but the first lines from the word immediately
!         after the footer, rather than on the next page. */
  
        if (trap_bol_stack.is_empty())
          curenv->output_pending_lines();
--- 2401,2408 ----
          .sp |\n(.pu-1i-.5v
          a\%very\%very\%long\%word
  
!           will print all but the first lines from the word immediately
!           after the footer, rather than on the next page. */
  
        if (trap_bol_stack.is_empty())
          curenv->output_pending_lines();
***************
*** 4682,4688 ****
  
  /*
   *  begin - if this is the outermost html_begin request then execute the
!  *          rest of the line, else skip line
   */
  
  void begin()
--- 4662,4668 ----
  
  /*
   *  begin - if this is the outermost html_begin request then execute the
!  *               rest of the line, else skip line
   */
  
  void begin()
***************
*** 5018,5024 ****
        else {
        error("the arguments to the %%%%BoundingBox comment in `%1' are bad",
              filename);
!       return;
        }
      }
    }
--- 4998,5004 ----
        else {
        error("the arguments to the %%%%BoundingBox comment in `%1' are bad",
              filename);
!         return;
        }
      }
    }
***************
*** 5571,5577 ****
      *pp = (*pp)->add_char(get_charinfo_by_number(val), curenv, &w, &s);
      break;
    case TOKEN_RIGHT_BRACE:
-   case TOKEN_OPAQUE_ESCAPE:
      break;
    case TOKEN_SPACE:
      n = new hmotion_node(curenv->get_space_width());
--- 5551,5556 ----
***************
*** 5651,5661 ****
    case TOKEN_NUMBERED_CHAR:
      curenv->add_char(get_charinfo_by_number(val));
      break;
-   case TOKEN_OPAQUE_ESCAPE:
-     // handled in process_input_stack()
-     break;
    case TOKEN_REQUEST:
!     // handled in process_input_stack()
      break;
    case TOKEN_RIGHT_BRACE:
      break;
--- 5630,5637 ----
    case TOKEN_NUMBERED_CHAR:
      curenv->add_char(get_charinfo_by_number(val));
      break;
    case TOKEN_REQUEST:
!     // handled in process_input_stack
      break;
    case TOKEN_RIGHT_BRACE:
      break;

reply via email to

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