diff options
| author | Richard M. Stallman | 1994-05-01 09:15:10 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-05-01 09:15:10 +0000 |
| commit | 3c6bc7d07a6b5ff37a9b96c59a954dc1000b9b65 (patch) | |
| tree | a6586c4e71b35f849aa3f14d31d9ebe2cfc84aaa /src | |
| parent | 6e42f5f8bb41579fdfd945c8d44bbaf46f3d9c17 (diff) | |
| download | emacs-3c6bc7d07a6b5ff37a9b96c59a954dc1000b9b65.tar.gz emacs-3c6bc7d07a6b5ff37a9b96c59a954dc1000b9b65.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/editfns.c | 82 |
1 files changed, 54 insertions, 28 deletions
diff --git a/src/editfns.c b/src/editfns.c index 5464c3ac717..ea1b7e42cd4 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -1697,7 +1697,7 @@ Transposing beyond buffer boundaries is an error.") | |||
| 1697 | { | 1697 | { |
| 1698 | register int start1, end1, start2, end2, | 1698 | register int start1, end1, start2, end2, |
| 1699 | gap, len1, len_mid, len2; | 1699 | gap, len1, len_mid, len2; |
| 1700 | char *start1_addr, *start2_addr, *temp; | 1700 | unsigned char *start1_addr, *start2_addr, *temp; |
| 1701 | 1701 | ||
| 1702 | #ifdef USE_TEXT_PROPERTIES | 1702 | #ifdef USE_TEXT_PROPERTIES |
| 1703 | INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2; | 1703 | INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2; |
| @@ -1724,8 +1724,6 @@ Transposing beyond buffer boundaries is an error.") | |||
| 1724 | end2 = glumph; | 1724 | end2 = glumph; |
| 1725 | } | 1725 | } |
| 1726 | 1726 | ||
| 1727 | start1_addr = BUF_CHAR_ADDRESS (current_buffer, start1); | ||
| 1728 | start2_addr = BUF_CHAR_ADDRESS (current_buffer, start2); | ||
| 1729 | len1 = end1 - start1; | 1727 | len1 = end1 - start1; |
| 1730 | len2 = end2 - start2; | 1728 | len2 = end2 - start2; |
| 1731 | 1729 | ||
| @@ -1755,6 +1753,19 @@ Transposing beyond buffer boundaries is an error.") | |||
| 1755 | a go! I just didn't feel like doing it, so I will simply move | 1753 | a go! I just didn't feel like doing it, so I will simply move |
| 1756 | the gap the minimum distance to get it out of the way, and then | 1754 | the gap the minimum distance to get it out of the way, and then |
| 1757 | deal with an unbroken array. */ | 1755 | deal with an unbroken array. */ |
| 1756 | |||
| 1757 | /* Make sure the gap won't interfere, by moving it out of the text | ||
| 1758 | we will operate on. */ | ||
| 1759 | if (start1 < gap && gap < end2) | ||
| 1760 | { | ||
| 1761 | if (gap - start1 < end2 - gap) | ||
| 1762 | move_gap (start1); | ||
| 1763 | else | ||
| 1764 | move_gap (end2); | ||
| 1765 | } | ||
| 1766 | |||
| 1767 | start1_addr = BUF_CHAR_ADDRESS (current_buffer, start1); | ||
| 1768 | start2_addr = BUF_CHAR_ADDRESS (current_buffer, start2); | ||
| 1758 | 1769 | ||
| 1759 | /* Hmmm... how about checking to see if the gap is large | 1770 | /* Hmmm... how about checking to see if the gap is large |
| 1760 | enough to use as the temporary storage? That would avoid an | 1771 | enough to use as the temporary storage? That would avoid an |
| @@ -1765,13 +1776,6 @@ Transposing beyond buffer boundaries is an error.") | |||
| 1765 | 1776 | ||
| 1766 | if (end1 == start2) /* adjacent regions */ | 1777 | if (end1 == start2) /* adjacent regions */ |
| 1767 | { | 1778 | { |
| 1768 | if ((start1 < gap) && (gap <= end2)) | ||
| 1769 | { | ||
| 1770 | if ((gap - start1) < (end2 - gap) || (end2 == Z)) | ||
| 1771 | move_gap (start1); | ||
| 1772 | else | ||
| 1773 | move_gap (end2 + 1); | ||
| 1774 | } | ||
| 1775 | modify_region (current_buffer, start1, end2); | 1779 | modify_region (current_buffer, start1, end2); |
| 1776 | record_change (start1, len1 + len2); | 1780 | record_change (start1, len1 + len2); |
| 1777 | 1781 | ||
| @@ -1784,18 +1788,30 @@ Transposing beyond buffer boundaries is an error.") | |||
| 1784 | /* First region smaller than second. */ | 1788 | /* First region smaller than second. */ |
| 1785 | if (len1 < len2) | 1789 | if (len1 < len2) |
| 1786 | { | 1790 | { |
| 1787 | temp = alloca (len2); | 1791 | /* We use alloca only if it is small, |
| 1792 | because we want to avoid stack overflow. */ | ||
| 1793 | if (len2 > 20000) | ||
| 1794 | temp = (unsigned char *) xmalloc (len2); | ||
| 1795 | else | ||
| 1796 | temp = (unsigned char *) alloca (len2); | ||
| 1788 | bcopy (start2_addr, temp, len2); | 1797 | bcopy (start2_addr, temp, len2); |
| 1789 | bcopy (start1_addr, start1_addr + len2, len1); | 1798 | bcopy (start1_addr, start1_addr + len2, len1); |
| 1790 | bcopy (temp, start1_addr, len2); | 1799 | bcopy (temp, start1_addr, len2); |
| 1800 | if (len2 > 20000) | ||
| 1801 | free (temp); | ||
| 1791 | } | 1802 | } |
| 1792 | else | 1803 | else |
| 1793 | /* First region not smaller than second. */ | 1804 | /* First region not smaller than second. */ |
| 1794 | { | 1805 | { |
| 1795 | temp = alloca (len1); | 1806 | if (len1 > 20000) |
| 1807 | temp = (unsigned char *) xmalloc (len1); | ||
| 1808 | else | ||
| 1809 | temp = (unsigned char *) alloca (len1); | ||
| 1796 | bcopy (start1_addr, temp, len1); | 1810 | bcopy (start1_addr, temp, len1); |
| 1797 | bcopy (start2_addr, start1_addr, len2); | 1811 | bcopy (start2_addr, start1_addr, len2); |
| 1798 | bcopy (temp, start1_addr + len2, len1); | 1812 | bcopy (temp, start1_addr + len2, len1); |
| 1813 | if (len1 > 20000) | ||
| 1814 | free (temp); | ||
| 1799 | } | 1815 | } |
| 1800 | #ifdef USE_TEXT_PROPERTIES | 1816 | #ifdef USE_TEXT_PROPERTIES |
| 1801 | graft_intervals_into_buffer (tmp_interval1, start1 + len2, | 1817 | graft_intervals_into_buffer (tmp_interval1, start1 + len2, |
| @@ -1807,11 +1823,6 @@ Transposing beyond buffer boundaries is an error.") | |||
| 1807 | /* Non-adjacent regions, because end1 != start2, bleagh... */ | 1823 | /* Non-adjacent regions, because end1 != start2, bleagh... */ |
| 1808 | else | 1824 | else |
| 1809 | { | 1825 | { |
| 1810 | if (((start1 < gap) && (gap <= end1)) || (end2 == Z)) | ||
| 1811 | move_gap (start1); | ||
| 1812 | else if ((start2 < gap) && (gap <= end2)) | ||
| 1813 | move_gap (end2 + 1); | ||
| 1814 | |||
| 1815 | if (len1 == len2) | 1826 | if (len1 == len2) |
| 1816 | /* Regions are same size, though, how nice. */ | 1827 | /* Regions are same size, though, how nice. */ |
| 1817 | { | 1828 | { |
| @@ -1826,10 +1837,15 @@ Transposing beyond buffer boundaries is an error.") | |||
| 1826 | Fset_text_properties (start2, end2, Qnil, Qnil); | 1837 | Fset_text_properties (start2, end2, Qnil, Qnil); |
| 1827 | #endif /* USE_TEXT_PROPERTIES */ | 1838 | #endif /* USE_TEXT_PROPERTIES */ |
| 1828 | 1839 | ||
| 1829 | temp = alloca (len1); | 1840 | if (len1 > 20000) |
| 1841 | temp = (unsigned char *) xmalloc (len1); | ||
| 1842 | else | ||
| 1843 | temp = (unsigned char *) alloca (len1); | ||
| 1830 | bcopy (start1_addr, temp, len1); | 1844 | bcopy (start1_addr, temp, len1); |
| 1831 | bcopy (start2_addr, start1_addr, len2); | 1845 | bcopy (start2_addr, start1_addr, len2); |
| 1832 | bcopy (temp, start2_addr, len1); | 1846 | bcopy (temp, start2_addr, len1); |
| 1847 | if (len1 > 20000) | ||
| 1848 | free (temp); | ||
| 1833 | #ifdef USE_TEXT_PROPERTIES | 1849 | #ifdef USE_TEXT_PROPERTIES |
| 1834 | graft_intervals_into_buffer (tmp_interval1, start2, | 1850 | graft_intervals_into_buffer (tmp_interval1, start2, |
| 1835 | len1, current_buffer, 0); | 1851 | len1, current_buffer, 0); |
| @@ -1851,12 +1867,17 @@ Transposing beyond buffer boundaries is an error.") | |||
| 1851 | Fset_text_properties (start1, end2, Qnil, Qnil); | 1867 | Fset_text_properties (start1, end2, Qnil, Qnil); |
| 1852 | #endif /* USE_TEXT_PROPERTIES */ | 1868 | #endif /* USE_TEXT_PROPERTIES */ |
| 1853 | 1869 | ||
| 1854 | temp = alloca (len_mid + len2); /* holds mid area & region 2 */ | 1870 | /* holds region 2 */ |
| 1855 | bcopy (start1_addr + len1, temp, len_mid); | 1871 | if (len2 > 20000) |
| 1856 | bcopy (start2_addr, temp + len_mid, len2); | 1872 | temp = (unsigned char *) xmalloc (len2); |
| 1873 | else | ||
| 1874 | temp = (unsigned char *) alloca (len2); | ||
| 1875 | bcopy (start2_addr, temp, len2); | ||
| 1857 | bcopy (start1_addr, start1_addr + len_mid + len2, len1); | 1876 | bcopy (start1_addr, start1_addr + len_mid + len2, len1); |
| 1858 | bcopy (temp + len_mid, start1_addr, len2); | 1877 | safe_bcopy (start1_addr + len1, start1_addr + len2, len_mid); |
| 1859 | bcopy (temp, start1_addr + len2, len_mid); | 1878 | bcopy (temp, start1_addr, len2); |
| 1879 | if (len2 > 20000) | ||
| 1880 | free (temp); | ||
| 1860 | #ifdef USE_TEXT_PROPERTIES | 1881 | #ifdef USE_TEXT_PROPERTIES |
| 1861 | graft_intervals_into_buffer (tmp_interval1, end2 - len1, | 1882 | graft_intervals_into_buffer (tmp_interval1, end2 - len1, |
| 1862 | len1, current_buffer, 0); | 1883 | len1, current_buffer, 0); |
| @@ -1880,12 +1901,17 @@ Transposing beyond buffer boundaries is an error.") | |||
| 1880 | Fset_text_properties (start1, end2, Qnil, Qnil); | 1901 | Fset_text_properties (start1, end2, Qnil, Qnil); |
| 1881 | #endif /* USE_TEXT_PROPERTIES */ | 1902 | #endif /* USE_TEXT_PROPERTIES */ |
| 1882 | 1903 | ||
| 1883 | temp = alloca (len_mid + len1); /* holds mid area & region 1 */ | 1904 | /* holds region 1 */ |
| 1884 | bcopy (start1_addr + len1, temp, len_mid); | 1905 | if (len1 > 20000) |
| 1885 | bcopy (start1_addr, temp + len_mid, len1); | 1906 | temp = (unsigned char *) xmalloc (len1); |
| 1907 | else | ||
| 1908 | temp = (unsigned char *) alloca (len1); | ||
| 1909 | bcopy (start1_addr, temp, len1); | ||
| 1886 | bcopy (start2_addr, start1_addr, len2); | 1910 | bcopy (start2_addr, start1_addr, len2); |
| 1887 | bcopy (temp + len_mid, start1_addr + len2 + len_mid, len1); | 1911 | bcopy (start1_addr + len1, start1_addr + len2, len_mid); |
| 1888 | bcopy (temp, start1_addr + len2, len_mid); | 1912 | bcopy (temp, start1_addr + len2 + len_mid, len1); |
| 1913 | if (len1 > 20000) | ||
| 1914 | free (temp); | ||
| 1889 | #ifdef USE_TEXT_PROPERTIES | 1915 | #ifdef USE_TEXT_PROPERTIES |
| 1890 | graft_intervals_into_buffer (tmp_interval1, end2 - len1, | 1916 | graft_intervals_into_buffer (tmp_interval1, end2 - len1, |
| 1891 | len1, current_buffer, 0); | 1917 | len1, current_buffer, 0); |