aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/textprop.c125
2 files changed, 75 insertions, 59 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 4f2fb4c1d53..dc9b97c3c03 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
12013-02-25 Eli Zaretskii <eliz@gnu.org>
2
3 * textprop.c (Fadd_text_properties, Fremove_text_properties)
4 (Fremove_list_of_text_properties): Skip all of the intervals in
5 the region between START and END that already have resp. don't
6 have the requested properties, not just the first one. Add
7 assertions that the loop afterwards always modifies the
8 properties. (Bug#13743)
9
12013-02-25 Stefan Monnier <monnier@iro.umontreal.ca> 102013-02-25 Stefan Monnier <monnier@iro.umontreal.ca>
2 11
3 * callint.c (Fcall_interactively): Use the right lexical environment 12 * callint.c (Fcall_interactively): Use the right lexical environment
diff --git a/src/textprop.c b/src/textprop.c
index c1f6e59bf2e..49fe427913c 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -1133,6 +1133,7 @@ Return t if any property value actually changed, nil otherwise. */)
1133 register ptrdiff_t s, len; 1133 register ptrdiff_t s, len;
1134 register int modified = 0; 1134 register int modified = 0;
1135 struct gcpro gcpro1; 1135 struct gcpro gcpro1;
1136 ptrdiff_t got;
1136 1137
1137 properties = validate_plist (properties); 1138 properties = validate_plist (properties);
1138 if (NILP (properties)) 1139 if (NILP (properties))
@@ -1152,26 +1153,25 @@ Return t if any property value actually changed, nil otherwise. */)
1152 and live buffers are always protected. */ 1153 and live buffers are always protected. */
1153 GCPRO1 (properties); 1154 GCPRO1 (properties);
1154 1155
1155 /* If we're not starting on an interval boundary, we have to 1156 /* If this interval already has the properties, we can skip it. */
1156 split this interval. */ 1157 if (interval_has_all_properties (properties, i))
1157 if (i->position != s)
1158 { 1158 {
1159 /* If this interval already has the properties, we can 1159 got = LENGTH (i) - (s - i->position);
1160 skip it. */ 1160 do {
1161 if (interval_has_all_properties (properties, i)) 1161 if (got >= len)
1162 { 1162 RETURN_UNGCPRO (Qnil);
1163 ptrdiff_t got = (LENGTH (i) - (s - i->position)); 1163 len -= got;
1164 if (got >= len) 1164 i = next_interval (i);
1165 RETURN_UNGCPRO (Qnil); 1165 got = LENGTH (i);
1166 len -= got; 1166 } while (interval_has_all_properties (properties, i));
1167 i = next_interval (i); 1167 }
1168 } 1168 else if (i->position != s)
1169 else 1169 {
1170 { 1170 /* If we're not starting on an interval boundary, we have to
1171 unchanged = i; 1171 split this interval. */
1172 i = split_interval_right (unchanged, s - unchanged->position); 1172 unchanged = i;
1173 copy_properties (unchanged, i); 1173 i = split_interval_right (unchanged, s - unchanged->position);
1174 } 1174 copy_properties (unchanged, i);
1175 } 1175 }
1176 1176
1177 if (BUFFERP (object)) 1177 if (BUFFERP (object))
@@ -1195,7 +1195,8 @@ Return t if any property value actually changed, nil otherwise. */)
1195 signal_after_change (XINT (start), XINT (end) - XINT (start), 1195 signal_after_change (XINT (start), XINT (end) - XINT (start),
1196 XINT (end) - XINT (start)); 1196 XINT (end) - XINT (start));
1197 1197
1198 return modified ? Qt : Qnil; 1198 eassert (modified);
1199 return Qt;
1199 } 1200 }
1200 1201
1201 if (LENGTH (i) == len) 1202 if (LENGTH (i) == len)
@@ -1426,6 +1427,7 @@ Use `set-text-properties' if you want to remove all text properties. */)
1426 register INTERVAL i, unchanged; 1427 register INTERVAL i, unchanged;
1427 register ptrdiff_t s, len; 1428 register ptrdiff_t s, len;
1428 register int modified = 0; 1429 register int modified = 0;
1430 ptrdiff_t got;
1429 1431
1430 if (NILP (object)) 1432 if (NILP (object))
1431 XSETBUFFER (object, current_buffer); 1433 XSETBUFFER (object, current_buffer);
@@ -1437,26 +1439,25 @@ Use `set-text-properties' if you want to remove all text properties. */)
1437 s = XINT (start); 1439 s = XINT (start);
1438 len = XINT (end) - s; 1440 len = XINT (end) - s;
1439 1441
1440 if (i->position != s) 1442 /* If there are no properties on this entire interval, return. */
1443 if (! interval_has_some_properties (properties, i))
1441 { 1444 {
1442 /* No properties on this first interval -- return if 1445 got = (LENGTH (i) - (s - i->position));
1443 it covers the entire region. */ 1446 do {
1444 if (! interval_has_some_properties (properties, i)) 1447 if (got >= len)
1445 { 1448 return Qnil;
1446 ptrdiff_t got = (LENGTH (i) - (s - i->position)); 1449 len -= got;
1447 if (got >= len) 1450 i = next_interval (i);
1448 return Qnil; 1451 got = LENGTH (i);
1449 len -= got; 1452 } while (! interval_has_some_properties (properties, i));
1450 i = next_interval (i); 1453 }
1451 } 1454 /* Split away the beginning of this interval; what we don't
1452 /* Split away the beginning of this interval; what we don't 1455 want to modify. */
1453 want to modify. */ 1456 else if (i->position != s)
1454 else 1457 {
1455 { 1458 unchanged = i;
1456 unchanged = i; 1459 i = split_interval_right (unchanged, s - unchanged->position);
1457 i = split_interval_right (unchanged, s - unchanged->position); 1460 copy_properties (unchanged, i);
1458 copy_properties (unchanged, i);
1459 }
1460 } 1461 }
1461 1462
1462 if (BUFFERP (object)) 1463 if (BUFFERP (object))
@@ -1470,7 +1471,13 @@ Use `set-text-properties' if you want to remove all text properties. */)
1470 if (LENGTH (i) >= len) 1471 if (LENGTH (i) >= len)
1471 { 1472 {
1472 if (! interval_has_some_properties (properties, i)) 1473 if (! interval_has_some_properties (properties, i))
1473 return modified ? Qt : Qnil; 1474 {
1475 eassert (modified);
1476 if (BUFFERP (object))
1477 signal_after_change (XINT (start), XINT (end) - XINT (start),
1478 XINT (end) - XINT (start));
1479 return Qt;
1480 }
1474 1481
1475 if (LENGTH (i) == len) 1482 if (LENGTH (i) == len)
1476 { 1483 {
@@ -1512,6 +1519,7 @@ Return t if any property was actually removed, nil otherwise. */)
1512 register ptrdiff_t s, len; 1519 register ptrdiff_t s, len;
1513 register int modified = 0; 1520 register int modified = 0;
1514 Lisp_Object properties; 1521 Lisp_Object properties;
1522 ptrdiff_t got;
1515 properties = list_of_properties; 1523 properties = list_of_properties;
1516 1524
1517 if (NILP (object)) 1525 if (NILP (object))
@@ -1524,26 +1532,25 @@ Return t if any property was actually removed, nil otherwise. */)
1524 s = XINT (start); 1532 s = XINT (start);
1525 len = XINT (end) - s; 1533 len = XINT (end) - s;
1526 1534
1527 if (i->position != s) 1535 /* If there are no properties on the interval, return. */
1536 if (! interval_has_some_properties_list (properties, i))
1528 { 1537 {
1529 /* No properties on this first interval -- return if 1538 got = (LENGTH (i) - (s - i->position));
1530 it covers the entire region. */ 1539 do {
1531 if (! interval_has_some_properties_list (properties, i)) 1540 if (got >= len)
1532 { 1541 return Qnil;
1533 ptrdiff_t got = (LENGTH (i) - (s - i->position)); 1542 len -= got;
1534 if (got >= len) 1543 i = next_interval (i);
1535 return Qnil; 1544 got = LENGTH (i);
1536 len -= got; 1545 } while (! interval_has_some_properties_list (properties, i));
1537 i = next_interval (i); 1546 }
1538 } 1547 /* Split away the beginning of this interval; what we don't
1539 /* Split away the beginning of this interval; what we don't 1548 want to modify. */
1540 want to modify. */ 1549 else if (i->position != s)
1541 else 1550 {
1542 { 1551 unchanged = i;
1543 unchanged = i; 1552 i = split_interval_right (unchanged, s - unchanged->position);
1544 i = split_interval_right (unchanged, s - unchanged->position); 1553 copy_properties (unchanged, i);
1545 copy_properties (unchanged, i);
1546 }
1547 } 1554 }
1548 1555
1549 /* We are at the beginning of an interval, with len to scan. 1556 /* We are at the beginning of an interval, with len to scan.