Mercurial > hg > xemacs-beta
comparison src/buffer.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | aabb7f5b1c81 |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
72 #include "chartab.h" | 72 #include "chartab.h" |
73 #include "commands.h" | 73 #include "commands.h" |
74 #include "elhash.h" | 74 #include "elhash.h" |
75 #include "extents.h" | 75 #include "extents.h" |
76 #include "faces.h" | 76 #include "faces.h" |
77 #ifdef FILE_CODING | |
78 #include "file-coding.h" | |
79 #endif | |
77 #include "frame.h" | 80 #include "frame.h" |
78 #include "insdel.h" | 81 #include "insdel.h" |
82 #include "lstream.h" | |
79 #include "process.h" /* for kill_buffer_processes */ | 83 #include "process.h" /* for kill_buffer_processes */ |
80 #ifdef REGION_CACHE_NEEDS_WORK | 84 #ifdef REGION_CACHE_NEEDS_WORK |
81 #include "region-cache.h" | 85 #include "region-cache.h" |
82 #endif | 86 #endif |
83 #include "specifier.h" | 87 #include "specifier.h" |
94 The default value occupies the same slot in this structure | 98 The default value occupies the same slot in this structure |
95 as an individual buffer's value occupies in that buffer. | 99 as an individual buffer's value occupies in that buffer. |
96 Setting the default value also goes through the alist of buffers | 100 Setting the default value also goes through the alist of buffers |
97 and stores into each buffer that does not say it has a local value. */ | 101 and stores into each buffer that does not say it has a local value. */ |
98 Lisp_Object Vbuffer_defaults; | 102 Lisp_Object Vbuffer_defaults; |
103 static void *buffer_defaults_saved_slots; | |
99 | 104 |
100 /* This structure marks which slots in a buffer have corresponding | 105 /* This structure marks which slots in a buffer have corresponding |
101 default values in Vbuffer_defaults. | 106 default values in Vbuffer_defaults. |
102 Each such slot has a nonzero value in this structure. | 107 Each such slot has a nonzero value in this structure. |
103 The value has only one nonzero bit. | 108 The value has only one nonzero bit. |
131 char initial_directory[MAXPATHLEN+1]; | 136 char initial_directory[MAXPATHLEN+1]; |
132 | 137 |
133 /* This structure holds the names of symbols whose values may be | 138 /* This structure holds the names of symbols whose values may be |
134 buffer-local. It is indexed and accessed in the same way as the above. */ | 139 buffer-local. It is indexed and accessed in the same way as the above. */ |
135 static Lisp_Object Vbuffer_local_symbols; | 140 static Lisp_Object Vbuffer_local_symbols; |
141 static void *buffer_local_symbols_saved_slots; | |
136 | 142 |
137 /* Alist of all buffer names vs the buffers. */ | 143 /* Alist of all buffer names vs the buffers. */ |
138 /* This used to be a variable, but is no longer, | 144 /* This used to be a variable, but is no longer, |
139 to prevent lossage due to user rplac'ing this alist or its elements. | 145 to prevent lossage due to user rplac'ing this alist or its elements. |
140 Note that there is a per-frame copy of this as well; the frame slot | 146 Note that there is a per-frame copy of this as well; the frame slot |
187 Lisp_Object QSFundamental; /* A string "Fundamental" */ | 193 Lisp_Object QSFundamental; /* A string "Fundamental" */ |
188 Lisp_Object QSscratch; /* "*scratch*" */ | 194 Lisp_Object QSscratch; /* "*scratch*" */ |
189 Lisp_Object Qdefault_directory; | 195 Lisp_Object Qdefault_directory; |
190 | 196 |
191 Lisp_Object Qkill_buffer_hook; | 197 Lisp_Object Qkill_buffer_hook; |
192 Lisp_Object Qbuffer_file_name, Qbuffer_undo_list; | 198 Lisp_Object Qrecord_buffer_hook; |
193 | 199 |
194 Lisp_Object Qrename_auto_save_file; | 200 Lisp_Object Qrename_auto_save_file; |
195 | 201 |
196 Lisp_Object Qget_file_buffer; | 202 Lisp_Object Qget_file_buffer; |
197 Lisp_Object Qchange_major_mode_hook, Vchange_major_mode_hook; | 203 Lisp_Object Qchange_major_mode_hook, Vchange_major_mode_hook; |
218 XSETBUFFER (obj, buf); | 224 XSETBUFFER (obj, buf); |
219 return obj; | 225 return obj; |
220 } | 226 } |
221 | 227 |
222 static Lisp_Object | 228 static Lisp_Object |
223 mark_buffer (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 229 mark_buffer (Lisp_Object obj) |
224 { | 230 { |
225 struct buffer *buf = XBUFFER (obj); | 231 struct buffer *buf = XBUFFER (obj); |
226 | 232 |
227 /* Truncate undo information. */ | 233 /* Truncate undo information. */ |
228 buf->undo_list = truncate_undo_list (buf->undo_list, | 234 buf->undo_list = truncate_undo_list (buf->undo_list, |
229 undo_threshold, | 235 undo_threshold, |
230 undo_high_threshold); | 236 undo_high_threshold); |
231 | 237 |
232 #define MARKED_SLOT(x) ((void) (markobj (buf->x))); | 238 #define MARKED_SLOT(x) mark_object (buf->x) |
233 #include "bufslots.h" | 239 #include "bufslots.h" |
234 #undef MARKED_SLOT | 240 #undef MARKED_SLOT |
235 | 241 |
236 markobj (buf->extent_info); | 242 mark_object (buf->extent_info); |
237 if (buf->text) | 243 if (buf->text) |
238 markobj (buf->text->line_number_cache); | 244 mark_object (buf->text->line_number_cache); |
239 | 245 |
240 /* Don't mark normally through the children slot. | 246 /* Don't mark normally through the children slot. |
241 (Actually, in this case, it doesn't matter.) */ | 247 (Actually, in this case, it doesn't matter.) */ |
242 if (! EQ (buf->indirect_children, Qnull_pointer)) | 248 if (! EQ (buf->indirect_children, Qnull_pointer)) |
243 mark_conses_in_list (buf->indirect_children); | 249 mark_conses_in_list (buf->indirect_children); |
274 | 280 |
275 /* We do not need a finalize method to handle a buffer's children list | 281 /* We do not need a finalize method to handle a buffer's children list |
276 because all buffers have `kill-buffer' applied to them before | 282 because all buffers have `kill-buffer' applied to them before |
277 they disappear, and the children removal happens then. */ | 283 they disappear, and the children removal happens then. */ |
278 DEFINE_LRECORD_IMPLEMENTATION ("buffer", buffer, | 284 DEFINE_LRECORD_IMPLEMENTATION ("buffer", buffer, |
279 mark_buffer, print_buffer, 0, 0, 0, | 285 mark_buffer, print_buffer, 0, 0, 0, 0, |
280 struct buffer); | 286 struct buffer); |
281 | 287 |
282 DEFUN ("bufferp", Fbufferp, 1, 1, 0, /* | 288 DEFUN ("bufferp", Fbufferp, 1, 1, 0, /* |
283 Return t if OBJECT is an editor buffer. | 289 Return t if OBJECT is an editor buffer. |
284 */ | 290 */ |
539 } | 545 } |
540 | 546 |
541 static struct buffer * | 547 static struct buffer * |
542 allocate_buffer (void) | 548 allocate_buffer (void) |
543 { | 549 { |
544 struct buffer *b = alloc_lcrecord_type (struct buffer, lrecord_buffer); | 550 struct buffer *b = alloc_lcrecord_type (struct buffer, &lrecord_buffer); |
545 | 551 |
546 copy_lcrecord (b, XBUFFER (Vbuffer_defaults)); | 552 copy_lcrecord (b, XBUFFER (Vbuffer_defaults)); |
547 | 553 |
548 return b; | 554 return b; |
549 } | 555 } |
1178 Lisp_Object killp; | 1184 Lisp_Object killp; |
1179 GCPRO1 (buf); | 1185 GCPRO1 (buf); |
1180 killp = call1 | 1186 killp = call1 |
1181 (Qyes_or_no_p, | 1187 (Qyes_or_no_p, |
1182 (emacs_doprnt_string_c | 1188 (emacs_doprnt_string_c |
1183 ((CONST Bufbyte *) GETTEXT ("Buffer %s modified; kill anyway? "), | 1189 ((const Bufbyte *) GETTEXT ("Buffer %s modified; kill anyway? "), |
1184 Qnil, -1, XSTRING_DATA (b->name)))); | 1190 Qnil, -1, XSTRING_DATA (b->name)))); |
1185 UNGCPRO; | 1191 UNGCPRO; |
1186 if (NILP (killp)) | 1192 if (NILP (killp)) |
1187 return Qnil; | 1193 return Qnil; |
1188 b = XBUFFER (buf); /* Hypothetical relocating GC. */ | 1194 b = XBUFFER (buf); /* Hypothetical relocating GC. */ |
1404 f->buffer_alist = XCDR (f->buffer_alist); | 1410 f->buffer_alist = XCDR (f->buffer_alist); |
1405 else | 1411 else |
1406 XCDR (prev) = XCDR (XCDR (prev)); | 1412 XCDR (prev) = XCDR (XCDR (prev)); |
1407 XCDR (lynk) = f->buffer_alist; | 1413 XCDR (lynk) = f->buffer_alist; |
1408 f->buffer_alist = lynk; | 1414 f->buffer_alist = lynk; |
1415 | |
1416 va_run_hook_with_args (Qrecord_buffer_hook, 1, buffer); | |
1417 | |
1409 return Qnil; | 1418 return Qnil; |
1410 } | 1419 } |
1411 | 1420 |
1412 DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, 1, 1, 0, /* | 1421 DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, 1, 1, 0, /* |
1413 Set an appropriate major mode for BUFFER, according to `default-major-mode'. | 1422 Set an appropriate major mode for BUFFER, according to `default-major-mode'. |
1617 There it is the least likely candidate for `other-buffer' to return; | 1626 There it is the least likely candidate for `other-buffer' to return; |
1618 thus, the least likely buffer for \\[switch-to-buffer] to select by default. | 1627 thus, the least likely buffer for \\[switch-to-buffer] to select by default. |
1619 If BUFFER is nil or omitted, bury the current buffer. | 1628 If BUFFER is nil or omitted, bury the current buffer. |
1620 Also, if BUFFER is nil or omitted, remove the current buffer from the | 1629 Also, if BUFFER is nil or omitted, remove the current buffer from the |
1621 selected window if it is displayed there. | 1630 selected window if it is displayed there. |
1631 Because of this, you may need to specify (current-buffer) as | |
1632 BUFFER when calling from minibuffer. | |
1622 If BEFORE is non-nil, it specifies a buffer before which BUFFER | 1633 If BEFORE is non-nil, it specifies a buffer before which BUFFER |
1623 will be placed, instead of being placed at the end. | 1634 will be placed, instead of being placed at the end. |
1624 */ | 1635 */ |
1625 (buffer, before)) | 1636 (buffer, before)) |
1626 { | 1637 { |
1796 return Fnreverse (val); | 1807 return Fnreverse (val); |
1797 } | 1808 } |
1798 | 1809 |
1799 #endif /* MEMORY_USAGE_STATS */ | 1810 #endif /* MEMORY_USAGE_STATS */ |
1800 | 1811 |
1812 | |
1813 /************************************************************************/ | |
1814 /* Implement TO_EXTERNAL_FORMAT, TO_INTERNAL_FORMAT */ | |
1815 /************************************************************************/ | |
1816 | |
1817 /* This implementation should probably be elsewhere, but it can't be | |
1818 in file-coding.c since that file is only available if FILE_CODING | |
1819 is defined. */ | |
1820 #ifdef FILE_CODING | |
1821 static int | |
1822 coding_system_is_binary (Lisp_Object coding_system) | |
1823 { | |
1824 Lisp_Coding_System *cs = XCODING_SYSTEM (coding_system); | |
1825 return | |
1826 (CODING_SYSTEM_TYPE (cs) == CODESYS_NO_CONVERSION && | |
1827 CODING_SYSTEM_EOL_TYPE (cs) == EOL_LF && | |
1828 EQ (CODING_SYSTEM_POST_READ_CONVERSION (cs), Qnil) && | |
1829 EQ (CODING_SYSTEM_PRE_WRITE_CONVERSION (cs), Qnil)); | |
1830 } | |
1831 #else | |
1832 #define coding_system_is_binary(coding_system) 1 | |
1833 #endif | |
1834 | |
1835 static Extbyte_dynarr *conversion_out_dynarr; | |
1836 static Bufbyte_dynarr *conversion_in_dynarr; | |
1837 | |
1838 static int dfc_convert_to_external_format_in_use; | |
1839 static int dfc_convert_to_internal_format_in_use; | |
1840 | |
1841 static Lisp_Object | |
1842 dfc_convert_to_external_format_reset_in_use (Lisp_Object value) | |
1843 { | |
1844 dfc_convert_to_external_format_in_use = XINT (value); | |
1845 return Qnil; | |
1846 } | |
1847 | |
1848 static Lisp_Object | |
1849 dfc_convert_to_internal_format_reset_in_use (Lisp_Object value) | |
1850 { | |
1851 dfc_convert_to_internal_format_in_use = XINT (value); | |
1852 return Qnil; | |
1853 } | |
1854 | |
1855 void | |
1856 dfc_convert_to_external_format (dfc_conversion_type source_type, | |
1857 dfc_conversion_data *source, | |
1858 #ifdef FILE_CODING | |
1859 Lisp_Object coding_system, | |
1860 #endif | |
1861 dfc_conversion_type sink_type, | |
1862 dfc_conversion_data *sink) | |
1863 { | |
1864 int count = specpdl_depth (); | |
1865 | |
1866 type_checking_assert | |
1867 (((source_type == DFC_TYPE_DATA) || | |
1868 (source_type == DFC_TYPE_LISP_LSTREAM && LSTREAMP (source->lisp_object)) || | |
1869 (source_type == DFC_TYPE_LISP_STRING && STRINGP (source->lisp_object))) | |
1870 && | |
1871 ((sink_type == DFC_TYPE_DATA) || | |
1872 (sink_type == DFC_TYPE_LISP_LSTREAM && LSTREAMP (source->lisp_object)))); | |
1873 | |
1874 if (dfc_convert_to_external_format_in_use != 0) | |
1875 error ("Can't call a conversion function from a conversion function"); | |
1876 else | |
1877 dfc_convert_to_external_format_in_use = 1; | |
1878 | |
1879 record_unwind_protect (dfc_convert_to_external_format_reset_in_use, | |
1880 Qzero); | |
1881 | |
1882 #ifdef FILE_CODING | |
1883 coding_system = Fget_coding_system (coding_system); | |
1884 #endif | |
1885 | |
1886 Dynarr_reset (conversion_out_dynarr); | |
1887 | |
1888 /* Here we optimize in the case where the coding system does no | |
1889 conversion. However, we don't want to optimize in case the source | |
1890 or sink is an lstream, since writing to an lstream can cause a | |
1891 garbage collection, and this could be problematic if the source | |
1892 is a lisp string. */ | |
1893 if (source_type != DFC_TYPE_LISP_LSTREAM && | |
1894 sink_type != DFC_TYPE_LISP_LSTREAM && | |
1895 coding_system_is_binary (coding_system)) | |
1896 { | |
1897 const Bufbyte *ptr; | |
1898 Bytecount len; | |
1899 | |
1900 if (source_type == DFC_TYPE_LISP_STRING) | |
1901 { | |
1902 ptr = XSTRING_DATA (source->lisp_object); | |
1903 len = XSTRING_LENGTH (source->lisp_object); | |
1904 } | |
1905 else | |
1906 { | |
1907 ptr = (Bufbyte *) source->data.ptr; | |
1908 len = source->data.len; | |
1909 } | |
1910 | |
1911 #ifdef MULE | |
1912 { | |
1913 const Bufbyte *end; | |
1914 for (end = ptr + len; ptr < end;) | |
1915 { | |
1916 Bufbyte c = | |
1917 (BYTE_ASCII_P (*ptr)) ? *ptr : | |
1918 (*ptr == LEADING_BYTE_CONTROL_1) ? (*(ptr+1) - 0x20) : | |
1919 (*ptr == LEADING_BYTE_LATIN_ISO8859_1) ? (*(ptr+1)) : | |
1920 '~'; | |
1921 | |
1922 Dynarr_add (conversion_out_dynarr, (Extbyte) c); | |
1923 INC_CHARPTR (ptr); | |
1924 } | |
1925 bufpos_checking_assert (ptr == end); | |
1926 } | |
1927 #else | |
1928 Dynarr_add_many (conversion_out_dynarr, ptr, len); | |
1929 #endif | |
1930 | |
1931 } | |
1932 else | |
1933 { | |
1934 Lisp_Object streams_to_delete[3]; | |
1935 int delete_count = 0; | |
1936 Lisp_Object instream, outstream; | |
1937 Lstream *reader, *writer; | |
1938 struct gcpro gcpro1, gcpro2; | |
1939 | |
1940 if (source_type == DFC_TYPE_LISP_LSTREAM) | |
1941 instream = source->lisp_object; | |
1942 else if (source_type == DFC_TYPE_DATA) | |
1943 streams_to_delete[delete_count++] = instream = | |
1944 make_fixed_buffer_input_stream (source->data.ptr, source->data.len); | |
1945 else | |
1946 { | |
1947 type_checking_assert (source_type == DFC_TYPE_LISP_STRING); | |
1948 streams_to_delete[delete_count++] = instream = | |
1949 make_lisp_string_input_stream (source->lisp_object, 0, -1); | |
1950 } | |
1951 | |
1952 if (sink_type == DFC_TYPE_LISP_LSTREAM) | |
1953 outstream = sink->lisp_object; | |
1954 else | |
1955 { | |
1956 type_checking_assert (sink_type == DFC_TYPE_DATA); | |
1957 streams_to_delete[delete_count++] = outstream = | |
1958 make_dynarr_output_stream | |
1959 ((unsigned_char_dynarr *) conversion_out_dynarr); | |
1960 } | |
1961 | |
1962 #ifdef FILE_CODING | |
1963 streams_to_delete[delete_count++] = outstream = | |
1964 make_encoding_output_stream (XLSTREAM (outstream), coding_system); | |
1965 #endif | |
1966 | |
1967 reader = XLSTREAM (instream); | |
1968 writer = XLSTREAM (outstream); | |
1969 /* decoding_stream will gc-protect outstream */ | |
1970 GCPRO2 (instream, outstream); | |
1971 | |
1972 while (1) | |
1973 { | |
1974 ssize_t size_in_bytes; | |
1975 char tempbuf[1024]; /* some random amount */ | |
1976 | |
1977 size_in_bytes = Lstream_read (reader, tempbuf, sizeof (tempbuf)); | |
1978 | |
1979 if (size_in_bytes == 0) | |
1980 break; | |
1981 else if (size_in_bytes < 0) | |
1982 error ("Error converting to external format"); | |
1983 | |
1984 size_in_bytes = Lstream_write (writer, tempbuf, size_in_bytes); | |
1985 | |
1986 if (size_in_bytes <= 0) | |
1987 error ("Error converting to external format"); | |
1988 } | |
1989 | |
1990 /* Closing writer will close any stream at the other end of writer. */ | |
1991 Lstream_close (writer); | |
1992 Lstream_close (reader); | |
1993 UNGCPRO; | |
1994 | |
1995 /* The idea is that this function will create no garbage. */ | |
1996 while (delete_count) | |
1997 Lstream_delete (XLSTREAM (streams_to_delete [--delete_count])); | |
1998 } | |
1999 | |
2000 unbind_to (count, Qnil); | |
2001 | |
2002 if (sink_type != DFC_TYPE_LISP_LSTREAM) | |
2003 { | |
2004 sink->data.len = Dynarr_length (conversion_out_dynarr); | |
2005 Dynarr_add (conversion_out_dynarr, 0); | |
2006 sink->data.ptr = Dynarr_atp (conversion_out_dynarr, 0); | |
2007 } | |
2008 } | |
2009 | |
2010 void | |
2011 dfc_convert_to_internal_format (dfc_conversion_type source_type, | |
2012 dfc_conversion_data *source, | |
2013 #ifdef FILE_CODING | |
2014 Lisp_Object coding_system, | |
2015 #endif | |
2016 dfc_conversion_type sink_type, | |
2017 dfc_conversion_data *sink) | |
2018 { | |
2019 int count = specpdl_depth (); | |
2020 | |
2021 type_checking_assert | |
2022 ((source_type == DFC_TYPE_DATA || | |
2023 source_type == DFC_TYPE_LISP_LSTREAM) | |
2024 && | |
2025 (sink_type == DFC_TYPE_DATA || | |
2026 sink_type == DFC_TYPE_LISP_LSTREAM)); | |
2027 | |
2028 if (dfc_convert_to_internal_format_in_use != 0) | |
2029 error ("Can't call a conversion function from a conversion function"); | |
2030 else | |
2031 dfc_convert_to_internal_format_in_use = 1; | |
2032 | |
2033 record_unwind_protect (dfc_convert_to_internal_format_reset_in_use, | |
2034 Qzero); | |
2035 | |
2036 #ifdef FILE_CODING | |
2037 coding_system = Fget_coding_system (coding_system); | |
2038 #endif | |
2039 | |
2040 Dynarr_reset (conversion_in_dynarr); | |
2041 | |
2042 if (source_type != DFC_TYPE_LISP_LSTREAM && | |
2043 sink_type != DFC_TYPE_LISP_LSTREAM && | |
2044 coding_system_is_binary (coding_system)) | |
2045 { | |
2046 #ifdef MULE | |
2047 const Bufbyte *ptr = (const Bufbyte *) source->data.ptr; | |
2048 Bytecount len = source->data.len; | |
2049 const Bufbyte *end = ptr + len; | |
2050 | |
2051 for (; ptr < end; ptr++) | |
2052 { | |
2053 Extbyte c = *ptr; | |
2054 | |
2055 if (BYTE_ASCII_P (c)) | |
2056 Dynarr_add (conversion_in_dynarr, c); | |
2057 else if (BYTE_C1_P (c)) | |
2058 { | |
2059 Dynarr_add (conversion_in_dynarr, LEADING_BYTE_CONTROL_1); | |
2060 Dynarr_add (conversion_in_dynarr, c + 0x20); | |
2061 } | |
2062 else | |
2063 { | |
2064 Dynarr_add (conversion_in_dynarr, LEADING_BYTE_LATIN_ISO8859_1); | |
2065 Dynarr_add (conversion_in_dynarr, c); | |
2066 } | |
2067 } | |
2068 #else | |
2069 Dynarr_add_many (conversion_in_dynarr, source->data.ptr, source->data.len); | |
2070 #endif | |
2071 } | |
2072 else | |
2073 { | |
2074 Lisp_Object streams_to_delete[3]; | |
2075 int delete_count = 0; | |
2076 Lisp_Object instream, outstream; | |
2077 Lstream *reader, *writer; | |
2078 struct gcpro gcpro1, gcpro2; | |
2079 | |
2080 if (source_type == DFC_TYPE_LISP_LSTREAM) | |
2081 instream = source->lisp_object; | |
2082 else | |
2083 { | |
2084 type_checking_assert (source_type == DFC_TYPE_DATA); | |
2085 streams_to_delete[delete_count++] = instream = | |
2086 make_fixed_buffer_input_stream (source->data.ptr, source->data.len); | |
2087 } | |
2088 | |
2089 if (sink_type == DFC_TYPE_LISP_LSTREAM) | |
2090 outstream = sink->lisp_object; | |
2091 else | |
2092 { | |
2093 type_checking_assert (sink_type == DFC_TYPE_DATA); | |
2094 streams_to_delete[delete_count++] = outstream = | |
2095 make_dynarr_output_stream | |
2096 ((unsigned_char_dynarr *) conversion_in_dynarr); | |
2097 } | |
2098 | |
2099 #ifdef FILE_CODING | |
2100 streams_to_delete[delete_count++] = outstream = | |
2101 make_decoding_output_stream (XLSTREAM (outstream), coding_system); | |
2102 #endif | |
2103 | |
2104 reader = XLSTREAM (instream); | |
2105 writer = XLSTREAM (outstream); | |
2106 /* outstream will gc-protect its sink stream, if necessary */ | |
2107 GCPRO2 (instream, outstream); | |
2108 | |
2109 while (1) | |
2110 { | |
2111 ssize_t size_in_bytes; | |
2112 char tempbuf[1024]; /* some random amount */ | |
2113 | |
2114 size_in_bytes = Lstream_read (reader, tempbuf, sizeof (tempbuf)); | |
2115 | |
2116 if (size_in_bytes == 0) | |
2117 break; | |
2118 else if (size_in_bytes < 0) | |
2119 error ("Error converting to internal format"); | |
2120 | |
2121 size_in_bytes = Lstream_write (writer, tempbuf, size_in_bytes); | |
2122 | |
2123 if (size_in_bytes <= 0) | |
2124 error ("Error converting to internal format"); | |
2125 } | |
2126 | |
2127 /* Closing writer will close any stream at the other end of writer. */ | |
2128 Lstream_close (writer); | |
2129 Lstream_close (reader); | |
2130 UNGCPRO; | |
2131 | |
2132 /* The idea is that this function will create no garbage. */ | |
2133 while (delete_count) | |
2134 Lstream_delete (XLSTREAM (streams_to_delete [--delete_count])); | |
2135 } | |
2136 | |
2137 unbind_to (count, Qnil); | |
2138 | |
2139 if (sink_type != DFC_TYPE_LISP_LSTREAM) | |
2140 { | |
2141 sink->data.len = Dynarr_length (conversion_in_dynarr); | |
2142 Dynarr_add (conversion_in_dynarr, 0); /* remember to zero-terminate! */ | |
2143 sink->data.ptr = Dynarr_atp (conversion_in_dynarr, 0); | |
2144 } | |
2145 } | |
2146 | |
2147 | |
1801 void | 2148 void |
1802 syms_of_buffer (void) | 2149 syms_of_buffer (void) |
1803 { | 2150 { |
1804 defsymbol (&Qbuffer_live_p, "buffer-live-p"); | 2151 defsymbol (&Qbuffer_live_p, "buffer-live-p"); |
1805 defsymbol (&Qbuffer_or_string_p, "buffer-or-string-p"); | 2152 defsymbol (&Qbuffer_or_string_p, "buffer-or-string-p"); |
1806 defsymbol (&Qmode_class, "mode-class"); | 2153 defsymbol (&Qmode_class, "mode-class"); |
1807 defsymbol (&Qrename_auto_save_file, "rename-auto-save-file"); | 2154 defsymbol (&Qrename_auto_save_file, "rename-auto-save-file"); |
1808 defsymbol (&Qkill_buffer_hook, "kill-buffer-hook"); | 2155 defsymbol (&Qkill_buffer_hook, "kill-buffer-hook"); |
2156 defsymbol (&Qrecord_buffer_hook, "record-buffer-hook"); | |
1809 defsymbol (&Qpermanent_local, "permanent-local"); | 2157 defsymbol (&Qpermanent_local, "permanent-local"); |
1810 | 2158 |
1811 defsymbol (&Qfirst_change_hook, "first-change-hook"); | 2159 defsymbol (&Qfirst_change_hook, "first-change-hook"); |
1812 defsymbol (&Qbefore_change_functions, "before-change-functions"); | 2160 defsymbol (&Qbefore_change_functions, "before-change-functions"); |
1813 defsymbol (&Qafter_change_functions, "after-change-functions"); | 2161 defsymbol (&Qafter_change_functions, "after-change-functions"); |
1814 | 2162 |
1815 /* #### Obsolete, for compatibility */ | 2163 /* #### Obsolete, for compatibility */ |
1816 defsymbol (&Qbefore_change_function, "before-change-function"); | 2164 defsymbol (&Qbefore_change_function, "before-change-function"); |
1817 defsymbol (&Qafter_change_function, "after-change-function"); | 2165 defsymbol (&Qafter_change_function, "after-change-function"); |
1818 | 2166 |
1819 defsymbol (&Qbuffer_file_name, "buffer-file-name"); | |
1820 defsymbol (&Qbuffer_undo_list, "buffer-undo-list"); | |
1821 defsymbol (&Qdefault_directory, "default-directory"); | 2167 defsymbol (&Qdefault_directory, "default-directory"); |
1822 | 2168 |
1823 defsymbol (&Qget_file_buffer, "get-file-buffer"); | 2169 defsymbol (&Qget_file_buffer, "get-file-buffer"); |
1824 defsymbol (&Qchange_major_mode_hook, "change-major-mode-hook"); | 2170 defsymbol (&Qchange_major_mode_hook, "change-major-mode-hook"); |
1825 | 2171 |
1868 | 2214 |
1869 deferror (&Qprotected_field, "protected-field", | 2215 deferror (&Qprotected_field, "protected-field", |
1870 "Attempt to modify a protected field", Qerror); | 2216 "Attempt to modify a protected field", Qerror); |
1871 } | 2217 } |
1872 | 2218 |
2219 void | |
2220 reinit_vars_of_buffer (void) | |
2221 { | |
2222 conversion_in_dynarr = Dynarr_new (Bufbyte); | |
2223 conversion_out_dynarr = Dynarr_new (Extbyte); | |
2224 | |
2225 staticpro_nodump (&Vbuffer_alist); | |
2226 Vbuffer_alist = Qnil; | |
2227 current_buffer = 0; | |
2228 } | |
2229 | |
1873 /* initialize the buffer routines */ | 2230 /* initialize the buffer routines */ |
1874 void | 2231 void |
1875 vars_of_buffer (void) | 2232 vars_of_buffer (void) |
1876 { | 2233 { |
1877 /* This function can GC */ | 2234 /* This function can GC */ |
2235 reinit_vars_of_buffer (); | |
2236 | |
1878 staticpro (&QSFundamental); | 2237 staticpro (&QSFundamental); |
1879 staticpro (&QSscratch); | 2238 staticpro (&QSscratch); |
1880 staticpro (&Vbuffer_alist); | 2239 |
1881 | 2240 QSFundamental = build_string ("Fundamental"); |
1882 QSFundamental = Fpurecopy (build_string ("Fundamental")); | 2241 QSscratch = build_string (DEFER_GETTEXT ("*scratch*")); |
1883 QSscratch = Fpurecopy (build_string (DEFER_GETTEXT ("*scratch*"))); | |
1884 | |
1885 Vbuffer_alist = Qnil; | |
1886 current_buffer = 0; | |
1887 | 2242 |
1888 DEFVAR_LISP ("change-major-mode-hook", &Vchange_major_mode_hook /* | 2243 DEFVAR_LISP ("change-major-mode-hook", &Vchange_major_mode_hook /* |
1889 List of hooks to be run before killing local variables in a buffer. | 2244 List of hooks to be run before killing local variables in a buffer. |
1890 This should be used by any mode that temporarily alters the contents or | 2245 This should be used by any mode that temporarily alters the contents or |
1891 the read-only state of the buffer. See also `kill-all-local-variables'. | 2246 the read-only state of the buffer. See also `kill-all-local-variables'. |
2021 | 2376 |
2022 /* Declaring this stuff as const produces 'Cannot reinitialize' messages | 2377 /* Declaring this stuff as const produces 'Cannot reinitialize' messages |
2023 from SunPro C's fix-and-continue feature (a way neato feature that | 2378 from SunPro C's fix-and-continue feature (a way neato feature that |
2024 makes debugging unbelievably more bearable) */ | 2379 makes debugging unbelievably more bearable) */ |
2025 #define DEFVAR_BUFFER_LOCAL_1(lname, field_name, forward_type, magicfun) do { \ | 2380 #define DEFVAR_BUFFER_LOCAL_1(lname, field_name, forward_type, magicfun) do { \ |
2026 static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C \ | 2381 static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C = \ |
2027 = { { { symbol_value_forward_lheader_initializer, \ | 2382 { /* struct symbol_value_forward */ \ |
2028 (struct lcrecord_header *) &(buffer_local_flags.field_name), 69 }, \ | 2383 { /* struct symbol_value_magic */ \ |
2029 forward_type }, magicfun }; \ | 2384 { /* struct lcrecord_header */ \ |
2385 { /* struct lrecord_header */ \ | |
2386 1, /* type - index into lrecord_implementations_table */ \ | |
2387 0, /* mark bit */ \ | |
2388 0, /* c_readonly bit */ \ | |
2389 0 /* lisp_readonly bit */ \ | |
2390 }, \ | |
2391 0, /* next */ \ | |
2392 0, /* uid */ \ | |
2393 0 /* free */ \ | |
2394 }, \ | |
2395 &(buffer_local_flags.field_name), \ | |
2396 forward_type \ | |
2397 }, \ | |
2398 magicfun \ | |
2399 }; \ | |
2400 \ | |
2030 { \ | 2401 { \ |
2031 int offset = ((char *)symbol_value_forward_forward (&I_hate_C) - \ | 2402 int offset = ((char *)symbol_value_forward_forward (&I_hate_C) - \ |
2032 (char *)&buffer_local_flags); \ | 2403 (char *)&buffer_local_flags); \ |
2033 defvar_magic (lname, &I_hate_C); \ | 2404 defvar_magic (lname, &I_hate_C); \ |
2034 \ | 2405 \ |
2061 | 2432 |
2062 b->extent_info = Qnil; | 2433 b->extent_info = Qnil; |
2063 b->indirect_children = Qnil; | 2434 b->indirect_children = Qnil; |
2064 b->own_text.line_number_cache = Qnil; | 2435 b->own_text.line_number_cache = Qnil; |
2065 | 2436 |
2066 #define MARKED_SLOT(x) b->x = (zap); | 2437 #define MARKED_SLOT(x) b->x = zap |
2067 #include "bufslots.h" | 2438 #include "bufslots.h" |
2068 #undef MARKED_SLOT | 2439 #undef MARKED_SLOT |
2069 } | 2440 } |
2070 | 2441 |
2071 void | 2442 static void |
2072 complex_vars_of_buffer (void) | 2443 common_init_complex_vars_of_buffer (void) |
2073 { | 2444 { |
2074 /* Make sure all markable slots in buffer_defaults | 2445 /* Make sure all markable slots in buffer_defaults |
2075 are initialized reasonably, so mark_buffer won't choke. */ | 2446 are initialized reasonably, so mark_buffer won't choke. */ |
2076 struct buffer *defs = alloc_lcrecord_type (struct buffer, lrecord_buffer); | 2447 struct buffer *defs = alloc_lcrecord_type (struct buffer, &lrecord_buffer); |
2077 struct buffer *syms = alloc_lcrecord_type (struct buffer, lrecord_buffer); | 2448 struct buffer *syms = alloc_lcrecord_type (struct buffer, &lrecord_buffer); |
2078 | 2449 |
2079 staticpro (&Vbuffer_defaults); | 2450 staticpro_nodump (&Vbuffer_defaults); |
2080 staticpro (&Vbuffer_local_symbols); | 2451 staticpro_nodump (&Vbuffer_local_symbols); |
2081 XSETBUFFER (Vbuffer_defaults, defs); | 2452 XSETBUFFER (Vbuffer_defaults, defs); |
2082 XSETBUFFER (Vbuffer_local_symbols, syms); | 2453 XSETBUFFER (Vbuffer_local_symbols, syms); |
2083 | 2454 |
2084 nuke_all_buffer_slots (syms, Qnil); | 2455 nuke_all_buffer_slots (syms, Qnil); |
2085 nuke_all_buffer_slots (defs, Qnil); | 2456 nuke_all_buffer_slots (defs, Qnil); |
2191 #endif | 2562 #endif |
2192 #ifdef FILE_CODING | 2563 #ifdef FILE_CODING |
2193 buffer_local_flags.buffer_file_coding_system = make_int (1<<14); | 2564 buffer_local_flags.buffer_file_coding_system = make_int (1<<14); |
2194 #endif | 2565 #endif |
2195 | 2566 |
2196 /* #### Warning: 1<<28 is the largest number currently allowable | 2567 /* #### Warning: 1<<31 is the largest number currently allowable |
2197 due to the XINT() handling of this value. With some | 2568 due to the XINT() handling of this value. With some |
2198 rearrangement you can get 3 more bits. */ | 2569 rearrangement you can get 3 more bits. */ |
2199 } | 2570 } |
2571 } | |
2572 | |
2573 #define BUFFER_SLOTS_SIZE (offsetof (struct buffer, BUFFER_SLOTS_LAST_NAME) - offsetof (struct buffer, BUFFER_SLOTS_FIRST_NAME) + sizeof (Lisp_Object)) | |
2574 #define BUFFER_SLOTS_COUNT (BUFFER_SLOTS_SIZE / sizeof (Lisp_Object)) | |
2575 | |
2576 void | |
2577 reinit_complex_vars_of_buffer (void) | |
2578 { | |
2579 struct buffer *defs, *syms; | |
2580 | |
2581 common_init_complex_vars_of_buffer (); | |
2582 | |
2583 defs = XBUFFER (Vbuffer_defaults); | |
2584 syms = XBUFFER (Vbuffer_local_symbols); | |
2585 memcpy (&defs->BUFFER_SLOTS_FIRST_NAME, | |
2586 buffer_defaults_saved_slots, | |
2587 BUFFER_SLOTS_SIZE); | |
2588 memcpy (&syms->BUFFER_SLOTS_FIRST_NAME, | |
2589 buffer_local_symbols_saved_slots, | |
2590 BUFFER_SLOTS_SIZE); | |
2591 } | |
2592 | |
2593 | |
2594 static const struct lrecord_description buffer_slots_description_1[] = { | |
2595 { XD_LISP_OBJECT_ARRAY, 0, BUFFER_SLOTS_COUNT }, | |
2596 { XD_END } | |
2597 }; | |
2598 | |
2599 static const struct struct_description buffer_slots_description = { | |
2600 BUFFER_SLOTS_SIZE, | |
2601 buffer_slots_description_1 | |
2602 }; | |
2603 | |
2604 void | |
2605 complex_vars_of_buffer (void) | |
2606 { | |
2607 struct buffer *defs, *syms; | |
2608 | |
2609 common_init_complex_vars_of_buffer (); | |
2610 | |
2611 defs = XBUFFER (Vbuffer_defaults); | |
2612 syms = XBUFFER (Vbuffer_local_symbols); | |
2613 buffer_defaults_saved_slots = &defs->BUFFER_SLOTS_FIRST_NAME; | |
2614 buffer_local_symbols_saved_slots = &syms->BUFFER_SLOTS_FIRST_NAME; | |
2615 dumpstruct (&buffer_defaults_saved_slots, &buffer_slots_description); | |
2616 dumpstruct (&buffer_local_symbols_saved_slots, &buffer_slots_description); | |
2200 | 2617 |
2201 DEFVAR_BUFFER_DEFAULTS ("default-modeline-format", modeline_format /* | 2618 DEFVAR_BUFFER_DEFAULTS ("default-modeline-format", modeline_format /* |
2202 Default value of `modeline-format' for buffers that don't override it. | 2619 Default value of `modeline-format' for buffers that don't override it. |
2203 This is the same as (default-value 'modeline-format). | 2620 This is the same as (default-value 'modeline-format). |
2204 */ ); | 2621 */ ); |
2688 } | 3105 } |
2689 } | 3106 } |
2690 | 3107 |
2691 /* Is PWD another name for `.' ? */ | 3108 /* Is PWD another name for `.' ? */ |
2692 static int | 3109 static int |
2693 directory_is_current_directory (char *pwd) | 3110 directory_is_current_directory (Extbyte *pwd) |
2694 { | 3111 { |
2695 Bufbyte *pwd_internal; | 3112 Bufbyte *pwd_internal; |
3113 Bytecount pwd_internal_len; | |
2696 struct stat dotstat, pwdstat; | 3114 struct stat dotstat, pwdstat; |
2697 | 3115 |
2698 GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (pwd, pwd_internal); | 3116 TO_INTERNAL_FORMAT (DATA, (pwd, strlen ((char *)pwd) + 1), |
3117 ALLOCA, (pwd_internal, pwd_internal_len), | |
3118 Qfile_name); | |
2699 | 3119 |
2700 return (IS_DIRECTORY_SEP (*pwd_internal) | 3120 return (IS_DIRECTORY_SEP (*pwd_internal) |
2701 && stat ((char *) pwd_internal, &pwdstat) == 0 | 3121 && stat ((char *) pwd_internal, &pwdstat) == 0 |
2702 && stat (".", &dotstat) == 0 | 3122 && stat (".", &dotstat) == 0 |
2703 && dotstat.st_ino == pwdstat.st_ino | 3123 && dotstat.st_ino == pwdstat.st_ino |
2704 && dotstat.st_dev == pwdstat.st_dev | 3124 && dotstat.st_dev == pwdstat.st_dev |
2705 && (int) strlen ((char *) pwd_internal) < MAXPATHLEN); | 3125 && pwd_internal_len < MAXPATHLEN); |
2706 } | 3126 } |
2707 | 3127 |
2708 void | 3128 void |
2709 init_initial_directory (void) | 3129 init_initial_directory (void) |
2710 { | 3130 { |
2711 /* This function can GC */ | 3131 /* This function can GC */ |
2712 | 3132 |
2713 char *pwd; | 3133 Extbyte *pwd; |
2714 | 3134 |
2715 initial_directory[0] = 0; | 3135 initial_directory[0] = 0; |
2716 | 3136 |
2717 /* If PWD is accurate, use it instead of calling getcwd. This is faster | 3137 /* If PWD is accurate, use it instead of calling getcwd. This is faster |
2718 when PWD is right, and may avoid a fatal error. */ | 3138 when PWD is right, and may avoid a fatal error. */ |
2719 if ((pwd = getenv ("PWD")) != NULL | 3139 if ((pwd = (Extbyte *) getenv ("PWD")) != NULL |
2720 && directory_is_current_directory (pwd)) | 3140 && directory_is_current_directory (pwd)) |
2721 strcpy (initial_directory, pwd); | 3141 strcpy (initial_directory, (char *) pwd); |
2722 else if (getcwd (initial_directory, MAXPATHLEN) == NULL) | 3142 else if (getcwd (initial_directory, MAXPATHLEN) == NULL) |
2723 fatal ("`getcwd' failed: %s\n", strerror (errno)); | 3143 fatal ("`getcwd' failed: %s\n", strerror (errno)); |
2724 | 3144 |
2725 /* Make sure pwd is DIRECTORY_SEP-terminated. | 3145 /* Make sure pwd is DIRECTORY_SEP-terminated. |
2726 Maybe this should really use some standard subroutine | 3146 Maybe this should really use some standard subroutine |
2754 /* This function can GC */ | 3174 /* This function can GC */ |
2755 | 3175 |
2756 Fset_buffer (Fget_buffer_create (QSscratch)); | 3176 Fset_buffer (Fget_buffer_create (QSscratch)); |
2757 | 3177 |
2758 current_buffer->directory = | 3178 current_buffer->directory = |
2759 build_ext_string (initial_directory, FORMAT_FILENAME); | 3179 build_ext_string (initial_directory, Qfile_name); |
2760 | 3180 |
2761 #if 0 /* FSFmacs */ | 3181 #if 0 /* FSFmacs */ |
2762 /* #### is this correct? */ | 3182 /* #### is this correct? */ |
2763 temp = get_minibuffer (0); | 3183 temp = get_minibuffer (0); |
2764 XBUFFER (temp)->directory = current_buffer->directory; | 3184 XBUFFER (temp)->directory = current_buffer->directory; |