Loading ...
Sorry, an error occurred while loading the content.

[patch] bug in syntax folding when using :syn sync fromstart

Expand Messages
  • Utz-Uwe Haus
    Hi, while using the fresh version 6.0k this morning I came across a buglet in syn_sync(). To reproduce try editing, for example vim s top-level Makefile, then
    Message 1 of 2 , Nov 1, 2000
    • 0 Attachment
      Hi,

      while using the fresh version 6.0k this morning I came across a buglet
      in syn_sync(). To reproduce try editing, for example vim's top-level
      Makefile, then type
      :syn sync fromstart

      I immediately get a 'ml_get(): invalid lnum:' error with a number that
      looks almost like MAX_INT. The reason is that syncing from start sets
      syn_buf->b_syn_sync_minlines to MAXLNUM, and the code in syn_sync()
      assumes it can do

      start_lnum -= syn_buf->b_syn_sync_minlines + 10;

      without overflow.

      Fix included; could probably be more beautiful but 'works for me' (tm).

      Later
      Utz

      ----- cut here -----
      Index: syntax.c
      ===================================================================
      RCS file: /cvsroot/vim/vim/src/syntax.c,v
      retrieving revision 1.18
      diff -u -c -r1.18 syntax.c
      cvs server: conflicting specifications of output style
      *** syntax.c 2000/10/29 22:50:27 1.18
      --- syntax.c 2000/11/01 14:16:30
      ***************
      *** 660,666 ****
      start_lnum -= syn_buf->b_syn_sync_minlines * 2;
      else
      start_lnum -= syn_buf->b_syn_sync_minlines + 10;
      ! if (start_lnum < 1)
      start_lnum = 1;
      current_lnum = start_lnum;

      --- 660,671 ----
      start_lnum -= syn_buf->b_syn_sync_minlines * 2;
      else
      start_lnum -= syn_buf->b_syn_sync_minlines + 10;
      ! /* start_lnum may be have passed the start, then set it to 1.
      ! * minlines+10 may also have overflowed signed int arithmetic, in that
      ! * case start_lnum is totally bogus. What we meant to do then was to start
      ! * from line 1 too, so there:
      ! */
      ! if (start_lnum < 1 || MAXLNUM-10 < syn_buf->b_syn_sync_minlines)
      start_lnum = 1;
      current_lnum = start_lnum;

      --------------------


      --
      Utz-Uwe Haus haus@...-magdeburg.de
      Inst. f. Math. Optim. utz@...
      Uni Magdeburg PGP keys 1024/6AD23BE1 and 2048/5D0B72A1
      GERMANY available via keyservers or email request
    • Bram Moolenaar
      ... Thanks for locating this problem. I already changed this code a bit, to go back a few more lines to speed up scrolling backwards. It now looks like this:
      Message 2 of 2 , Nov 1, 2000
      • 0 Attachment
        Utz-Uwe Haus wrote:

        > while using the fresh version 6.0k this morning I came across a buglet
        > in syn_sync(). To reproduce try editing, for example vim's top-level
        > Makefile, then type
        > :syn sync fromstart
        >
        > I immediately get a 'ml_get(): invalid lnum:' error with a number that
        > looks almost like MAX_INT. The reason is that syncing from start sets
        > syn_buf->b_syn_sync_minlines to MAXLNUM, and the code in syn_sync()
        > assumes it can do
        >
        > start_lnum -= syn_buf->b_syn_sync_minlines + 10;
        >
        > without overflow.
        >
        > Fix included; could probably be more beautiful but 'works for me' (tm).

        Thanks for locating this problem. I already changed this code a bit, to go
        back a few more lines to speed up scrolling backwards. It now looks like
        this:

        /*
        * Start at least "minlines" back. Default starting point for parsing is
        * there.
        * Start further back, to avoid that scrolling backwards will result in
        * resyncing for every line. Now it resyncs only one out of N lines,
        * where N is minlines * 1.5, or minlines * 2 if minlines is small.
        * Watch out for overflow when minlines is MAXLNUM.
        */
        if (syn_buf->b_syn_sync_minlines > start_lnum)
        start_lnum = 1;
        else
        {
        if (syn_buf->b_syn_sync_minlines == 1)
        lnum = 1;
        else if (syn_buf->b_syn_sync_minlines < 10)
        lnum = syn_buf->b_syn_sync_minlines * 2;
        else
        lnum = syn_buf->b_syn_sync_minlines * 3 / 2;
        if (syn_buf->b_syn_sync_maxlines != 0
        && lnum > syn_buf->b_syn_sync_maxlines)
        lnum = syn_buf->b_syn_sync_maxlines;
        if (lnum >= start_lnum)
        start_lnum = 1;
        else
        start_lnum -= lnum;
        }
        current_lnum = start_lnum;

        --
        If someone questions your market projections, simply point out that your
        target market is "People who are nuts" and "People who will buy any damn
        thing". Nobody is going to tell you there aren't enough of those people to go
        around.
        (Scott Adams - The Dilbert principle)

        /// Bram Moolenaar Bram@... http://www.moolenaar.net \\\
        \\\ Vim: http://www.vim.org ICCF Holland: http://iccf-holland.org ///
      Your message has been successfully submitted and would be delivered to recipients shortly.