Mercurial > hg > xemacs-beta
comparison src/buffer.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | de805c49cfc1 |
children | 41dbb7a9d5f2 |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
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 | |
80 #include "frame.h" | 77 #include "frame.h" |
81 #include "insdel.h" | 78 #include "insdel.h" |
82 #include "lstream.h" | |
83 #include "process.h" /* for kill_buffer_processes */ | 79 #include "process.h" /* for kill_buffer_processes */ |
84 #ifdef REGION_CACHE_NEEDS_WORK | 80 #ifdef REGION_CACHE_NEEDS_WORK |
85 #include "region-cache.h" | 81 #include "region-cache.h" |
86 #endif | 82 #endif |
87 #include "select.h" /* for select_notify_buffer_kill */ | |
88 #include "specifier.h" | 83 #include "specifier.h" |
89 #include "syntax.h" | 84 #include "syntax.h" |
90 #include "sysdep.h" /* for getwd */ | 85 #include "sysdep.h" /* for getwd */ |
91 #include "window.h" | 86 #include "window.h" |
92 | 87 |
99 The default value occupies the same slot in this structure | 94 The default value occupies the same slot in this structure |
100 as an individual buffer's value occupies in that buffer. | 95 as an individual buffer's value occupies in that buffer. |
101 Setting the default value also goes through the alist of buffers | 96 Setting the default value also goes through the alist of buffers |
102 and stores into each buffer that does not say it has a local value. */ | 97 and stores into each buffer that does not say it has a local value. */ |
103 Lisp_Object Vbuffer_defaults; | 98 Lisp_Object Vbuffer_defaults; |
104 static void *buffer_defaults_saved_slots; | |
105 | 99 |
106 /* This structure marks which slots in a buffer have corresponding | 100 /* This structure marks which slots in a buffer have corresponding |
107 default values in Vbuffer_defaults. | 101 default values in Vbuffer_defaults. |
108 Each such slot has a nonzero value in this structure. | 102 Each such slot has a nonzero value in this structure. |
109 The value has only one nonzero bit. | 103 The value has only one nonzero bit. |
137 char initial_directory[MAXPATHLEN+1]; | 131 char initial_directory[MAXPATHLEN+1]; |
138 | 132 |
139 /* This structure holds the names of symbols whose values may be | 133 /* This structure holds the names of symbols whose values may be |
140 buffer-local. It is indexed and accessed in the same way as the above. */ | 134 buffer-local. It is indexed and accessed in the same way as the above. */ |
141 static Lisp_Object Vbuffer_local_symbols; | 135 static Lisp_Object Vbuffer_local_symbols; |
142 static void *buffer_local_symbols_saved_slots; | |
143 | 136 |
144 /* Alist of all buffer names vs the buffers. */ | 137 /* Alist of all buffer names vs the buffers. */ |
145 /* This used to be a variable, but is no longer, | 138 /* This used to be a variable, but is no longer, |
146 to prevent lossage due to user rplac'ing this alist or its elements. | 139 to prevent lossage due to user rplac'ing this alist or its elements. |
147 Note that there is a per-frame copy of this as well; the frame slot | 140 Note that there is a per-frame copy of this as well; the frame slot |
194 Lisp_Object QSFundamental; /* A string "Fundamental" */ | 187 Lisp_Object QSFundamental; /* A string "Fundamental" */ |
195 Lisp_Object QSscratch; /* "*scratch*" */ | 188 Lisp_Object QSscratch; /* "*scratch*" */ |
196 Lisp_Object Qdefault_directory; | 189 Lisp_Object Qdefault_directory; |
197 | 190 |
198 Lisp_Object Qkill_buffer_hook; | 191 Lisp_Object Qkill_buffer_hook; |
192 Lisp_Object Qbuffer_file_name, Qbuffer_undo_list; | |
199 | 193 |
200 Lisp_Object Qrename_auto_save_file; | 194 Lisp_Object Qrename_auto_save_file; |
201 | 195 |
202 Lisp_Object Qget_file_buffer; | 196 Lisp_Object Qget_file_buffer; |
203 Lisp_Object Qchange_major_mode_hook, Vchange_major_mode_hook; | 197 Lisp_Object Qchange_major_mode_hook, Vchange_major_mode_hook; |
224 XSETBUFFER (obj, buf); | 218 XSETBUFFER (obj, buf); |
225 return obj; | 219 return obj; |
226 } | 220 } |
227 | 221 |
228 static Lisp_Object | 222 static Lisp_Object |
229 mark_buffer (Lisp_Object obj) | 223 mark_buffer (Lisp_Object obj, void (*markobj) (Lisp_Object)) |
230 { | 224 { |
231 struct buffer *buf = XBUFFER (obj); | 225 struct buffer *buf = XBUFFER (obj); |
232 | 226 |
233 /* Truncate undo information. */ | 227 /* Truncate undo information. */ |
234 buf->undo_list = truncate_undo_list (buf->undo_list, | 228 buf->undo_list = truncate_undo_list (buf->undo_list, |
235 undo_threshold, | 229 undo_threshold, |
236 undo_high_threshold); | 230 undo_high_threshold); |
237 | 231 |
238 #define MARKED_SLOT(x) mark_object (buf->x) | 232 #define MARKED_SLOT(x) ((void) (markobj (buf->x))); |
239 #include "bufslots.h" | 233 #include "bufslots.h" |
240 #undef MARKED_SLOT | 234 #undef MARKED_SLOT |
241 | 235 |
242 mark_object (buf->extent_info); | 236 markobj (buf->extent_info); |
243 if (buf->text) | 237 if (buf->text) |
244 mark_object (buf->text->line_number_cache); | 238 markobj (buf->text->line_number_cache); |
245 | 239 |
246 /* Don't mark normally through the children slot. | 240 /* Don't mark normally through the children slot. |
247 (Actually, in this case, it doesn't matter.) */ | 241 (Actually, in this case, it doesn't matter.) */ |
248 if (! EQ (buf->indirect_children, Qnull_pointer)) | 242 if (! EQ (buf->indirect_children, Qnull_pointer)) |
249 mark_conses_in_list (buf->indirect_children); | 243 mark_conses_in_list (buf->indirect_children); |
280 | 274 |
281 /* We do not need a finalize method to handle a buffer's children list | 275 /* We do not need a finalize method to handle a buffer's children list |
282 because all buffers have `kill-buffer' applied to them before | 276 because all buffers have `kill-buffer' applied to them before |
283 they disappear, and the children removal happens then. */ | 277 they disappear, and the children removal happens then. */ |
284 DEFINE_LRECORD_IMPLEMENTATION ("buffer", buffer, | 278 DEFINE_LRECORD_IMPLEMENTATION ("buffer", buffer, |
285 mark_buffer, print_buffer, 0, 0, 0, 0, | 279 mark_buffer, print_buffer, 0, 0, 0, |
286 struct buffer); | 280 struct buffer); |
287 | 281 |
288 DEFUN ("bufferp", Fbufferp, 1, 1, 0, /* | 282 DEFUN ("bufferp", Fbufferp, 1, 1, 0, /* |
289 Return t if OBJECT is an editor buffer. | 283 Return t if OBJECT is an editor buffer. |
290 */ | 284 */ |
565 /* #### This really does not need to be called. We already | 559 /* #### This really does not need to be called. We already |
566 initialized the buffer-local variables in allocate_buffer(). | 560 initialized the buffer-local variables in allocate_buffer(). |
567 local_var_alist is set to Qnil at the same point, in | 561 local_var_alist is set to Qnil at the same point, in |
568 nuke_all_buffer_slots(). */ | 562 nuke_all_buffer_slots(). */ |
569 reset_buffer_local_variables (b, 1); | 563 reset_buffer_local_variables (b, 1); |
570 b->directory = current_buffer ? current_buffer->directory : Qnil; | 564 b->directory = ((current_buffer) ? current_buffer->directory : Qnil); |
571 | 565 |
572 b->last_window_start = 1; | 566 b->last_window_start = 1; |
573 | 567 |
574 b->name = name; | 568 b->name = name; |
575 if (string_byte (XSTRING (name), 0) != ' ') | 569 if (string_byte (XSTRING (name), 0) != ' ') |
1025 buf = Fcurrent_buffer (); | 1019 buf = Fcurrent_buffer (); |
1026 | 1020 |
1027 /* The aconses in the Vbuffer_alist are shared with frame->buffer_alist, | 1021 /* The aconses in the Vbuffer_alist are shared with frame->buffer_alist, |
1028 so this will change it in the per-frame ordering as well. */ | 1022 so this will change it in the per-frame ordering as well. */ |
1029 Fsetcar (Frassq (buf, Vbuffer_alist), newname); | 1023 Fsetcar (Frassq (buf, Vbuffer_alist), newname); |
1030 | |
1031 if (NILP (current_buffer->filename) | 1024 if (NILP (current_buffer->filename) |
1032 && !NILP (current_buffer->auto_save_file_name)) | 1025 && !NILP (current_buffer->auto_save_file_name)) |
1033 call0 (Qrename_auto_save_file); | 1026 call0 (Qrename_auto_save_file); |
1034 /* refetch since that last call may have done GC */ | 1027 /* refetch since that last call may have done GC */ |
1035 /* (hypothetical relocating GC) */ | 1028 /* (hypothetical relocating GC) */ |
1185 Lisp_Object killp; | 1178 Lisp_Object killp; |
1186 GCPRO1 (buf); | 1179 GCPRO1 (buf); |
1187 killp = call1 | 1180 killp = call1 |
1188 (Qyes_or_no_p, | 1181 (Qyes_or_no_p, |
1189 (emacs_doprnt_string_c | 1182 (emacs_doprnt_string_c |
1190 ((const Bufbyte *) GETTEXT ("Buffer %s modified; kill anyway? "), | 1183 ((CONST Bufbyte *) GETTEXT ("Buffer %s modified; kill anyway? "), |
1191 Qnil, -1, XSTRING_DATA (b->name)))); | 1184 Qnil, -1, XSTRING_DATA (b->name)))); |
1192 UNGCPRO; | 1185 UNGCPRO; |
1193 if (NILP (killp)) | 1186 if (NILP (killp)) |
1194 return Qnil; | 1187 return Qnil; |
1195 b = XBUFFER (buf); /* Hypothetical relocating GC. */ | 1188 b = XBUFFER (buf); /* Hypothetical relocating GC. */ |
1219 } | 1212 } |
1220 } | 1213 } |
1221 | 1214 |
1222 /* Then run the hooks. */ | 1215 /* Then run the hooks. */ |
1223 run_hook (Qkill_buffer_hook); | 1216 run_hook (Qkill_buffer_hook); |
1224 | 1217 #ifdef HAVE_X_WINDOWS |
1225 /* Inform the selection code that a buffer just got killed. | 1218 /* If an X selection was in this buffer, disown it. |
1226 We do this in C because (a) it's faster, and (b) it needs | 1219 We could have done this by simply adding this function to the |
1227 to access data internal to select.c that can't be seen from | 1220 kill-buffer-hook, but the user might mess that up. |
1228 Lisp (so the Lisp code would just call into C anyway. */ | 1221 */ |
1229 select_notify_buffer_kill (buf); | 1222 if (EQ (Vwindow_system, Qx)) |
1230 | 1223 call0 (intern ("xselect-kill-buffer-hook")); |
1224 /* #### generalize me! */ | |
1225 #endif /* HAVE_X_WINDOWS */ | |
1231 unbind_to (speccount, Qnil); | 1226 unbind_to (speccount, Qnil); |
1232 UNGCPRO; | 1227 UNGCPRO; |
1233 b = XBUFFER (buf); /* Hypothetical relocating GC. */ | 1228 b = XBUFFER (buf); /* Hypothetical relocating GC. */ |
1234 } | 1229 } |
1235 | 1230 |
1301 int speccount = specpdl_depth (); | 1296 int speccount = specpdl_depth (); |
1302 specbind (Qinhibit_quit, Qt); | 1297 specbind (Qinhibit_quit, Qt); |
1303 | 1298 |
1304 kill_buffer_processes (buf); | 1299 kill_buffer_processes (buf); |
1305 | 1300 |
1306 delete_from_buffer_alist (buf); | |
1307 | |
1308 /* #### This is a problem if this buffer is in a dedicated window. | 1301 /* #### This is a problem if this buffer is in a dedicated window. |
1309 Need to undedicate any windows of this buffer first (and delete them?) | 1302 Need to undedicate any windows of this buffer first (and delete them?) |
1310 */ | 1303 */ |
1311 Freplace_buffer_in_windows (buf); | 1304 Freplace_buffer_in_windows (buf); |
1305 | |
1306 delete_from_buffer_alist (buf); | |
1312 | 1307 |
1313 font_lock_buffer_was_killed (b); | 1308 font_lock_buffer_was_killed (b); |
1314 | 1309 |
1315 /* Delete any auto-save file, if we saved it in this session. */ | 1310 /* Delete any auto-save file, if we saved it in this session. */ |
1316 if (STRINGP (b->auto_save_file_name) | 1311 if (STRINGP (b->auto_save_file_name) |
1409 f->buffer_alist = XCDR (f->buffer_alist); | 1404 f->buffer_alist = XCDR (f->buffer_alist); |
1410 else | 1405 else |
1411 XCDR (prev) = XCDR (XCDR (prev)); | 1406 XCDR (prev) = XCDR (XCDR (prev)); |
1412 XCDR (lynk) = f->buffer_alist; | 1407 XCDR (lynk) = f->buffer_alist; |
1413 f->buffer_alist = lynk; | 1408 f->buffer_alist = lynk; |
1414 | |
1415 return Qnil; | 1409 return Qnil; |
1416 } | 1410 } |
1417 | 1411 |
1418 DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, 1, 1, 0, /* | 1412 DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, 1, 1, 0, /* |
1419 Set an appropriate major mode for BUFFER, according to `default-major-mode'. | 1413 Set an appropriate major mode for BUFFER, according to `default-major-mode'. |
1477 INVALIDATE_PIXEL_TO_GLYPH_CACHE; | 1471 INVALIDATE_PIXEL_TO_GLYPH_CACHE; |
1478 | 1472 |
1479 old_buf = current_buffer; | 1473 old_buf = current_buffer; |
1480 current_buffer = b; | 1474 current_buffer = b; |
1481 invalidate_current_column (); /* invalidate indentation cache */ | 1475 invalidate_current_column (); /* invalidate indentation cache */ |
1476 | |
1477 #ifdef HAVE_FEP | |
1478 if (!noninteractive && initialized) | |
1479 { | |
1480 extern Lisp_Object Ffep_force_on (), Ffep_force_off (), Ffep_get_mode (); | |
1481 | |
1482 old_buf->fep_mode = Ffep_get_mode (); | |
1483 | |
1484 if (!NILP (current_buffer->fep_mode)) | |
1485 Ffep_force_on (); | |
1486 else | |
1487 Ffep_force_off (); | |
1488 } | |
1489 #endif /* HAVE_FEP */ | |
1482 | 1490 |
1483 if (old_buf) | 1491 if (old_buf) |
1484 { | 1492 { |
1485 /* Put the undo list back in the base buffer, so that it appears | 1493 /* Put the undo list back in the base buffer, so that it appears |
1486 that an indirect buffer shares the undo list of its base. */ | 1494 that an indirect buffer shares the undo list of its base. */ |
1609 There it is the least likely candidate for `other-buffer' to return; | 1617 There it is the least likely candidate for `other-buffer' to return; |
1610 thus, the least likely buffer for \\[switch-to-buffer] to select by default. | 1618 thus, the least likely buffer for \\[switch-to-buffer] to select by default. |
1611 If BUFFER is nil or omitted, bury the current buffer. | 1619 If BUFFER is nil or omitted, bury the current buffer. |
1612 Also, if BUFFER is nil or omitted, remove the current buffer from the | 1620 Also, if BUFFER is nil or omitted, remove the current buffer from the |
1613 selected window if it is displayed there. | 1621 selected window if it is displayed there. |
1614 Because of this, you may need to specify (current-buffer) as | |
1615 BUFFER when calling from minibuffer. | |
1616 If BEFORE is non-nil, it specifies a buffer before which BUFFER | 1622 If BEFORE is non-nil, it specifies a buffer before which BUFFER |
1617 will be placed, instead of being placed at the end. | 1623 will be placed, instead of being placed at the end. |
1618 */ | 1624 */ |
1619 (buffer, before)) | 1625 (buffer, before)) |
1620 { | 1626 { |
1790 return Fnreverse (val); | 1796 return Fnreverse (val); |
1791 } | 1797 } |
1792 | 1798 |
1793 #endif /* MEMORY_USAGE_STATS */ | 1799 #endif /* MEMORY_USAGE_STATS */ |
1794 | 1800 |
1795 | |
1796 /************************************************************************/ | |
1797 /* Implement TO_EXTERNAL_FORMAT, TO_INTERNAL_FORMAT */ | |
1798 /************************************************************************/ | |
1799 | |
1800 /* This implementation should probably be elsewhere, but it can't be | |
1801 in file-coding.c since that file is only available if FILE_CODING | |
1802 is defined. */ | |
1803 #ifdef FILE_CODING | |
1804 static int | |
1805 coding_system_is_binary (Lisp_Object coding_system) | |
1806 { | |
1807 Lisp_Coding_System *cs = XCODING_SYSTEM (coding_system); | |
1808 return | |
1809 (CODING_SYSTEM_TYPE (cs) == CODESYS_NO_CONVERSION && | |
1810 CODING_SYSTEM_EOL_TYPE (cs) == EOL_LF && | |
1811 EQ (CODING_SYSTEM_POST_READ_CONVERSION (cs), Qnil) && | |
1812 EQ (CODING_SYSTEM_PRE_WRITE_CONVERSION (cs), Qnil)); | |
1813 } | |
1814 #else | |
1815 #define coding_system_is_binary(coding_system) 1 | |
1816 #endif | |
1817 | |
1818 typedef struct | |
1819 { | |
1820 Dynarr_declare (Bufbyte_dynarr *); | |
1821 } Bufbyte_dynarr_dynarr; | |
1822 | |
1823 typedef struct | |
1824 { | |
1825 Dynarr_declare (Extbyte_dynarr *); | |
1826 } Extbyte_dynarr_dynarr; | |
1827 | |
1828 static Extbyte_dynarr_dynarr *conversion_out_dynarr_list; | |
1829 static Bufbyte_dynarr_dynarr *conversion_in_dynarr_list; | |
1830 | |
1831 static int dfc_convert_to_external_format_in_use; | |
1832 static int dfc_convert_to_internal_format_in_use; | |
1833 | |
1834 static Lisp_Object | |
1835 dfc_convert_to_external_format_reset_in_use (Lisp_Object value) | |
1836 { | |
1837 dfc_convert_to_external_format_in_use = XINT (value); | |
1838 return Qnil; | |
1839 } | |
1840 | |
1841 static Lisp_Object | |
1842 dfc_convert_to_internal_format_reset_in_use (Lisp_Object value) | |
1843 { | |
1844 dfc_convert_to_internal_format_in_use = XINT (value); | |
1845 return Qnil; | |
1846 } | |
1847 | |
1848 void | |
1849 dfc_convert_to_external_format (dfc_conversion_type source_type, | |
1850 dfc_conversion_data *source, | |
1851 #ifdef FILE_CODING | |
1852 Lisp_Object coding_system, | |
1853 #endif | |
1854 dfc_conversion_type sink_type, | |
1855 dfc_conversion_data *sink) | |
1856 { | |
1857 int count = specpdl_depth (); | |
1858 Extbyte_dynarr *conversion_out_dynarr; | |
1859 | |
1860 type_checking_assert | |
1861 (((source_type == DFC_TYPE_DATA) || | |
1862 (source_type == DFC_TYPE_LISP_LSTREAM && LSTREAMP (source->lisp_object)) || | |
1863 (source_type == DFC_TYPE_LISP_STRING && STRINGP (source->lisp_object))) | |
1864 && | |
1865 ((sink_type == DFC_TYPE_DATA) || | |
1866 (sink_type == DFC_TYPE_LISP_LSTREAM && LSTREAMP (source->lisp_object)))); | |
1867 | |
1868 record_unwind_protect (dfc_convert_to_external_format_reset_in_use, | |
1869 make_int (dfc_convert_to_external_format_in_use)); | |
1870 if (Dynarr_length (conversion_out_dynarr_list) <= | |
1871 dfc_convert_to_external_format_in_use) | |
1872 Dynarr_add (conversion_out_dynarr_list, Dynarr_new (Extbyte)); | |
1873 conversion_out_dynarr = Dynarr_at (conversion_out_dynarr_list, | |
1874 dfc_convert_to_external_format_in_use); | |
1875 dfc_convert_to_external_format_in_use++; | |
1876 Dynarr_reset (conversion_out_dynarr); | |
1877 | |
1878 #ifdef FILE_CODING | |
1879 coding_system = Fget_coding_system (coding_system); | |
1880 #endif | |
1881 | |
1882 /* Here we optimize in the case where the coding system does no | |
1883 conversion. However, we don't want to optimize in case the source | |
1884 or sink is an lstream, since writing to an lstream can cause a | |
1885 garbage collection, and this could be problematic if the source | |
1886 is a lisp string. */ | |
1887 if (source_type != DFC_TYPE_LISP_LSTREAM && | |
1888 sink_type != DFC_TYPE_LISP_LSTREAM && | |
1889 coding_system_is_binary (coding_system)) | |
1890 { | |
1891 const Bufbyte *ptr; | |
1892 Bytecount len; | |
1893 | |
1894 if (source_type == DFC_TYPE_LISP_STRING) | |
1895 { | |
1896 ptr = XSTRING_DATA (source->lisp_object); | |
1897 len = XSTRING_LENGTH (source->lisp_object); | |
1898 } | |
1899 else | |
1900 { | |
1901 ptr = (Bufbyte *) source->data.ptr; | |
1902 len = source->data.len; | |
1903 } | |
1904 | |
1905 #ifdef MULE | |
1906 { | |
1907 const Bufbyte *end; | |
1908 for (end = ptr + len; ptr < end;) | |
1909 { | |
1910 Bufbyte c = | |
1911 (BYTE_ASCII_P (*ptr)) ? *ptr : | |
1912 (*ptr == LEADING_BYTE_CONTROL_1) ? (*(ptr+1) - 0x20) : | |
1913 (*ptr == LEADING_BYTE_LATIN_ISO8859_1) ? (*(ptr+1)) : | |
1914 '~'; | |
1915 | |
1916 Dynarr_add (conversion_out_dynarr, (Extbyte) c); | |
1917 INC_CHARPTR (ptr); | |
1918 } | |
1919 bufpos_checking_assert (ptr == end); | |
1920 } | |
1921 #else | |
1922 Dynarr_add_many (conversion_out_dynarr, ptr, len); | |
1923 #endif | |
1924 | |
1925 } | |
1926 else | |
1927 { | |
1928 Lisp_Object streams_to_delete[3]; | |
1929 int delete_count = 0; | |
1930 Lisp_Object instream, outstream; | |
1931 Lstream *reader, *writer; | |
1932 struct gcpro gcpro1, gcpro2; | |
1933 | |
1934 if (source_type == DFC_TYPE_LISP_LSTREAM) | |
1935 instream = source->lisp_object; | |
1936 else if (source_type == DFC_TYPE_DATA) | |
1937 streams_to_delete[delete_count++] = instream = | |
1938 make_fixed_buffer_input_stream (source->data.ptr, source->data.len); | |
1939 else | |
1940 { | |
1941 type_checking_assert (source_type == DFC_TYPE_LISP_STRING); | |
1942 streams_to_delete[delete_count++] = instream = | |
1943 make_lisp_string_input_stream (source->lisp_object, 0, -1); | |
1944 } | |
1945 | |
1946 if (sink_type == DFC_TYPE_LISP_LSTREAM) | |
1947 outstream = sink->lisp_object; | |
1948 else | |
1949 { | |
1950 type_checking_assert (sink_type == DFC_TYPE_DATA); | |
1951 streams_to_delete[delete_count++] = outstream = | |
1952 make_dynarr_output_stream | |
1953 ((unsigned_char_dynarr *) conversion_out_dynarr); | |
1954 } | |
1955 | |
1956 #ifdef FILE_CODING | |
1957 streams_to_delete[delete_count++] = outstream = | |
1958 make_encoding_output_stream (XLSTREAM (outstream), coding_system); | |
1959 #endif | |
1960 | |
1961 reader = XLSTREAM (instream); | |
1962 writer = XLSTREAM (outstream); | |
1963 /* decoding_stream will gc-protect outstream */ | |
1964 GCPRO2 (instream, outstream); | |
1965 | |
1966 while (1) | |
1967 { | |
1968 ssize_t size_in_bytes; | |
1969 char tempbuf[1024]; /* some random amount */ | |
1970 | |
1971 size_in_bytes = Lstream_read (reader, tempbuf, sizeof (tempbuf)); | |
1972 | |
1973 if (size_in_bytes == 0) | |
1974 break; | |
1975 else if (size_in_bytes < 0) | |
1976 error ("Error converting to external format"); | |
1977 | |
1978 size_in_bytes = Lstream_write (writer, tempbuf, size_in_bytes); | |
1979 | |
1980 if (size_in_bytes <= 0) | |
1981 error ("Error converting to external format"); | |
1982 } | |
1983 | |
1984 /* Closing writer will close any stream at the other end of writer. */ | |
1985 Lstream_close (writer); | |
1986 Lstream_close (reader); | |
1987 UNGCPRO; | |
1988 | |
1989 /* The idea is that this function will create no garbage. */ | |
1990 while (delete_count) | |
1991 Lstream_delete (XLSTREAM (streams_to_delete [--delete_count])); | |
1992 } | |
1993 | |
1994 unbind_to (count, Qnil); | |
1995 | |
1996 if (sink_type != DFC_TYPE_LISP_LSTREAM) | |
1997 { | |
1998 sink->data.len = Dynarr_length (conversion_out_dynarr); | |
1999 Dynarr_add (conversion_out_dynarr, 0); | |
2000 sink->data.ptr = Dynarr_atp (conversion_out_dynarr, 0); | |
2001 } | |
2002 } | |
2003 | |
2004 void | |
2005 dfc_convert_to_internal_format (dfc_conversion_type source_type, | |
2006 dfc_conversion_data *source, | |
2007 #ifdef FILE_CODING | |
2008 Lisp_Object coding_system, | |
2009 #endif | |
2010 dfc_conversion_type sink_type, | |
2011 dfc_conversion_data *sink) | |
2012 { | |
2013 int count = specpdl_depth (); | |
2014 Bufbyte_dynarr *conversion_in_dynarr; | |
2015 | |
2016 type_checking_assert | |
2017 ((source_type == DFC_TYPE_DATA || | |
2018 source_type == DFC_TYPE_LISP_LSTREAM) | |
2019 && | |
2020 (sink_type == DFC_TYPE_DATA || | |
2021 sink_type == DFC_TYPE_LISP_LSTREAM)); | |
2022 | |
2023 record_unwind_protect (dfc_convert_to_internal_format_reset_in_use, | |
2024 make_int (dfc_convert_to_internal_format_in_use)); | |
2025 if (Dynarr_length (conversion_in_dynarr_list) <= | |
2026 dfc_convert_to_internal_format_in_use) | |
2027 Dynarr_add (conversion_in_dynarr_list, Dynarr_new (Bufbyte)); | |
2028 conversion_in_dynarr = Dynarr_at (conversion_in_dynarr_list, | |
2029 dfc_convert_to_internal_format_in_use); | |
2030 dfc_convert_to_internal_format_in_use++; | |
2031 Dynarr_reset (conversion_in_dynarr); | |
2032 | |
2033 #ifdef FILE_CODING | |
2034 coding_system = Fget_coding_system (coding_system); | |
2035 #endif | |
2036 | |
2037 if (source_type != DFC_TYPE_LISP_LSTREAM && | |
2038 sink_type != DFC_TYPE_LISP_LSTREAM && | |
2039 coding_system_is_binary (coding_system)) | |
2040 { | |
2041 #ifdef MULE | |
2042 const Bufbyte *ptr = (const Bufbyte *) source->data.ptr; | |
2043 Bytecount len = source->data.len; | |
2044 const Bufbyte *end = ptr + len; | |
2045 | |
2046 for (; ptr < end; ptr++) | |
2047 { | |
2048 Extbyte c = *ptr; | |
2049 | |
2050 if (BYTE_ASCII_P (c)) | |
2051 Dynarr_add (conversion_in_dynarr, c); | |
2052 else if (BYTE_C1_P (c)) | |
2053 { | |
2054 Dynarr_add (conversion_in_dynarr, LEADING_BYTE_CONTROL_1); | |
2055 Dynarr_add (conversion_in_dynarr, c + 0x20); | |
2056 } | |
2057 else | |
2058 { | |
2059 Dynarr_add (conversion_in_dynarr, LEADING_BYTE_LATIN_ISO8859_1); | |
2060 Dynarr_add (conversion_in_dynarr, c); | |
2061 } | |
2062 } | |
2063 #else | |
2064 Dynarr_add_many (conversion_in_dynarr, source->data.ptr, source->data.len); | |
2065 #endif | |
2066 } | |
2067 else | |
2068 { | |
2069 Lisp_Object streams_to_delete[3]; | |
2070 int delete_count = 0; | |
2071 Lisp_Object instream, outstream; | |
2072 Lstream *reader, *writer; | |
2073 struct gcpro gcpro1, gcpro2; | |
2074 | |
2075 if (source_type == DFC_TYPE_LISP_LSTREAM) | |
2076 instream = source->lisp_object; | |
2077 else | |
2078 { | |
2079 type_checking_assert (source_type == DFC_TYPE_DATA); | |
2080 streams_to_delete[delete_count++] = instream = | |
2081 make_fixed_buffer_input_stream (source->data.ptr, source->data.len); | |
2082 } | |
2083 | |
2084 if (sink_type == DFC_TYPE_LISP_LSTREAM) | |
2085 outstream = sink->lisp_object; | |
2086 else | |
2087 { | |
2088 type_checking_assert (sink_type == DFC_TYPE_DATA); | |
2089 streams_to_delete[delete_count++] = outstream = | |
2090 make_dynarr_output_stream | |
2091 ((unsigned_char_dynarr *) conversion_in_dynarr); | |
2092 } | |
2093 | |
2094 #ifdef FILE_CODING | |
2095 streams_to_delete[delete_count++] = outstream = | |
2096 make_decoding_output_stream (XLSTREAM (outstream), coding_system); | |
2097 #endif | |
2098 | |
2099 reader = XLSTREAM (instream); | |
2100 writer = XLSTREAM (outstream); | |
2101 /* outstream will gc-protect its sink stream, if necessary */ | |
2102 GCPRO2 (instream, outstream); | |
2103 | |
2104 while (1) | |
2105 { | |
2106 ssize_t size_in_bytes; | |
2107 char tempbuf[1024]; /* some random amount */ | |
2108 | |
2109 size_in_bytes = Lstream_read (reader, tempbuf, sizeof (tempbuf)); | |
2110 | |
2111 if (size_in_bytes == 0) | |
2112 break; | |
2113 else if (size_in_bytes < 0) | |
2114 error ("Error converting to internal format"); | |
2115 | |
2116 size_in_bytes = Lstream_write (writer, tempbuf, size_in_bytes); | |
2117 | |
2118 if (size_in_bytes <= 0) | |
2119 error ("Error converting to internal format"); | |
2120 } | |
2121 | |
2122 /* Closing writer will close any stream at the other end of writer. */ | |
2123 Lstream_close (writer); | |
2124 Lstream_close (reader); | |
2125 UNGCPRO; | |
2126 | |
2127 /* The idea is that this function will create no garbage. */ | |
2128 while (delete_count) | |
2129 Lstream_delete (XLSTREAM (streams_to_delete [--delete_count])); | |
2130 } | |
2131 | |
2132 unbind_to (count, Qnil); | |
2133 | |
2134 if (sink_type != DFC_TYPE_LISP_LSTREAM) | |
2135 { | |
2136 sink->data.len = Dynarr_length (conversion_in_dynarr); | |
2137 Dynarr_add (conversion_in_dynarr, 0); /* remember to zero-terminate! */ | |
2138 sink->data.ptr = Dynarr_atp (conversion_in_dynarr, 0); | |
2139 } | |
2140 } | |
2141 | |
2142 | |
2143 void | 1801 void |
2144 syms_of_buffer (void) | 1802 syms_of_buffer (void) |
2145 { | 1803 { |
2146 INIT_LRECORD_IMPLEMENTATION (buffer); | |
2147 | |
2148 defsymbol (&Qbuffer_live_p, "buffer-live-p"); | 1804 defsymbol (&Qbuffer_live_p, "buffer-live-p"); |
2149 defsymbol (&Qbuffer_or_string_p, "buffer-or-string-p"); | 1805 defsymbol (&Qbuffer_or_string_p, "buffer-or-string-p"); |
2150 defsymbol (&Qmode_class, "mode-class"); | 1806 defsymbol (&Qmode_class, "mode-class"); |
2151 defsymbol (&Qrename_auto_save_file, "rename-auto-save-file"); | 1807 defsymbol (&Qrename_auto_save_file, "rename-auto-save-file"); |
2152 defsymbol (&Qkill_buffer_hook, "kill-buffer-hook"); | 1808 defsymbol (&Qkill_buffer_hook, "kill-buffer-hook"); |
2158 | 1814 |
2159 /* #### Obsolete, for compatibility */ | 1815 /* #### Obsolete, for compatibility */ |
2160 defsymbol (&Qbefore_change_function, "before-change-function"); | 1816 defsymbol (&Qbefore_change_function, "before-change-function"); |
2161 defsymbol (&Qafter_change_function, "after-change-function"); | 1817 defsymbol (&Qafter_change_function, "after-change-function"); |
2162 | 1818 |
1819 defsymbol (&Qbuffer_file_name, "buffer-file-name"); | |
1820 defsymbol (&Qbuffer_undo_list, "buffer-undo-list"); | |
2163 defsymbol (&Qdefault_directory, "default-directory"); | 1821 defsymbol (&Qdefault_directory, "default-directory"); |
2164 | 1822 |
2165 defsymbol (&Qget_file_buffer, "get-file-buffer"); | 1823 defsymbol (&Qget_file_buffer, "get-file-buffer"); |
2166 defsymbol (&Qchange_major_mode_hook, "change-major-mode-hook"); | 1824 defsymbol (&Qchange_major_mode_hook, "change-major-mode-hook"); |
2167 | 1825 |
2210 | 1868 |
2211 deferror (&Qprotected_field, "protected-field", | 1869 deferror (&Qprotected_field, "protected-field", |
2212 "Attempt to modify a protected field", Qerror); | 1870 "Attempt to modify a protected field", Qerror); |
2213 } | 1871 } |
2214 | 1872 |
2215 void | |
2216 reinit_vars_of_buffer (void) | |
2217 { | |
2218 conversion_in_dynarr_list = Dynarr_new2 (Bufbyte_dynarr_dynarr, | |
2219 Bufbyte_dynarr *); | |
2220 conversion_out_dynarr_list = Dynarr_new2 (Extbyte_dynarr_dynarr, | |
2221 Extbyte_dynarr *); | |
2222 | |
2223 staticpro_nodump (&Vbuffer_alist); | |
2224 Vbuffer_alist = Qnil; | |
2225 current_buffer = 0; | |
2226 } | |
2227 | |
2228 /* initialize the buffer routines */ | 1873 /* initialize the buffer routines */ |
2229 void | 1874 void |
2230 vars_of_buffer (void) | 1875 vars_of_buffer (void) |
2231 { | 1876 { |
2232 /* This function can GC */ | 1877 /* This function can GC */ |
2233 reinit_vars_of_buffer (); | |
2234 | |
2235 staticpro (&QSFundamental); | 1878 staticpro (&QSFundamental); |
2236 staticpro (&QSscratch); | 1879 staticpro (&QSscratch); |
2237 | 1880 staticpro (&Vbuffer_alist); |
2238 QSFundamental = build_string ("Fundamental"); | 1881 |
2239 QSscratch = build_string (DEFER_GETTEXT ("*scratch*")); | 1882 QSFundamental = Fpurecopy (build_string ("Fundamental")); |
1883 QSscratch = Fpurecopy (build_string (DEFER_GETTEXT ("*scratch*"))); | |
1884 | |
1885 Vbuffer_alist = Qnil; | |
1886 current_buffer = 0; | |
2240 | 1887 |
2241 DEFVAR_LISP ("change-major-mode-hook", &Vchange_major_mode_hook /* | 1888 DEFVAR_LISP ("change-major-mode-hook", &Vchange_major_mode_hook /* |
2242 List of hooks to be run before killing local variables in a buffer. | 1889 List of hooks to be run before killing local variables in a buffer. |
2243 This should be used by any mode that temporarily alters the contents or | 1890 This should be used by any mode that temporarily alters the contents or |
2244 the read-only state of the buffer. See also `kill-all-local-variables'. | 1891 the read-only state of the buffer. See also `kill-all-local-variables'. |
2369 | 2016 |
2370 /* The docstrings for DEFVAR_* are recorded externally by make-docfile. */ | 2017 /* The docstrings for DEFVAR_* are recorded externally by make-docfile. */ |
2371 | 2018 |
2372 /* Renamed from DEFVAR_PER_BUFFER because FSFmacs D_P_B takes | 2019 /* Renamed from DEFVAR_PER_BUFFER because FSFmacs D_P_B takes |
2373 a bogus extra arg, which confuses an otherwise identical make-docfile.c */ | 2020 a bogus extra arg, which confuses an otherwise identical make-docfile.c */ |
2021 | |
2022 /* Declaring this stuff as const produces 'Cannot reinitialize' messages | |
2023 from SunPro C's fix-and-continue feature (a way neato feature that | |
2024 makes debugging unbelievably more bearable) */ | |
2374 #define DEFVAR_BUFFER_LOCAL_1(lname, field_name, forward_type, magicfun) do { \ | 2025 #define DEFVAR_BUFFER_LOCAL_1(lname, field_name, forward_type, magicfun) do { \ |
2375 static const struct symbol_value_forward I_hate_C = \ | 2026 static CONST_IF_NOT_DEBUG struct symbol_value_forward I_hate_C \ |
2376 { /* struct symbol_value_forward */ \ | 2027 = { { { symbol_value_forward_lheader_initializer, \ |
2377 { /* struct symbol_value_magic */ \ | 2028 (struct lcrecord_header *) &(buffer_local_flags.field_name), 69 }, \ |
2378 { /* struct lcrecord_header */ \ | 2029 forward_type }, magicfun }; \ |
2379 { /* struct lrecord_header */ \ | |
2380 lrecord_type_symbol_value_forward, /* lrecord_type_index */ \ | |
2381 1, /* mark bit */ \ | |
2382 1, /* c_readonly bit */ \ | |
2383 1 /* lisp_readonly bit */ \ | |
2384 }, \ | |
2385 0, /* next */ \ | |
2386 0, /* uid */ \ | |
2387 0 /* free */ \ | |
2388 }, \ | |
2389 &(buffer_local_flags.field_name), \ | |
2390 forward_type \ | |
2391 }, \ | |
2392 magicfun \ | |
2393 }; \ | |
2394 \ | |
2395 { \ | 2030 { \ |
2396 int offset = ((char *)symbol_value_forward_forward (&I_hate_C) - \ | 2031 int offset = ((char *)symbol_value_forward_forward (&I_hate_C) - \ |
2397 (char *)&buffer_local_flags); \ | 2032 (char *)&buffer_local_flags); \ |
2398 defvar_magic (lname, &I_hate_C); \ | 2033 defvar_magic (lname, &I_hate_C); \ |
2399 \ | 2034 \ |
2426 | 2061 |
2427 b->extent_info = Qnil; | 2062 b->extent_info = Qnil; |
2428 b->indirect_children = Qnil; | 2063 b->indirect_children = Qnil; |
2429 b->own_text.line_number_cache = Qnil; | 2064 b->own_text.line_number_cache = Qnil; |
2430 | 2065 |
2431 #define MARKED_SLOT(x) b->x = zap | 2066 #define MARKED_SLOT(x) b->x = (zap); |
2432 #include "bufslots.h" | 2067 #include "bufslots.h" |
2433 #undef MARKED_SLOT | 2068 #undef MARKED_SLOT |
2434 } | 2069 } |
2435 | 2070 |
2436 static void | 2071 void |
2437 common_init_complex_vars_of_buffer (void) | 2072 complex_vars_of_buffer (void) |
2438 { | 2073 { |
2439 /* Make sure all markable slots in buffer_defaults | 2074 /* Make sure all markable slots in buffer_defaults |
2440 are initialized reasonably, so mark_buffer won't choke. */ | 2075 are initialized reasonably, so mark_buffer won't choke. */ |
2441 struct buffer *defs = alloc_lcrecord_type (struct buffer, &lrecord_buffer); | 2076 struct buffer *defs = alloc_lcrecord_type (struct buffer, &lrecord_buffer); |
2442 struct buffer *syms = alloc_lcrecord_type (struct buffer, &lrecord_buffer); | 2077 struct buffer *syms = alloc_lcrecord_type (struct buffer, &lrecord_buffer); |
2443 | 2078 |
2444 staticpro_nodump (&Vbuffer_defaults); | 2079 staticpro (&Vbuffer_defaults); |
2445 staticpro_nodump (&Vbuffer_local_symbols); | 2080 staticpro (&Vbuffer_local_symbols); |
2446 XSETBUFFER (Vbuffer_defaults, defs); | 2081 XSETBUFFER (Vbuffer_defaults, defs); |
2447 XSETBUFFER (Vbuffer_local_symbols, syms); | 2082 XSETBUFFER (Vbuffer_local_symbols, syms); |
2448 | 2083 |
2449 nuke_all_buffer_slots (syms, Qnil); | 2084 nuke_all_buffer_slots (syms, Qnil); |
2450 nuke_all_buffer_slots (defs, Qnil); | 2085 nuke_all_buffer_slots (defs, Qnil); |
2556 #endif | 2191 #endif |
2557 #ifdef FILE_CODING | 2192 #ifdef FILE_CODING |
2558 buffer_local_flags.buffer_file_coding_system = make_int (1<<14); | 2193 buffer_local_flags.buffer_file_coding_system = make_int (1<<14); |
2559 #endif | 2194 #endif |
2560 | 2195 |
2561 /* #### Warning: 1<<31 is the largest number currently allowable | 2196 /* #### Warning: 1<<28 is the largest number currently allowable |
2562 due to the XINT() handling of this value. With some | 2197 due to the XINT() handling of this value. With some |
2563 rearrangement you can get 3 more bits. */ | 2198 rearrangement you can get 3 more bits. */ |
2564 } | 2199 } |
2565 } | |
2566 | |
2567 #define BUFFER_SLOTS_SIZE (offsetof (struct buffer, BUFFER_SLOTS_LAST_NAME) - offsetof (struct buffer, BUFFER_SLOTS_FIRST_NAME) + sizeof (Lisp_Object)) | |
2568 #define BUFFER_SLOTS_COUNT (BUFFER_SLOTS_SIZE / sizeof (Lisp_Object)) | |
2569 | |
2570 void | |
2571 reinit_complex_vars_of_buffer (void) | |
2572 { | |
2573 struct buffer *defs, *syms; | |
2574 | |
2575 common_init_complex_vars_of_buffer (); | |
2576 | |
2577 defs = XBUFFER (Vbuffer_defaults); | |
2578 syms = XBUFFER (Vbuffer_local_symbols); | |
2579 memcpy (&defs->BUFFER_SLOTS_FIRST_NAME, | |
2580 buffer_defaults_saved_slots, | |
2581 BUFFER_SLOTS_SIZE); | |
2582 memcpy (&syms->BUFFER_SLOTS_FIRST_NAME, | |
2583 buffer_local_symbols_saved_slots, | |
2584 BUFFER_SLOTS_SIZE); | |
2585 } | |
2586 | |
2587 | |
2588 static const struct lrecord_description buffer_slots_description_1[] = { | |
2589 { XD_LISP_OBJECT_ARRAY, 0, BUFFER_SLOTS_COUNT }, | |
2590 { XD_END } | |
2591 }; | |
2592 | |
2593 static const struct struct_description buffer_slots_description = { | |
2594 BUFFER_SLOTS_SIZE, | |
2595 buffer_slots_description_1 | |
2596 }; | |
2597 | |
2598 void | |
2599 complex_vars_of_buffer (void) | |
2600 { | |
2601 struct buffer *defs, *syms; | |
2602 | |
2603 common_init_complex_vars_of_buffer (); | |
2604 | |
2605 defs = XBUFFER (Vbuffer_defaults); | |
2606 syms = XBUFFER (Vbuffer_local_symbols); | |
2607 buffer_defaults_saved_slots = &defs->BUFFER_SLOTS_FIRST_NAME; | |
2608 buffer_local_symbols_saved_slots = &syms->BUFFER_SLOTS_FIRST_NAME; | |
2609 dumpstruct (&buffer_defaults_saved_slots, &buffer_slots_description); | |
2610 dumpstruct (&buffer_local_symbols_saved_slots, &buffer_slots_description); | |
2611 | 2200 |
2612 DEFVAR_BUFFER_DEFAULTS ("default-modeline-format", modeline_format /* | 2201 DEFVAR_BUFFER_DEFAULTS ("default-modeline-format", modeline_format /* |
2613 Default value of `modeline-format' for buffers that don't override it. | 2202 Default value of `modeline-format' for buffers that don't override it. |
2614 This is the same as (default-value 'modeline-format). | 2203 This is the same as (default-value 'modeline-format). |
2615 */ ); | 2204 */ ); |
2658 */ ); | 2247 */ ); |
2659 | 2248 |
2660 DEFVAR_BUFFER_LOCAL ("modeline-format", modeline_format /* | 2249 DEFVAR_BUFFER_LOCAL ("modeline-format", modeline_format /* |
2661 Template for displaying modeline for current buffer. | 2250 Template for displaying modeline for current buffer. |
2662 Each buffer has its own value of this variable. | 2251 Each buffer has its own value of this variable. |
2663 Value may be a string, symbol, glyph, generic specifier, list or cons cell. | 2252 Value may be a string, a symbol or a list or cons cell. |
2664 For a symbol, its value is processed (but it is ignored if t or nil). | 2253 For a symbol, its value is used (but it is ignored if t or nil). |
2665 A string appearing directly as the value of a symbol is processed verbatim | 2254 A string appearing directly as the value of a symbol is processed verbatim |
2666 in that the %-constructs below are not recognized. | 2255 in that the %-constructs below are not recognized. |
2667 For a glyph, it is inserted as is. | 2256 For a glyph, it is inserted as is. |
2668 For a generic specifier (i.e. a specifier of type `generic'), its instance | |
2669 is computed in the current window using the equivalent of `specifier-instance' | |
2670 and the value is processed. | |
2671 For a list whose car is a symbol, the symbol's value is taken, | 2257 For a list whose car is a symbol, the symbol's value is taken, |
2672 and if that is non-nil, the cadr of the list is processed recursively. | 2258 and if that is non-nil, the cadr of the list is processed recursively. |
2673 Otherwise, the caddr of the list (if there is one) is processed. | 2259 Otherwise, the caddr of the list (if there is one) is processed. |
2674 For a list whose car is a string or list, each element is processed | 2260 For a list whose car is a string or list, each element is processed |
2675 recursively and the results are effectively concatenated. | 2261 recursively and the results are effectively concatenated. |
2676 For a list whose car is an integer, the cdr of the list is processed | 2262 For a list whose car is an integer, the cdr of the list is processed |
2677 and padded (if the number is positive) or truncated (if negative) | 2263 and padded (if the number is positive) or truncated (if negative) |
2678 to the width specified by that number. | 2264 to the width specified by that number. |
2679 For a list whose car is an extent, the cdr of the list is processed | 2265 For a list whose car is an extent, the cdr of the list is processed |
2680 normally but the results are displayed using the face of the | 2266 normally but the results are displayed using the face of the |
2681 extent, and mouse clicks over this section are processed using the | 2267 extent, and mouse clicks over this section are processed using the |
2682 keymap of the extent. (In addition, if the extent has a help-echo | 2268 keymap of the extent. (In addition, if the extent has a help-echo |
2683 property, that string will be echoed when the mouse moves over this | 2269 property, that string will be echoed when the mouse moves over this |
2684 section.) If extents are nested, all keymaps are properly consulted | 2270 section.) See `generated-modeline-string' for more information. |
2685 when processing mouse clicks, but multiple faces are not correctly | 2271 For a list whose car is a face, the cdr of the list is processed |
2686 merged (only the first face is used), and lists of faces are not | 2272 normally but the results will be displayed using the face in the car. |
2687 correctly handled. See `generated-modeline-string' for more information. | 2273 For a list whose car is a keymap, the cdr of the list is processed |
2274 normally but the keymap will apply for mouse clicks over the results, | |
2275 in addition to `modeline-map'. Nested keymap specifications are | |
2276 handled properly. | |
2688 A string is printed verbatim in the modeline except for %-constructs: | 2277 A string is printed verbatim in the modeline except for %-constructs: |
2689 (%-constructs are processed when the string is the entire modeline-format | 2278 (%-constructs are processed when the string is the entire modeline-format |
2690 or when it is found in a cons-cell or a list) | 2279 or when it is found in a cons-cell or a list) |
2691 %b -- print buffer name. %c -- print the current column number. | 2280 %b -- print buffer name. %c -- print the current column number. |
2692 %f -- print visited file name. | 2281 %f -- print visited file name. |
3097 /* Want no undo records for *scratch* until after Emacs is dumped */ | 2686 /* Want no undo records for *scratch* until after Emacs is dumped */ |
3098 Fbuffer_disable_undo (scratch); | 2687 Fbuffer_disable_undo (scratch); |
3099 } | 2688 } |
3100 } | 2689 } |
3101 | 2690 |
3102 #ifndef WIN32_NATIVE | |
3103 /* Is PWD another name for `.' ? */ | 2691 /* Is PWD another name for `.' ? */ |
3104 static int | 2692 static int |
3105 directory_is_current_directory (Extbyte *pwd) | 2693 directory_is_current_directory (char *pwd) |
3106 { | 2694 { |
3107 Bufbyte *pwd_internal; | 2695 Bufbyte *pwd_internal; |
3108 Bytecount pwd_internal_len; | |
3109 struct stat dotstat, pwdstat; | 2696 struct stat dotstat, pwdstat; |
3110 | 2697 |
3111 TO_INTERNAL_FORMAT (DATA, (pwd, strlen ((char *)pwd) + 1), | 2698 GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (pwd, pwd_internal); |
3112 ALLOCA, (pwd_internal, pwd_internal_len), | |
3113 Qfile_name); | |
3114 | 2699 |
3115 return (IS_DIRECTORY_SEP (*pwd_internal) | 2700 return (IS_DIRECTORY_SEP (*pwd_internal) |
3116 && stat ((char *) pwd_internal, &pwdstat) == 0 | 2701 && stat ((char *) pwd_internal, &pwdstat) == 0 |
3117 && stat (".", &dotstat) == 0 | 2702 && stat (".", &dotstat) == 0 |
3118 && dotstat.st_ino == pwdstat.st_ino | 2703 && dotstat.st_ino == pwdstat.st_ino |
3119 && dotstat.st_dev == pwdstat.st_dev | 2704 && dotstat.st_dev == pwdstat.st_dev |
3120 && pwd_internal_len < MAXPATHLEN); | 2705 && (int) strlen ((char *) pwd_internal) < MAXPATHLEN); |
3121 } | 2706 } |
3122 #endif | |
3123 | 2707 |
3124 void | 2708 void |
3125 init_initial_directory (void) | 2709 init_initial_directory (void) |
3126 { | 2710 { |
3127 /* This function can GC */ | 2711 /* This function can GC */ |
3128 | 2712 |
3129 #ifndef WIN32_NATIVE | 2713 char *pwd; |
3130 Extbyte *pwd; | |
3131 #endif | |
3132 | 2714 |
3133 initial_directory[0] = 0; | 2715 initial_directory[0] = 0; |
3134 | 2716 |
3135 /* If PWD is accurate, use it instead of calling getcwd. This is faster | 2717 /* If PWD is accurate, use it instead of calling getcwd. This is faster |
3136 when PWD is right, and may avoid a fatal error. */ | 2718 when PWD is right, and may avoid a fatal error. */ |
3137 #ifndef WIN32_NATIVE | 2719 if ((pwd = getenv ("PWD")) != NULL |
3138 if ((pwd = (Extbyte *) getenv ("PWD")) != NULL | |
3139 && directory_is_current_directory (pwd)) | 2720 && directory_is_current_directory (pwd)) |
3140 strcpy (initial_directory, (char *) pwd); | 2721 strcpy (initial_directory, pwd); |
3141 else | 2722 else if (getcwd (initial_directory, MAXPATHLEN) == NULL) |
3142 #endif | 2723 fatal ("`getcwd' failed: %s\n", strerror (errno)); |
3143 if (getcwd (initial_directory, MAXPATHLEN) == NULL) | |
3144 fatal ("`getcwd' failed: %s\n", strerror (errno)); | |
3145 | 2724 |
3146 /* Make sure pwd is DIRECTORY_SEP-terminated. | 2725 /* Make sure pwd is DIRECTORY_SEP-terminated. |
3147 Maybe this should really use some standard subroutine | 2726 Maybe this should really use some standard subroutine |
3148 whose definition is filename syntax dependent. */ | 2727 whose definition is filename syntax dependent. */ |
3149 { | 2728 { |
3154 initial_directory[len] = DIRECTORY_SEP; | 2733 initial_directory[len] = DIRECTORY_SEP; |
3155 initial_directory[len + 1] = '\0'; | 2734 initial_directory[len + 1] = '\0'; |
3156 } | 2735 } |
3157 } | 2736 } |
3158 | 2737 |
3159 #ifdef CORRECT_DIR_SEPS | 2738 /* XEmacs change: store buffer's default directory |
3160 CORRECT_DIR_SEPS (initial_directory); | 2739 using preferred (i.e. as defined at compile-time) |
2740 directory separator. --marcpa */ | |
2741 #ifdef DOS_NT | |
2742 #define CORRECT_DIR_SEPS(s) \ | |
2743 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \ | |
2744 else unixtodos_filename (s); \ | |
2745 } while (0) | |
2746 | |
2747 CORRECT_DIR_SEPS(initial_directory); | |
3161 #endif | 2748 #endif |
3162 } | 2749 } |
3163 | 2750 |
3164 void | 2751 void |
3165 init_buffer (void) | 2752 init_buffer (void) |
3167 /* This function can GC */ | 2754 /* This function can GC */ |
3168 | 2755 |
3169 Fset_buffer (Fget_buffer_create (QSscratch)); | 2756 Fset_buffer (Fget_buffer_create (QSscratch)); |
3170 | 2757 |
3171 current_buffer->directory = | 2758 current_buffer->directory = |
3172 build_ext_string (initial_directory, Qfile_name); | 2759 build_ext_string (initial_directory, FORMAT_FILENAME); |
3173 | 2760 |
3174 #if 0 /* FSFmacs */ | 2761 #if 0 /* FSFmacs */ |
3175 /* #### is this correct? */ | 2762 /* #### is this correct? */ |
3176 temp = get_minibuffer (0); | 2763 temp = get_minibuffer (0); |
3177 XBUFFER (temp)->directory = current_buffer->directory; | 2764 XBUFFER (temp)->directory = current_buffer->directory; |