Mercurial > emacs
changeset 7250:67bb3bb1b62d
(Ftranspose_regions): Take addresses only after move gap.
Cast result of alloca. Use xmalloc instead, for large objects.
Always copy the middle portion directly; never put it in temp.
Always move the gap to START1 or END2, whichever is nearer.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 01 May 1994 09:15:10 +0000 |
parents | 876b3518fa78 |
children | 02cc4eee5928 |
files | src/editfns.c |
diffstat | 1 files changed, 54 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/src/editfns.c Sun May 01 08:55:23 1994 +0000 +++ b/src/editfns.c Sun May 01 09:15:10 1994 +0000 @@ -1697,7 +1697,7 @@ { register int start1, end1, start2, end2, gap, len1, len_mid, len2; - char *start1_addr, *start2_addr, *temp; + unsigned char *start1_addr, *start2_addr, *temp; #ifdef USE_TEXT_PROPERTIES INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2; @@ -1724,8 +1724,6 @@ end2 = glumph; } - start1_addr = BUF_CHAR_ADDRESS (current_buffer, start1); - start2_addr = BUF_CHAR_ADDRESS (current_buffer, start2); len1 = end1 - start1; len2 = end2 - start2; @@ -1755,6 +1753,19 @@ a go! I just didn't feel like doing it, so I will simply move the gap the minimum distance to get it out of the way, and then deal with an unbroken array. */ + + /* Make sure the gap won't interfere, by moving it out of the text + we will operate on. */ + if (start1 < gap && gap < end2) + { + if (gap - start1 < end2 - gap) + move_gap (start1); + else + move_gap (end2); + } + + start1_addr = BUF_CHAR_ADDRESS (current_buffer, start1); + start2_addr = BUF_CHAR_ADDRESS (current_buffer, start2); /* Hmmm... how about checking to see if the gap is large enough to use as the temporary storage? That would avoid an @@ -1765,13 +1776,6 @@ if (end1 == start2) /* adjacent regions */ { - if ((start1 < gap) && (gap <= end2)) - { - if ((gap - start1) < (end2 - gap) || (end2 == Z)) - move_gap (start1); - else - move_gap (end2 + 1); - } modify_region (current_buffer, start1, end2); record_change (start1, len1 + len2); @@ -1784,18 +1788,30 @@ /* First region smaller than second. */ if (len1 < len2) { - temp = alloca (len2); + /* We use alloca only if it is small, + because we want to avoid stack overflow. */ + if (len2 > 20000) + temp = (unsigned char *) xmalloc (len2); + else + temp = (unsigned char *) alloca (len2); bcopy (start2_addr, temp, len2); bcopy (start1_addr, start1_addr + len2, len1); bcopy (temp, start1_addr, len2); + if (len2 > 20000) + free (temp); } else /* First region not smaller than second. */ { - temp = alloca (len1); + if (len1 > 20000) + temp = (unsigned char *) xmalloc (len1); + else + temp = (unsigned char *) alloca (len1); bcopy (start1_addr, temp, len1); bcopy (start2_addr, start1_addr, len2); bcopy (temp, start1_addr + len2, len1); + if (len1 > 20000) + free (temp); } #ifdef USE_TEXT_PROPERTIES graft_intervals_into_buffer (tmp_interval1, start1 + len2, @@ -1807,11 +1823,6 @@ /* Non-adjacent regions, because end1 != start2, bleagh... */ else { - if (((start1 < gap) && (gap <= end1)) || (end2 == Z)) - move_gap (start1); - else if ((start2 < gap) && (gap <= end2)) - move_gap (end2 + 1); - if (len1 == len2) /* Regions are same size, though, how nice. */ { @@ -1826,10 +1837,15 @@ Fset_text_properties (start2, end2, Qnil, Qnil); #endif /* USE_TEXT_PROPERTIES */ - temp = alloca (len1); + if (len1 > 20000) + temp = (unsigned char *) xmalloc (len1); + else + temp = (unsigned char *) alloca (len1); bcopy (start1_addr, temp, len1); bcopy (start2_addr, start1_addr, len2); bcopy (temp, start2_addr, len1); + if (len1 > 20000) + free (temp); #ifdef USE_TEXT_PROPERTIES graft_intervals_into_buffer (tmp_interval1, start2, len1, current_buffer, 0); @@ -1851,12 +1867,17 @@ Fset_text_properties (start1, end2, Qnil, Qnil); #endif /* USE_TEXT_PROPERTIES */ - temp = alloca (len_mid + len2); /* holds mid area & region 2 */ - bcopy (start1_addr + len1, temp, len_mid); - bcopy (start2_addr, temp + len_mid, len2); + /* holds region 2 */ + if (len2 > 20000) + temp = (unsigned char *) xmalloc (len2); + else + temp = (unsigned char *) alloca (len2); + bcopy (start2_addr, temp, len2); bcopy (start1_addr, start1_addr + len_mid + len2, len1); - bcopy (temp + len_mid, start1_addr, len2); - bcopy (temp, start1_addr + len2, len_mid); + safe_bcopy (start1_addr + len1, start1_addr + len2, len_mid); + bcopy (temp, start1_addr, len2); + if (len2 > 20000) + free (temp); #ifdef USE_TEXT_PROPERTIES graft_intervals_into_buffer (tmp_interval1, end2 - len1, len1, current_buffer, 0); @@ -1880,12 +1901,17 @@ Fset_text_properties (start1, end2, Qnil, Qnil); #endif /* USE_TEXT_PROPERTIES */ - temp = alloca (len_mid + len1); /* holds mid area & region 1 */ - bcopy (start1_addr + len1, temp, len_mid); - bcopy (start1_addr, temp + len_mid, len1); + /* holds region 1 */ + if (len1 > 20000) + temp = (unsigned char *) xmalloc (len1); + else + temp = (unsigned char *) alloca (len1); + bcopy (start1_addr, temp, len1); bcopy (start2_addr, start1_addr, len2); - bcopy (temp + len_mid, start1_addr + len2 + len_mid, len1); - bcopy (temp, start1_addr + len2, len_mid); + bcopy (start1_addr + len1, start1_addr + len2, len_mid); + bcopy (temp, start1_addr + len2 + len_mid, len1); + if (len1 > 20000) + free (temp); #ifdef USE_TEXT_PROPERTIES graft_intervals_into_buffer (tmp_interval1, end2 - len1, len1, current_buffer, 0);