diff options
| author | Richard M. Stallman | 1998-01-01 06:38:45 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1998-01-01 06:38:45 +0000 |
| commit | 6f7f43d59d6e55c6562030d858d59b1beb4c4b69 (patch) | |
| tree | a1a5722d05f523fd561bec9eb7378a722fd1d6ae /src | |
| parent | d5d57b92e26ba3d1e188e0692ad6710af067e04e (diff) | |
| download | emacs-6f7f43d59d6e55c6562030d858d59b1beb4c4b69.tar.gz emacs-6f7f43d59d6e55c6562030d858d59b1beb4c4b69.zip | |
(readchar_backlog): New variable.
(readchar): When fetching from buffer or marker,
use readchar_backlog to fetch bytes from a character.
(unreadchar): Increment readchar_backlog.
(readevalloop, Fread): Init readchar_backlog.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lread.c | 110 |
1 files changed, 75 insertions, 35 deletions
diff --git a/src/lread.c b/src/lread.c index 48292c630af..c6f6a53d2c8 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -130,6 +130,10 @@ static int read_pure; | |||
| 130 | static int read_from_string_index; | 130 | static int read_from_string_index; |
| 131 | static int read_from_string_limit; | 131 | static int read_from_string_limit; |
| 132 | 132 | ||
| 133 | /* Number of bytes left to read in the buffer character | ||
| 134 | that `readchar' has already advanced over. */ | ||
| 135 | static int readchar_backlog; | ||
| 136 | |||
| 133 | /* This contains the last string skipped with #@, but only on some systems. | 137 | /* This contains the last string skipped with #@, but only on some systems. |
| 134 | On other systems we can't put the string here. */ | 138 | On other systems we can't put the string here. */ |
| 135 | static char *saved_doc_string; | 139 | static char *saved_doc_string; |
| @@ -169,28 +173,58 @@ readchar (readcharfun) | |||
| 169 | { | 173 | { |
| 170 | inbuffer = XBUFFER (readcharfun); | 174 | inbuffer = XBUFFER (readcharfun); |
| 171 | 175 | ||
| 172 | if (BUF_PT (inbuffer) >= BUF_ZV (inbuffer)) | 176 | if (readchar_backlog == 0) |
| 173 | return -1; | 177 | { |
| 174 | c = *(unsigned char *) BUF_CHAR_ADDRESS (inbuffer, BUF_PT (inbuffer)); | 178 | int pt_byte = BUF_PT_BYTE (inbuffer); |
| 175 | SET_BUF_PT (inbuffer, BUF_PT (inbuffer) + 1); | 179 | int orig_pt_byte = pt_byte; |
| 180 | |||
| 181 | if (pt_byte >= BUF_ZV_BYTE (inbuffer)) | ||
| 182 | return -1; | ||
| 176 | 183 | ||
| 177 | return c; | 184 | if (! NILP (inbuffer->enable_multibyte_characters)) |
| 185 | BUF_INC_POS (inbuffer, pt_byte); | ||
| 186 | else | ||
| 187 | pt_byte++; | ||
| 188 | SET_BUF_PT_BOTH (inbuffer, BUF_PT (inbuffer) + 1, pt_byte); | ||
| 189 | readchar_backlog = pt_byte - orig_pt_byte; | ||
| 190 | } | ||
| 191 | |||
| 192 | /* We get the address of the byte just passed, | ||
| 193 | which is the last byte of the character. | ||
| 194 | The other bytes in this character are consecutive with it, | ||
| 195 | because the gap can't be in the middle of a character. */ | ||
| 196 | return *(BUF_BYTE_ADDRESS (inbuffer, BUF_PT_BYTE (inbuffer) - 1) | ||
| 197 | - --readchar_backlog); | ||
| 178 | } | 198 | } |
| 179 | if (MARKERP (readcharfun)) | 199 | if (MARKERP (readcharfun)) |
| 180 | { | 200 | { |
| 181 | inbuffer = XMARKER (readcharfun)->buffer; | 201 | inbuffer = XMARKER (readcharfun)->buffer; |
| 182 | 202 | ||
| 183 | mpos = marker_position (readcharfun); | 203 | if (readchar_backlog == 0) |
| 204 | { | ||
| 205 | int bytepos = marker_byte_position (readcharfun); | ||
| 206 | int orig_bytepos = bytepos; | ||
| 184 | 207 | ||
| 185 | if (mpos > BUF_ZV (inbuffer) - 1) | 208 | if (bytepos >= BUF_ZV_BYTE (inbuffer)) |
| 186 | return -1; | 209 | return -1; |
| 187 | c = *(unsigned char *) BUF_CHAR_ADDRESS (inbuffer, mpos); | 210 | |
| 188 | if (mpos != BUF_GPT (inbuffer)) | 211 | if (XMARKER (readcharfun)->bufpos == BUF_GPT_BYTE (inbuffer)) |
| 189 | XMARKER (readcharfun)->bufpos++; | 212 | XMARKER (readcharfun)->bufpos += BUF_GAP_SIZE (inbuffer); |
| 190 | else | 213 | |
| 191 | Fset_marker (readcharfun, make_number (mpos + 1), | 214 | if (! NILP (inbuffer->enable_multibyte_characters)) |
| 192 | Fmarker_buffer (readcharfun)); | 215 | INC_POS (bytepos); |
| 193 | return c; | 216 | else |
| 217 | bytepos++; | ||
| 218 | XMARKER (readcharfun)->bufpos += bytepos - orig_bytepos; | ||
| 219 | XMARKER (readcharfun)->charpos++; | ||
| 220 | |||
| 221 | readchar_backlog = bytepos - orig_bytepos; | ||
| 222 | } | ||
| 223 | |||
| 224 | /* Because we move ->bufpos across the gap before we advance it, | ||
| 225 | the gap never comes between the previous character and ->bufpos. */ | ||
| 226 | return *(BUF_BEG_ADDR (inbuffer) + XMARKER (readcharfun)->bufpos | ||
| 227 | - readchar_backlog--); | ||
| 194 | } | 228 | } |
| 195 | if (EQ (readcharfun, Qget_file_char)) | 229 | if (EQ (readcharfun, Qget_file_char)) |
| 196 | { | 230 | { |
| @@ -215,6 +249,7 @@ readchar (readcharfun) | |||
| 215 | c = XSTRING (readcharfun)->data[read_from_string_index++]; | 249 | c = XSTRING (readcharfun)->data[read_from_string_index++]; |
| 216 | else | 250 | else |
| 217 | c = -1; | 251 | c = -1; |
| 252 | |||
| 218 | return c; | 253 | return c; |
| 219 | } | 254 | } |
| 220 | 255 | ||
| @@ -238,14 +273,9 @@ unreadchar (readcharfun, c) | |||
| 238 | since readchar didn't advance it when we read it. */ | 273 | since readchar didn't advance it when we read it. */ |
| 239 | ; | 274 | ; |
| 240 | else if (BUFFERP (readcharfun)) | 275 | else if (BUFFERP (readcharfun)) |
| 241 | { | 276 | readchar_backlog++; |
| 242 | if (XBUFFER (readcharfun) == current_buffer) | ||
| 243 | SET_PT (PT - 1); | ||
| 244 | else | ||
| 245 | SET_BUF_PT (XBUFFER (readcharfun), BUF_PT (XBUFFER (readcharfun)) - 1); | ||
| 246 | } | ||
| 247 | else if (MARKERP (readcharfun)) | 277 | else if (MARKERP (readcharfun)) |
| 248 | XMARKER (readcharfun)->bufpos--; | 278 | readchar_backlog++; |
| 249 | else if (STRINGP (readcharfun)) | 279 | else if (STRINGP (readcharfun)) |
| 250 | read_from_string_index--; | 280 | read_from_string_index--; |
| 251 | else if (EQ (readcharfun, Qget_file_char)) | 281 | else if (EQ (readcharfun, Qget_file_char)) |
| @@ -255,6 +285,7 @@ unreadchar (readcharfun, c) | |||
| 255 | } | 285 | } |
| 256 | 286 | ||
| 257 | static Lisp_Object read0 (), read1 (), read_list (), read_vector (); | 287 | static Lisp_Object read0 (), read1 (), read_list (), read_vector (); |
| 288 | static int read_multibyte (); | ||
| 258 | 289 | ||
| 259 | /* get a character from the tty */ | 290 | /* get a character from the tty */ |
| 260 | 291 | ||
| @@ -884,6 +915,8 @@ readevalloop (readcharfun, stream, sourcename, evalfun, printflag) | |||
| 884 | specbind (Qstandard_input, readcharfun); | 915 | specbind (Qstandard_input, readcharfun); |
| 885 | specbind (Qcurrent_load_list, Qnil); | 916 | specbind (Qcurrent_load_list, Qnil); |
| 886 | 917 | ||
| 918 | readchar_backlog = 0; | ||
| 919 | |||
| 887 | GCPRO1 (sourcename); | 920 | GCPRO1 (sourcename); |
| 888 | 921 | ||
| 889 | LOADHIST_ATTACH (sourcename); | 922 | LOADHIST_ATTACH (sourcename); |
| @@ -1068,6 +1101,7 @@ STREAM or the value of `standard-input' may be:\n\ | |||
| 1068 | if (EQ (stream, Qt)) | 1101 | if (EQ (stream, Qt)) |
| 1069 | stream = Qread_char; | 1102 | stream = Qread_char; |
| 1070 | 1103 | ||
| 1104 | readchar_backlog = 0; | ||
| 1071 | new_backquote_flag = 0; | 1105 | new_backquote_flag = 0; |
| 1072 | read_objects = Qnil; | 1106 | read_objects = Qnil; |
| 1073 | 1107 | ||
| @@ -1145,6 +1179,7 @@ static char *read_buffer; | |||
| 1145 | /* Read multibyte form and return it as a character. C is a first | 1179 | /* Read multibyte form and return it as a character. C is a first |
| 1146 | byte of multibyte form, and rest of them are read from | 1180 | byte of multibyte form, and rest of them are read from |
| 1147 | READCHARFUN. */ | 1181 | READCHARFUN. */ |
| 1182 | |||
| 1148 | static int | 1183 | static int |
| 1149 | read_multibyte (c, readcharfun) | 1184 | read_multibyte (c, readcharfun) |
| 1150 | register int c; | 1185 | register int c; |
| @@ -1163,6 +1198,8 @@ read_multibyte (c, readcharfun) | |||
| 1163 | return STRING_CHAR (str, len); | 1198 | return STRING_CHAR (str, len); |
| 1164 | } | 1199 | } |
| 1165 | 1200 | ||
| 1201 | /* Read a \-escape sequence, assuming we already read the `\'. */ | ||
| 1202 | |||
| 1166 | static int | 1203 | static int |
| 1167 | read_escape (readcharfun) | 1204 | read_escape (readcharfun) |
| 1168 | Lisp_Object readcharfun; | 1205 | Lisp_Object readcharfun; |
| @@ -1624,9 +1661,8 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1624 | c = read_escape (readcharfun); | 1661 | c = read_escape (readcharfun); |
| 1625 | else if (BASE_LEADING_CODE_P (c)) | 1662 | else if (BASE_LEADING_CODE_P (c)) |
| 1626 | c = read_multibyte (c, readcharfun); | 1663 | c = read_multibyte (c, readcharfun); |
| 1627 | XSETINT (val, c); | ||
| 1628 | 1664 | ||
| 1629 | return val; | 1665 | return make_number (c); |
| 1630 | } | 1666 | } |
| 1631 | 1667 | ||
| 1632 | case '\"': | 1668 | case '\"': |
| @@ -1670,6 +1706,7 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1670 | continue; | 1706 | continue; |
| 1671 | } | 1707 | } |
| 1672 | } | 1708 | } |
| 1709 | |||
| 1673 | /* c is -1 if \ newline has just been seen */ | 1710 | /* c is -1 if \ newline has just been seen */ |
| 1674 | if (c == -1) | 1711 | if (c == -1) |
| 1675 | { | 1712 | { |
| @@ -1692,7 +1729,8 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1692 | *p++ = c; | 1729 | *p++ = c; |
| 1693 | } | 1730 | } |
| 1694 | } | 1731 | } |
| 1695 | if (c < 0) return Fsignal (Qend_of_file, Qnil); | 1732 | if (c < 0) |
| 1733 | return Fsignal (Qend_of_file, Qnil); | ||
| 1696 | 1734 | ||
| 1697 | /* If purifying, and string starts with \ newline, | 1735 | /* If purifying, and string starts with \ newline, |
| 1698 | return zero instead. This is for doc strings | 1736 | return zero instead. This is for doc strings |
| @@ -1736,16 +1774,16 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1736 | { | 1774 | { |
| 1737 | register char *end = read_buffer + read_buffer_size; | 1775 | register char *end = read_buffer + read_buffer_size; |
| 1738 | 1776 | ||
| 1739 | while (c > 040 && | 1777 | while (c > 040 |
| 1740 | !(c == '\"' || c == '\'' || c == ';' || c == '?' | 1778 | && !(c == '\"' || c == '\'' || c == ';' || c == '?' |
| 1741 | || c == '(' || c == ')' | 1779 | || c == '(' || c == ')' |
| 1742 | #ifndef LISP_FLOAT_TYPE | 1780 | #ifndef LISP_FLOAT_TYPE |
| 1743 | /* If we have floating-point support, then we need | 1781 | /* If we have floating-point support, then we need |
| 1744 | to allow <digits><dot><digits>. */ | 1782 | to allow <digits><dot><digits>. */ |
| 1745 | || c =='.' | 1783 | || c =='.' |
| 1746 | #endif /* not LISP_FLOAT_TYPE */ | 1784 | #endif /* not LISP_FLOAT_TYPE */ |
| 1747 | || c == '[' || c == ']' || c == '#' | 1785 | || c == '[' || c == ']' || c == '#' |
| 1748 | )) | 1786 | )) |
| 1749 | { | 1787 | { |
| 1750 | if (p == end) | 1788 | if (p == end) |
| 1751 | { | 1789 | { |
| @@ -1759,7 +1797,9 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1759 | c = READCHAR; | 1797 | c = READCHAR; |
| 1760 | quoted = 1; | 1798 | quoted = 1; |
| 1761 | } | 1799 | } |
| 1800 | |||
| 1762 | *p++ = c; | 1801 | *p++ = c; |
| 1802 | |||
| 1763 | c = READCHAR; | 1803 | c = READCHAR; |
| 1764 | } | 1804 | } |
| 1765 | 1805 | ||
| @@ -1905,8 +1945,8 @@ read_vector (readcharfun) | |||
| 1905 | return vector; | 1945 | return vector; |
| 1906 | } | 1946 | } |
| 1907 | 1947 | ||
| 1908 | /* flag = 1 means check for ] to terminate rather than ) and . | 1948 | /* FLAG = 1 means check for ] to terminate rather than ) and . |
| 1909 | flag = -1 means check for starting with defun | 1949 | FLAG = -1 means check for starting with defun |
| 1910 | and make structure pure. */ | 1950 | and make structure pure. */ |
| 1911 | 1951 | ||
| 1912 | static Lisp_Object | 1952 | static Lisp_Object |