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;