emacs-devel
[Top][All Lists]
Advanced

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

Re: C++ mode and c-beginning-of-current-token


From: Herbert Euler
Subject: Re: C++ mode and c-beginning-of-current-token
Date: Tue, 15 May 2007 21:30:06 +0800

> If `parse-sexp-lookup-properties' is t, `skip-syntax-backward' would
> not return -1, but signaling an error in some cases.

Sounds like a bug in skip-syntax-backward.

In the previous message, I described a way to reproduce the error:

0. Start Emacs with emacs -Q.

1. Visit a new, empty C++ file.

2. Insert the following characters:

#include <iostream>

The error happens when inserting the second character, i.  Now let's
remember the following two facts:

a) `parse-sexp-lookup-properties' is t in a c++-mode buffer,

b) `after-change-functions' contains `c-after-change', which leads to
  invocation of `skip-syntax-backward' in the way
  (skip-syntax-backward ".()" nil),

c) the c++-mode buffer is not multibyte.

Now, with fact a), code in syntax.c will update interval information,
including the function `skip_syntaxes', invoked by
`Fskip_syntax_backward'.  Take a look at how `skip_syntaxes' works, we
might know how the error happens.

The code that skips characters and updates interval information uses a
variable `pos', and below is how it updates interval information:

   while (1)
     {
       if (p <= stop)
         {
           if (p <= endp)
             break;
           p = GPT_ADDR;
           stop = endp;
         }
       if (! fastmap[(int) SYNTAX (p[-1])])
         break;
       p--, pos--, pos_byte--;
       UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
     }

As you see, it updates interval information at position (pos - 1).  At
an earlier stage in this function, `pos' is initialized to the buffer
position:

   int start_point = PT;
   int pos = PT;
   int pos_byte = PT_BYTE;
   unsigned char *p = PT_ADDR, *endp, *stop;

Since we're inserting the second character, `PT' is now 2, and so the
initial value of `pos' is 2.  Later, before updating interval
information, `pos' is self-decreased, so (pos - 1) = (1 - 1) = 0.

Here is how `UPDATE_SYNTAX_TABLE_BACKWARD' is defined:

   #define UPDATE_SYNTAX_TABLE_BACKWARD(charpos)                   \
     (parse_sexp_lookup_properties                                 \
      && (charpos) < gl_state.b_property                           \
      ? (update_syntax_table ((charpos) + gl_state.offset, -1, 0,  \
                              gl_state.object),                    \
         1)                                                        \
      : 0)

It invokes `update_syntax_table' with `charpos' set to (charpos +
gl_state.offset).  `charpos' is 0 there, and gl_state.offset is 0.  So
`update_syntax_table' is invoked with `charpos' set to 0.  Finally,
`update_interval' is invoked in `update_syntax_table':

   void
   update_syntax_table (charpos, count, init, object)
        int charpos, count, init;
        Lisp_Object object;
   {
     /* ... ... */
     i = update_interval (i, charpos);

So `update_interval' is invoked with `pos' set to 0:

   INTERVAL
   update_interval (i, pos)
        register INTERVAL i;
        int pos;
   {
     if (NULL_INTERVAL_P (i))
       return NULL_INTERVAL;

     while (1)
       {
         if (pos < i->position)
           {
             /* Move left. */
             if (pos >= i->position - TOTAL_LENGTH (i->left))
               {
                 i->left->position = i->position - TOTAL_LENGTH (i->left)
                   + LEFT_TOTAL_LENGTH (i->left);
                 i = i->left;              /* Move to the left child */
               }
             else if (NULL_PARENT (i))
               error ("Point before start of properties");
             else
                 i = INTERVAL_PARENT (i);
             continue;
           }

`pos' is 0, and `*i' is

(gdb) p *i
$14 = {
 total_length = 1,
 position = 1,
 left = 0x0,
 right = 0x0,
 up = {
   interval = 0x86a1204,
   obj = 141169156
 },
 up_obj = 1,
 gcmarkbit = 0,
 write_protect = 0,
 visible = 0,
 front_sticky = 0,
 rear_sticky = 0,
 plist = 156480797
}
(gdb)

That's why the error is signaled, I think.

Regards,
Guanpeng Xu

_________________________________________________________________
Don't just search. Find. Check out the new MSN Search! http://search.msn.click-url.com/go/onm00200636ave/direct/01/





reply via email to

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