aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 7eb37bb12da..9dc6ef79e39 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1786,13 +1786,12 @@ allocate_string (void)
1786 1786
1787 If CLEARIT, also clear the other bytes of S->u.s.data. */ 1787 If CLEARIT, also clear the other bytes of S->u.s.data. */
1788 1788
1789void 1789static void
1790allocate_string_data (struct Lisp_String *s, 1790allocate_string_data (struct Lisp_String *s,
1791 EMACS_INT nchars, EMACS_INT nbytes, bool clearit) 1791 EMACS_INT nchars, EMACS_INT nbytes, bool clearit)
1792{ 1792{
1793 sdata *data, *old_data; 1793 sdata *data;
1794 struct sblock *b; 1794 struct sblock *b;
1795 ptrdiff_t old_nbytes;
1796 1795
1797 if (STRING_BYTES_MAX < nbytes) 1796 if (STRING_BYTES_MAX < nbytes)
1798 string_overflow (); 1797 string_overflow ();
@@ -1800,13 +1799,6 @@ allocate_string_data (struct Lisp_String *s,
1800 /* Determine the number of bytes needed to store NBYTES bytes 1799 /* Determine the number of bytes needed to store NBYTES bytes
1801 of string data. */ 1800 of string data. */
1802 ptrdiff_t needed = sdata_size (nbytes); 1801 ptrdiff_t needed = sdata_size (nbytes);
1803 if (s->u.s.data)
1804 {
1805 old_data = SDATA_OF_STRING (s);
1806 old_nbytes = STRING_BYTES (s);
1807 }
1808 else
1809 old_data = NULL;
1810 1802
1811 MALLOC_BLOCK_INPUT; 1803 MALLOC_BLOCK_INPUT;
1812 1804
@@ -1875,16 +1867,53 @@ allocate_string_data (struct Lisp_String *s,
1875 GC_STRING_OVERRUN_COOKIE_SIZE); 1867 GC_STRING_OVERRUN_COOKIE_SIZE);
1876#endif 1868#endif
1877 1869
1878 /* Note that Faset may call to this function when S has already data 1870 tally_consing (needed);
1879 assigned. In this case, mark data as free by setting it's string 1871}
1880 back-pointer to null, and record the size of the data in it. */ 1872
1881 if (old_data) 1873/* Reallocate the data for STRING when a single character is replaced.
1874 The character is at byte offset CIDX_BYTE in the string.
1875 The character being replaced is CLEN bytes long,
1876 and the character that will replace it is NEW_CLEN bytes long.
1877 Return the address of where the caller should store the
1878 the new character. */
1879
1880unsigned char *
1881resize_string_data (Lisp_Object string, ptrdiff_t cidx_byte,
1882 int clen, int new_clen)
1883{
1884 sdata *old_sdata = SDATA_OF_STRING (XSTRING (string));
1885 ptrdiff_t nchars = SCHARS (string);
1886 ptrdiff_t nbytes = SBYTES (string);
1887 ptrdiff_t new_nbytes = nbytes + (new_clen - clen);
1888 unsigned char *data = SDATA (string);
1889 unsigned char *new_charaddr;
1890
1891 if (sdata_size (nbytes) == sdata_size (new_nbytes))
1892 {
1893 /* No need to reallocate, as the size change falls within the
1894 alignment slop. */
1895 new_charaddr = data + cidx_byte;
1896 memmove (new_charaddr + new_clen, new_charaddr + clen,
1897 nbytes - (cidx_byte + (clen - 1)));
1898 }
1899 else
1882 { 1900 {
1883 SDATA_NBYTES (old_data) = old_nbytes; 1901 allocate_string_data (XSTRING (string), nchars, new_nbytes, false);
1884 old_data->string = NULL; 1902 unsigned char *new_data = SDATA (string);
1903 new_charaddr = new_data + cidx_byte;
1904 memcpy (new_charaddr + new_clen, data + cidx_byte + clen,
1905 nbytes - (cidx_byte + clen));
1906 memcpy (new_data, data, cidx_byte);
1907
1908 /* Mark old string data as free by setting its string back-pointer
1909 to null, and record the size of the data in it. */
1910 SDATA_NBYTES (old_sdata) = nbytes;
1911 old_sdata->string = NULL;
1885 } 1912 }
1886 1913
1887 tally_consing (needed); 1914 clear_string_char_byte_cache ();
1915
1916 return new_charaddr;
1888} 1917}
1889 1918
1890 1919