comparison src/buffer.c @ 440:8de8e3f6228a r21-2-28

Import from CVS: tag r21-2-28
author cvs
date Mon, 13 Aug 2007 11:33:38 +0200
parents 9d177e8d4150
children abe6d1db359e
comparison
equal deleted inserted replaced
439:357dd071b03c 440:8de8e3f6228a
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"
1408 XCDR (prev) = XCDR (XCDR (prev)); 1412 XCDR (prev) = XCDR (XCDR (prev));
1409 XCDR (lynk) = f->buffer_alist; 1413 XCDR (lynk) = f->buffer_alist;
1410 f->buffer_alist = lynk; 1414 f->buffer_alist = lynk;
1411 1415
1412 va_run_hook_with_args (Qrecord_buffer_hook, 1, buffer); 1416 va_run_hook_with_args (Qrecord_buffer_hook, 1, buffer);
1413 1417
1414 return Qnil; 1418 return Qnil;
1415 } 1419 }
1416 1420
1417 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, /*
1418 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'.
1802 1806
1803 return Fnreverse (val); 1807 return Fnreverse (val);
1804 } 1808 }
1805 1809
1806 #endif /* MEMORY_USAGE_STATS */ 1810 #endif /* MEMORY_USAGE_STATS */
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
1807 2147
1808 void 2148 void
1809 syms_of_buffer (void) 2149 syms_of_buffer (void)
1810 { 2150 {
1811 defsymbol (&Qbuffer_live_p, "buffer-live-p"); 2151 defsymbol (&Qbuffer_live_p, "buffer-live-p");
1877 } 2217 }
1878 2218
1879 void 2219 void
1880 reinit_vars_of_buffer (void) 2220 reinit_vars_of_buffer (void)
1881 { 2221 {
2222 conversion_in_dynarr = Dynarr_new (Bufbyte);
2223 conversion_out_dynarr = Dynarr_new (Extbyte);
2224
1882 staticpro_nodump (&Vbuffer_alist); 2225 staticpro_nodump (&Vbuffer_alist);
1883 Vbuffer_alist = Qnil; 2226 Vbuffer_alist = Qnil;
1884 current_buffer = 0; 2227 current_buffer = 0;
1885 } 2228 }
1886 2229
2231 BUFFER_SLOTS_SIZE); 2574 BUFFER_SLOTS_SIZE);
2232 } 2575 }
2233 2576
2234 2577
2235 static const struct lrecord_description buffer_slots_description_1[] = { 2578 static const struct lrecord_description buffer_slots_description_1[] = {
2236 { XD_LISP_OBJECT, 0, BUFFER_SLOTS_COUNT }, 2579 { XD_LISP_OBJECT_ARRAY, 0, BUFFER_SLOTS_COUNT },
2237 { XD_END } 2580 { XD_END }
2238 }; 2581 };
2239 2582
2240 static const struct struct_description buffer_slots_description = { 2583 static const struct struct_description buffer_slots_description = {
2241 BUFFER_SLOTS_SIZE, 2584 BUFFER_SLOTS_SIZE,
2253 syms = XBUFFER (Vbuffer_local_symbols); 2596 syms = XBUFFER (Vbuffer_local_symbols);
2254 buffer_defaults_saved_slots = &defs->BUFFER_SLOTS_FIRST_NAME; 2597 buffer_defaults_saved_slots = &defs->BUFFER_SLOTS_FIRST_NAME;
2255 buffer_local_symbols_saved_slots = &syms->BUFFER_SLOTS_FIRST_NAME; 2598 buffer_local_symbols_saved_slots = &syms->BUFFER_SLOTS_FIRST_NAME;
2256 dumpstruct (&buffer_defaults_saved_slots, &buffer_slots_description); 2599 dumpstruct (&buffer_defaults_saved_slots, &buffer_slots_description);
2257 dumpstruct (&buffer_local_symbols_saved_slots, &buffer_slots_description); 2600 dumpstruct (&buffer_local_symbols_saved_slots, &buffer_slots_description);
2258 2601
2259 DEFVAR_BUFFER_DEFAULTS ("default-modeline-format", modeline_format /* 2602 DEFVAR_BUFFER_DEFAULTS ("default-modeline-format", modeline_format /*
2260 Default value of `modeline-format' for buffers that don't override it. 2603 Default value of `modeline-format' for buffers that don't override it.
2261 This is the same as (default-value 'modeline-format). 2604 This is the same as (default-value 'modeline-format).
2262 */ ); 2605 */ );
2263 2606
2746 } 3089 }
2747 } 3090 }
2748 3091
2749 /* Is PWD another name for `.' ? */ 3092 /* Is PWD another name for `.' ? */
2750 static int 3093 static int
2751 directory_is_current_directory (char *pwd) 3094 directory_is_current_directory (Extbyte *pwd)
2752 { 3095 {
2753 Bufbyte *pwd_internal; 3096 Bufbyte *pwd_internal;
3097 Bytecount pwd_internal_len;
2754 struct stat dotstat, pwdstat; 3098 struct stat dotstat, pwdstat;
2755 3099
2756 GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (pwd, pwd_internal); 3100 TO_INTERNAL_FORMAT (DATA, (pwd, strlen ((char *)pwd) + 1),
3101 ALLOCA, (pwd_internal, pwd_internal_len),
3102 Qfile_name);
2757 3103
2758 return (IS_DIRECTORY_SEP (*pwd_internal) 3104 return (IS_DIRECTORY_SEP (*pwd_internal)
2759 && stat ((char *) pwd_internal, &pwdstat) == 0 3105 && stat ((char *) pwd_internal, &pwdstat) == 0
2760 && stat (".", &dotstat) == 0 3106 && stat (".", &dotstat) == 0
2761 && dotstat.st_ino == pwdstat.st_ino 3107 && dotstat.st_ino == pwdstat.st_ino
2762 && dotstat.st_dev == pwdstat.st_dev 3108 && dotstat.st_dev == pwdstat.st_dev
2763 && (int) strlen ((char *) pwd_internal) < MAXPATHLEN); 3109 && pwd_internal_len < MAXPATHLEN);
2764 } 3110 }
2765 3111
2766 void 3112 void
2767 init_initial_directory (void) 3113 init_initial_directory (void)
2768 { 3114 {
2769 /* This function can GC */ 3115 /* This function can GC */
2770 3116
2771 char *pwd; 3117 Extbyte *pwd;
2772 3118
2773 initial_directory[0] = 0; 3119 initial_directory[0] = 0;
2774 3120
2775 /* If PWD is accurate, use it instead of calling getcwd. This is faster 3121 /* If PWD is accurate, use it instead of calling getcwd. This is faster
2776 when PWD is right, and may avoid a fatal error. */ 3122 when PWD is right, and may avoid a fatal error. */
2777 if ((pwd = getenv ("PWD")) != NULL 3123 if ((pwd = (Extbyte *) getenv ("PWD")) != NULL
2778 && directory_is_current_directory (pwd)) 3124 && directory_is_current_directory (pwd))
2779 strcpy (initial_directory, pwd); 3125 strcpy (initial_directory, (char *) pwd);
2780 else if (getcwd (initial_directory, MAXPATHLEN) == NULL) 3126 else if (getcwd (initial_directory, MAXPATHLEN) == NULL)
2781 fatal ("`getcwd' failed: %s\n", strerror (errno)); 3127 fatal ("`getcwd' failed: %s\n", strerror (errno));
2782 3128
2783 /* Make sure pwd is DIRECTORY_SEP-terminated. 3129 /* Make sure pwd is DIRECTORY_SEP-terminated.
2784 Maybe this should really use some standard subroutine 3130 Maybe this should really use some standard subroutine
2812 /* This function can GC */ 3158 /* This function can GC */
2813 3159
2814 Fset_buffer (Fget_buffer_create (QSscratch)); 3160 Fset_buffer (Fget_buffer_create (QSscratch));
2815 3161
2816 current_buffer->directory = 3162 current_buffer->directory =
2817 build_ext_string (initial_directory, FORMAT_FILENAME); 3163 build_ext_string (initial_directory, Qfile_name);
2818 3164
2819 #if 0 /* FSFmacs */ 3165 #if 0 /* FSFmacs */
2820 /* #### is this correct? */ 3166 /* #### is this correct? */
2821 temp = get_minibuffer (0); 3167 temp = get_minibuffer (0);
2822 XBUFFER (temp)->directory = current_buffer->directory; 3168 XBUFFER (temp)->directory = current_buffer->directory;