Hi, XEmacs!
On Mon, Mar 18, 2013 at 10:22:55PM +0000, Alan Mackenzie wrote:
On Sat, Mar 16, 2013 at 05:47:38PM +0000, Alan Mackenzie wrote:
> 1. Using an up to date XEmacs and Packages, create the following
> Objective C file, class-30.m:
>
#########################################################################
> @interface Foo
> (Bar)
> <X, Y, Z>
> @end
> @interface Foo (Bar)
> <X, Y, Z>
> @end
> #########################################################################
> 2. Kill the buffer and reload the file freshly.
> 3. M-: (scan-lists 1 1 -1). This (correctly) returns 17, just
after the
> "(" on L2.
> 4. Put point at BOL3 ("<X ,Y, Z>"). Narrow to
the first two lines with
> M-<, C-x n n.
> 5. With point at BOL3, (point-max), do M-: (looking-at
c-opt-cpp-start).
> 6. M-: (scan-lists 1 1 -1). This now (buggily) returns 2.
> N.B. c-opt-cpp-start is "\\s *#\\s
*\\([a-zA-Z0-9]+\\)".
I've now diagnosed this problem. The fault is in
update_syntax_cache
(syntax.c) in the following statement:
tmp_table = get_char_property (pos, Qsyntax_table,
cache->object,
EXTENT_AT_AFTER, 0);
When `cpos' is at (point-max) and the character just after
(point-max) has
an extent with a syntax-table property, get_char_property returns that
extent's property, even though that extent lies wholly in the inaccessible
portion of the buffer. In the above bug, tmp_table gets a cons (the
internal representation of the "open paren" syntax).
Later on, CONSP (tmp_table) is detected, causing it to mark the
syntax_cache as being at a syntax-table property. Sadly, the region it
marks as being thus propertised is the entire visible buffer portion.
Here is a patch to fix this bug. Actually, only the hunk in syntax.c is
strictly relevant to the bug. The rest of the patch prevents Fextent_at
and friends from accessing buffer positions just outside the accessible
portion.
Please consider installing this patch, wholly or partially. CC Mode will
not function properly without it.
diff -r ec3712ffd0e6 src/extents.c
--- a/src/extents.c Fri Mar 15 13:52:53 2013 -0600
+++ b/src/extents.c Sat Mar 30 18:22:45 2013 +0000
@@ -4339,17 +4339,18 @@
{
Bytexpos position;
EXTENT before_extent;
- enum extent_at_flag fl;
+ enum extent_at_flag fl = decode_extent_at_flag (at_flag);
+ unsigned int flags = (fl == EXTENT_AT_BEFORE) ? GB_NEED_CHAR_BEFORE :
+ (fl == EXTENT_AT_AFTER) ? GB_NEED_CHAR_AFTER : 0;
object = decode_buffer_or_string (object);
- position = get_buffer_or_string_pos_byte (object, pos, GB_NO_ERROR_IF_BAD);
+ position = get_buffer_or_string_pos_byte (object, pos, flags | GB_NO_ERROR_IF_BAD);
if (NILP (before))
before_extent = 0;
else
before_extent = decode_extent (before, DE_MUST_BE_ATTACHED);
if (before_extent && !EQ (object, extent_object (before_extent)))
invalid_argument ("extent not in specified buffer or string", object);
- fl = decode_extent_at_flag (at_flag);
return extent_at (position, object, property, before_extent, fl, 0);
}
@@ -4389,17 +4390,18 @@
{
Bytexpos position;
EXTENT before_extent;
- enum extent_at_flag fl;
+ enum extent_at_flag fl = decode_extent_at_flag (at_flag);
+ unsigned int flags = (fl == EXTENT_AT_BEFORE) ? GB_NEED_CHAR_BEFORE :
+ (fl == EXTENT_AT_AFTER) ? GB_NEED_CHAR_AFTER : 0;
object = decode_buffer_or_string (object);
- position = get_buffer_or_string_pos_byte (object, pos, GB_NO_ERROR_IF_BAD);
+ position = get_buffer_or_string_pos_byte (object, pos, flags | GB_NO_ERROR_IF_BAD);
if (NILP (before))
before_extent = 0;
else
before_extent = decode_extent (before, DE_MUST_BE_ATTACHED);
if (before_extent && !EQ (object, extent_object (before_extent)))
invalid_argument ("extent not in specified buffer or string", object);
- fl = decode_extent_at_flag (at_flag);
return extent_at (position, object, property, before_extent, fl, 1);
}
@@ -6278,9 +6280,12 @@
{
Bytexpos position;
int invert = 0;
+ enum extent_at_flag fl = decode_extent_at_flag (at_flag);
+ unsigned int flags = (fl == EXTENT_AT_BEFORE) ? GB_NEED_CHAR_BEFORE :
+ (fl == EXTENT_AT_AFTER) ? GB_NEED_CHAR_AFTER : 0;
object = decode_buffer_or_string (object);
- position = get_buffer_or_string_pos_byte (object, pos, GB_NO_ERROR_IF_BAD);
+ position = get_buffer_or_string_pos_byte (object, pos, flags | GB_NO_ERROR_IF_BAD);
/* We canonicalize the start/end-open/closed properties to the
non-default version -- "adding" the default property really
@@ -6300,9 +6305,7 @@
{
Lisp_Object val =
- get_char_property (position, prop, object,
- decode_extent_at_flag (at_flag),
- text_props_only);
+ get_char_property (position, prop, object, fl, text_props_only);
if (invert)
val = NILP (val) ? Qt : Qnil;
return val;
diff -r ec3712ffd0e6 src/lisp.h
--- a/src/lisp.h Fri Mar 15 13:52:53 2013 -0600
+++ b/src/lisp.h Sat Mar 30 18:22:45 2013 +0000
@@ -5885,6 +5885,8 @@
#define GB_COERCE_RANGE (1 << 3)
#define GB_NO_ERROR_IF_BAD (1 << 4)
#define GB_NEGATIVE_FROM_END (1 << 5)
+#define GB_NEED_CHAR_BEFORE (1 << 6)
+#define GB_NEED_CHAR_AFTER (1 << 7)
#define GB_HISTORICAL_STRING_BEHAVIOR (GB_NEGATIVE_FROM_END | GB_ALLOW_NIL)
Charbpos get_buffer_pos_char (struct buffer *b, Lisp_Object pos,
diff -r ec3712ffd0e6 src/syntax.c
--- a/src/syntax.c Fri Mar 15 13:52:53 2013 -0600
+++ b/src/syntax.c Sat Mar 30 18:22:45 2013 +0000
@@ -454,8 +454,12 @@
pos = buffer_or_string_charxpos_to_bytexpos (cache->object, cpos);
- tmp_table = get_char_property (pos, Qsyntax_table, cache->object,
- EXTENT_AT_AFTER, 0);
+ if (pos < buffer_or_string_accessible_end_byte (cache->object))
+ tmp_table = get_char_property (pos, Qsyntax_table, cache->object,
+ EXTENT_AT_AFTER, 0);
+ else
+ tmp_table = Qnil;
+
lim = next_previous_single_property_change (pos, Qsyntax_table,
cache->object, -1, 1, 0);
if (lim < 0)
diff -r ec3712ffd0e6 src/text.c
--- a/src/text.c Fri Mar 15 13:52:53 2013 -0600
+++ b/src/text.c Sat Mar 30 18:22:45 2013 +0000
@@ -3626,6 +3626,11 @@
of the range. If the positions are reversed, an error is
signalled.
+ GB_NEED_CHAR_BEFORE, GB_NEED_CHAR_AFTER
+
+ The character before or after POS must be in the accessible portion
+ of the buffer (BUF_BEGV to BUF_ZV).
+
The following is a combination flag:
GB_HISTORICAL_STRING_BEHAVIOR
@@ -3652,7 +3657,9 @@
CHECK_FIXNUM_COERCE_MARKER (pos);
ind = XFIXNUM (pos);
min_allowed = flags & GB_ALLOW_PAST_ACCESSIBLE ? BUF_BEG (b) : BUF_BEGV (b);
+ if (flags & GB_NEED_CHAR_BEFORE) min_allowed += 1;
max_allowed = flags & GB_ALLOW_PAST_ACCESSIBLE ? BUF_Z (b) : BUF_ZV (b);
+ if (flags & GB_NEED_CHAR_AFTER) max_allowed -= 1;
if (ind < min_allowed || ind > max_allowed)
{
@@ -3757,8 +3764,8 @@
Charcount known_length)
{
Charcount ccpos;
- Charcount min_allowed = 0;
- Charcount max_allowed = known_length;
+ Charcount min_allowed = (flags & GB_NEED_CHAR_BEFORE) ? 1 : 0;
+ Charcount max_allowed = (flags & GB_NEED_CHAR_AFTER) ? known_length -1 :
known_length;
/* Computation of KNOWN_LENGTH is potentially expensive so we pass
it in. */
--
Alan Mackenzie (Nuremberg, Germany).
_______________________________________________
XEmacs-Beta mailing list
XEmacs-Beta(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-beta