Mercurial > emacs
comparison src/lread.c @ 20548:e9733cb049d9
(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.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Thu, 01 Jan 1998 06:38:45 +0000 |
parents | 0f0a48a69b88 |
children | 0877f6e6fc15 |
comparison
equal
deleted
inserted
replaced
20547:07053199a368 | 20548:e9733cb049d9 |
---|---|
127 static int read_pure; | 127 static int read_pure; |
128 | 128 |
129 /* For use within read-from-string (this reader is non-reentrant!!) */ | 129 /* For use within read-from-string (this reader is non-reentrant!!) */ |
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 | |
133 /* Number of bytes left to read in the buffer character | |
134 that `readchar' has already advanced over. */ | |
135 static int readchar_backlog; | |
132 | 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; |
136 /* Length of buffer allocated in saved_doc_string. */ | 140 /* Length of buffer allocated in saved_doc_string. */ |
167 | 171 |
168 if (BUFFERP (readcharfun)) | 172 if (BUFFERP (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; |
176 | 180 |
177 return c; | 181 if (pt_byte >= BUF_ZV_BYTE (inbuffer)) |
182 return -1; | |
183 | |
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) |
184 | 204 { |
185 if (mpos > BUF_ZV (inbuffer) - 1) | 205 int bytepos = marker_byte_position (readcharfun); |
186 return -1; | 206 int orig_bytepos = bytepos; |
187 c = *(unsigned char *) BUF_CHAR_ADDRESS (inbuffer, mpos); | 207 |
188 if (mpos != BUF_GPT (inbuffer)) | 208 if (bytepos >= BUF_ZV_BYTE (inbuffer)) |
189 XMARKER (readcharfun)->bufpos++; | 209 return -1; |
190 else | 210 |
191 Fset_marker (readcharfun, make_number (mpos + 1), | 211 if (XMARKER (readcharfun)->bufpos == BUF_GPT_BYTE (inbuffer)) |
192 Fmarker_buffer (readcharfun)); | 212 XMARKER (readcharfun)->bufpos += BUF_GAP_SIZE (inbuffer); |
193 return c; | 213 |
214 if (! NILP (inbuffer->enable_multibyte_characters)) | |
215 INC_POS (bytepos); | |
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 { |
197 c = getc (instream); | 231 c = getc (instream); |
198 #ifdef EINTR | 232 #ifdef EINTR |
213 but that truncated -1 to a char on VMS. */ | 247 but that truncated -1 to a char on VMS. */ |
214 if (read_from_string_index < read_from_string_limit) | 248 if (read_from_string_index < read_from_string_limit) |
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 |
221 tem = call0 (readcharfun); | 256 tem = call0 (readcharfun); |
222 | 257 |
236 if (c == -1) | 271 if (c == -1) |
237 /* Don't back up the pointer if we're unreading the end-of-input mark, | 272 /* Don't back up the pointer if we're unreading the end-of-input mark, |
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)) |
252 ungetc (c, instream); | 282 ungetc (c, instream); |
253 else | 283 else |
254 call1 (readcharfun, make_number (c)); | 284 call1 (readcharfun, make_number (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 |
261 extern Lisp_Object read_char (); | 292 extern Lisp_Object read_char (); |
262 | 293 |
882 b = XMARKER (readcharfun)->buffer; | 913 b = XMARKER (readcharfun)->buffer; |
883 | 914 |
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); |
890 | 923 |
891 while (1) | 924 while (1) |
1066 if (NILP (stream)) | 1099 if (NILP (stream)) |
1067 stream = Vstandard_input; | 1100 stream = Vstandard_input; |
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 |
1074 #ifndef standalone | 1108 #ifndef standalone |
1075 if (EQ (stream, Qread_char)) | 1109 if (EQ (stream, Qread_char)) |
1143 static char *read_buffer; | 1177 static char *read_buffer; |
1144 | 1178 |
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; |
1151 Lisp_Object readcharfun; | 1186 Lisp_Object readcharfun; |
1152 { | 1187 { |
1160 && len < MAX_LENGTH_OF_MULTI_BYTE_FORM) | 1195 && len < MAX_LENGTH_OF_MULTI_BYTE_FORM) |
1161 str[len++] = c; | 1196 str[len++] = c; |
1162 UNREAD (c); | 1197 UNREAD (c); |
1163 return STRING_CHAR (str, len); | 1198 return STRING_CHAR (str, len); |
1164 } | 1199 } |
1200 | |
1201 /* Read a \-escape sequence, assuming we already read the `\'. */ | |
1165 | 1202 |
1166 static int | 1203 static int |
1167 read_escape (readcharfun) | 1204 read_escape (readcharfun) |
1168 Lisp_Object readcharfun; | 1205 Lisp_Object readcharfun; |
1169 { | 1206 { |
1622 | 1659 |
1623 if (c == '\\') | 1660 if (c == '\\') |
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); | 1664 |
1628 | 1665 return make_number (c); |
1629 return val; | |
1630 } | 1666 } |
1631 | 1667 |
1632 case '\"': | 1668 case '\"': |
1633 { | 1669 { |
1634 register char *p = read_buffer; | 1670 register char *p = read_buffer; |
1668 bcopy (str, p, length); | 1704 bcopy (str, p, length); |
1669 p += length; | 1705 p += length; |
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 { |
1676 if (p == read_buffer) | 1713 if (p == read_buffer) |
1677 cancel = 1; | 1714 cancel = 1; |
1690 if (c & ~0xff) | 1727 if (c & ~0xff) |
1691 error ("Invalid modifier in string"); | 1728 error ("Invalid modifier in string"); |
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 |
1699 that we are really going to find in etc/DOC.nn.nn */ | 1737 that we are really going to find in etc/DOC.nn.nn */ |
1700 if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel) | 1738 if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel) |
1734 int quoted = 0; | 1772 int quoted = 0; |
1735 | 1773 |
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 { |
1752 register char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2); | 1790 register char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2); |
1753 p += new - read_buffer; | 1791 p += new - read_buffer; |
1757 if (c == '\\') | 1795 if (c == '\\') |
1758 { | 1796 { |
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 |
1766 if (p == end) | 1806 if (p == end) |
1767 { | 1807 { |
1903 free_cons (otem); | 1943 free_cons (otem); |
1904 } | 1944 } |
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 |
1913 read_list (flag, readcharfun) | 1953 read_list (flag, readcharfun) |
1914 int flag; | 1954 int flag; |