ptrdiff_t s, len;
bool modified = 0;
struct gcpro gcpro1;
+ int first_time = 1;
properties = validate_plist (properties);
if (NILP (properties))
if (NILP (object))
XSETBUFFER (object, current_buffer);
+ retry:
i = validate_interval_range (object, &start, &end, hard);
if (!i)
return Qnil;
copy_properties (unchanged, i);
}
- if (BUFFERP (object))
- modify_region (object, start, end);
+ if (BUFFERP (object) && first_time)
+ {
+ ptrdiff_t prev_total_length = TOTAL_LENGTH (i);
+ ptrdiff_t prev_pos = i->position;
+
+ modify_region (object, start, end);
+ /* If someone called us recursively as a side effect of
+ modify_region, and changed the intervals behind our back
+ (could happen if lock_file, called by prepare_to_modify_buffer,
+ triggers redisplay, and that calls add-text-properties again
+ in the same buffer), we cannot continue with I, because its
+ data changed. So we restart the interval analysis anew. */
+ if (TOTAL_LENGTH (i) != prev_total_length
+ || i->position != prev_pos)
+ {
+ first_time = 0;
+ goto retry;
+ }
+ }
/* We are at the beginning of interval I, with LEN chars to scan. */
for (;;)
INTERVAL i, unchanged;
ptrdiff_t s, len;
bool modified = 0;
+ int first_time = 1;
if (NILP (object))
XSETBUFFER (object, current_buffer);
+ retry:
i = validate_interval_range (object, &start, &end, soft);
if (!i)
return Qnil;
copy_properties (unchanged, i);
}
- if (BUFFERP (object))
- modify_region (object, start, end);
+ if (BUFFERP (object) && first_time)
+ {
+ ptrdiff_t prev_total_length = TOTAL_LENGTH (i);
+ ptrdiff_t prev_pos = i->position;
+
+ modify_region (object, start, end);
+ /* If someone called us recursively as a side effect of
+ modify_region, and changed the intervals behind our back
+ (could happen if lock_file, called by prepare_to_modify_buffer,
+ triggers redisplay, and that calls add-text-properties again
+ in the same buffer), we cannot continue with I, because its
+ data changed. So we restart the interval analysis anew. */
+ if (TOTAL_LENGTH (i) != prev_total_length
+ || i->position != prev_pos)
+ {
+ first_time = 0;
+ goto retry;
+ }
+ }
/* We are at the beginning of an interval, with len to scan */
for (;;)