diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 9 | ||||
| -rw-r--r-- | src/textprop.c | 125 |
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 @@ | |||
| 1 | 2013-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 | |||
| 1 | 2013-02-25 Stefan Monnier <monnier@iro.umontreal.ca> | 10 | 2013-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. |