diff options
| author | Richard M. Stallman | 1995-08-05 22:51:17 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-08-05 22:51:17 +0000 |
| commit | b2a30870b013fa712bf3bcd82b8ce42aceadacbf (patch) | |
| tree | d369e139f55f54a290c61c2383b858ab68cc4082 | |
| parent | 03524be63ae2a8d72fce0652208a57f1fc788edb (diff) | |
| download | emacs-b2a30870b013fa712bf3bcd82b8ce42aceadacbf.tar.gz emacs-b2a30870b013fa712bf3bcd82b8ce42aceadacbf.zip | |
(saved_doc_string*): New variables.
(load_force_doc_strings): New variable.
(syms_of_lread): Set up Lisp var load-force-doc-strings.
(read_list): Handle load_force_doc_strings.
Use the saved_doc_string, if it's right; otherwise, reread from file.
(read1): Save last doc string in saved_doc_string.
| -rw-r--r-- | src/lread.c | 115 |
1 files changed, 108 insertions, 7 deletions
diff --git a/src/lread.c b/src/lread.c index 05ba7a5285a..5febd2fea5a 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -91,19 +91,31 @@ Lisp_Object Vload_file_name; | |||
| 91 | /* Function to use for reading, in `load' and friends. */ | 91 | /* Function to use for reading, in `load' and friends. */ |
| 92 | Lisp_Object Vload_read_function; | 92 | Lisp_Object Vload_read_function; |
| 93 | 93 | ||
| 94 | /* Nonzero means load should forcibly load all dynamic doc strings. */ | ||
| 95 | static int load_force_doc_strings; | ||
| 96 | |||
| 94 | /* List of descriptors now open for Fload. */ | 97 | /* List of descriptors now open for Fload. */ |
| 95 | static Lisp_Object load_descriptor_list; | 98 | static Lisp_Object load_descriptor_list; |
| 96 | 99 | ||
| 97 | /* File for get_file_char to read from. Use by load */ | 100 | /* File for get_file_char to read from. Use by load. */ |
| 98 | static FILE *instream; | 101 | static FILE *instream; |
| 99 | 102 | ||
| 100 | /* When nonzero, read conses in pure space */ | 103 | /* When nonzero, read conses in pure space */ |
| 101 | static int read_pure; | 104 | static int read_pure; |
| 102 | 105 | ||
| 103 | /* For use within read-from-string (this reader is non-reentrant!!) */ | 106 | /* For use within read-from-string (this reader is non-reentrant!!) */ |
| 104 | static int read_from_string_index; | 107 | static int read_from_string_index; |
| 105 | static int read_from_string_limit; | 108 | static int read_from_string_limit; |
| 106 | 109 | ||
| 110 | /* This contains the last string skipped with #@. */ | ||
| 111 | static char *saved_doc_string; | ||
| 112 | /* Length of buffer allocated in saved_doc_string. */ | ||
| 113 | static int saved_doc_string_size; | ||
| 114 | /* Length of actual data in saved_doc_string. */ | ||
| 115 | static int saved_doc_string_length; | ||
| 116 | /* This is the file position that string came from. */ | ||
| 117 | static int saved_doc_string_position; | ||
| 118 | |||
| 107 | /* Nonzero means inside a new-style backquote | 119 | /* Nonzero means inside a new-style backquote |
| 108 | with no surrounding parentheses. | 120 | with no surrounding parentheses. |
| 109 | Fread initializes this to zero, so we need not specbind it | 121 | Fread initializes this to zero, so we need not specbind it |
| @@ -462,6 +474,11 @@ Return t if file exists.") | |||
| 462 | Fprogn (Fcdr (temp)); | 474 | Fprogn (Fcdr (temp)); |
| 463 | UNGCPRO; | 475 | UNGCPRO; |
| 464 | 476 | ||
| 477 | if (saved_doc_string) | ||
| 478 | free (saved_doc_string); | ||
| 479 | saved_doc_string = 0; | ||
| 480 | saved_doc_string_size = 0; | ||
| 481 | |||
| 465 | if (!noninteractive && NILP (nomessage)) | 482 | if (!noninteractive && NILP (nomessage)) |
| 466 | message ("Loading %s...done", XSTRING (str)->data); | 483 | message ("Loading %s...done", XSTRING (str)->data); |
| 467 | return Qt; | 484 | return Qt; |
| @@ -1223,9 +1240,39 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1223 | if (c >= 0) | 1240 | if (c >= 0) |
| 1224 | UNREAD (c); | 1241 | UNREAD (c); |
| 1225 | 1242 | ||
| 1226 | /* Skip that many characters. */ | 1243 | #ifndef DOS_NT /* I don't know if filepos works right on MSDOS and Windoze. */ |
| 1227 | for (i = 0; i < nskip && c >= 0; i++) | 1244 | if (load_force_doc_strings && EQ (readcharfun, Qget_file_char)) |
| 1228 | c = READCHAR; | 1245 | { |
| 1246 | /* If we are supposed to force doc strings into core right now, | ||
| 1247 | record the last string that we skipped, | ||
| 1248 | and record where in the file it comes from. */ | ||
| 1249 | if (saved_doc_string_size == 0) | ||
| 1250 | { | ||
| 1251 | saved_doc_string_size = nskip + 100; | ||
| 1252 | saved_doc_string = (char *) malloc (saved_doc_string_size); | ||
| 1253 | } | ||
| 1254 | if (nskip > saved_doc_string_size) | ||
| 1255 | { | ||
| 1256 | saved_doc_string_size = nskip + 100; | ||
| 1257 | saved_doc_string = (char *) realloc (saved_doc_string, | ||
| 1258 | saved_doc_string_size); | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | saved_doc_string_position = ftell (instream); | ||
| 1262 | |||
| 1263 | /* Copy that many characters into saved_doc_string. */ | ||
| 1264 | for (i = 0; i < nskip && c >= 0; i++) | ||
| 1265 | saved_doc_string[i] = c = READCHAR; | ||
| 1266 | |||
| 1267 | saved_doc_string_length = i; | ||
| 1268 | } | ||
| 1269 | else | ||
| 1270 | #endif /* not DOS_NT */ | ||
| 1271 | { | ||
| 1272 | /* Skip that many characters. */ | ||
| 1273 | for (i = 0; i < nskip && c >= 0; i++) | ||
| 1274 | c = READCHAR; | ||
| 1275 | } | ||
| 1229 | goto retry; | 1276 | goto retry; |
| 1230 | } | 1277 | } |
| 1231 | if (c == '$') | 1278 | if (c == '$') |
| @@ -1565,7 +1612,8 @@ read_list (flag, readcharfun) | |||
| 1565 | register Lisp_Object elt, tem; | 1612 | register Lisp_Object elt, tem; |
| 1566 | struct gcpro gcpro1, gcpro2; | 1613 | struct gcpro gcpro1, gcpro2; |
| 1567 | /* 0 is the normal case. | 1614 | /* 0 is the normal case. |
| 1568 | 1 means this list is a doc reference; replace it with the number 0. */ | 1615 | 1 means this list is a doc reference; replace it with the number 0. |
| 1616 | 2 means this list is a doc reference; replace it with the doc string. */ | ||
| 1569 | int doc_reference = 0; | 1617 | int doc_reference = 0; |
| 1570 | 1618 | ||
| 1571 | /* Initialize this to 1 if we are reading a list. */ | 1619 | /* Initialize this to 1 if we are reading a list. */ |
| @@ -1602,6 +1650,9 @@ read_list (flag, readcharfun) | |||
| 1602 | elt = concat2 (build_string ("../lisp/"), | 1650 | elt = concat2 (build_string ("../lisp/"), |
| 1603 | Ffile_name_nondirectory (elt)); | 1651 | Ffile_name_nondirectory (elt)); |
| 1604 | } | 1652 | } |
| 1653 | else if (EQ (elt, Vload_file_name) | ||
| 1654 | && load_force_doc_strings) | ||
| 1655 | doc_reference = 2; | ||
| 1605 | 1656 | ||
| 1606 | if (ch) | 1657 | if (ch) |
| 1607 | { | 1658 | { |
| @@ -1627,6 +1678,46 @@ read_list (flag, readcharfun) | |||
| 1627 | { | 1678 | { |
| 1628 | if (doc_reference == 1) | 1679 | if (doc_reference == 1) |
| 1629 | return make_number (0); | 1680 | return make_number (0); |
| 1681 | if (doc_reference == 2) | ||
| 1682 | { | ||
| 1683 | /* Get a doc string from the file we are loading. | ||
| 1684 | If it's in saved_doc_string, get it from there. */ | ||
| 1685 | int pos = XINT (XCONS (val)->cdr); | ||
| 1686 | if (pos >= saved_doc_string_position | ||
| 1687 | && pos < (saved_doc_string_position | ||
| 1688 | + saved_doc_string_length)) | ||
| 1689 | { | ||
| 1690 | int start = pos - saved_doc_string_position; | ||
| 1691 | int from, to; | ||
| 1692 | |||
| 1693 | /* Process quoting with ^A, | ||
| 1694 | and find the end of the string, | ||
| 1695 | which is marked with ^_ (037). */ | ||
| 1696 | for (from = start, to = start; | ||
| 1697 | saved_doc_string[from] != 037;) | ||
| 1698 | { | ||
| 1699 | int c = saved_doc_string[from++]; | ||
| 1700 | if (c == 1) | ||
| 1701 | { | ||
| 1702 | c = saved_doc_string[from++]; | ||
| 1703 | if (c == 1) | ||
| 1704 | saved_doc_string[to++] = c; | ||
| 1705 | else if (c == '0') | ||
| 1706 | saved_doc_string[to++] = 0; | ||
| 1707 | else if (c == '_') | ||
| 1708 | saved_doc_string[to++] = 037; | ||
| 1709 | } | ||
| 1710 | else | ||
| 1711 | saved_doc_string[to++] = c; | ||
| 1712 | } | ||
| 1713 | |||
| 1714 | return make_string (saved_doc_string + start, | ||
| 1715 | to - start); | ||
| 1716 | } | ||
| 1717 | else | ||
| 1718 | return read_doc_string (val); | ||
| 1719 | } | ||
| 1720 | |||
| 1630 | return val; | 1721 | return val; |
| 1631 | } | 1722 | } |
| 1632 | return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil)); | 1723 | return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil)); |
| @@ -1783,7 +1874,12 @@ OBARRAY defaults to the value of the variable `obarray'.") | |||
| 1783 | hash = oblookup_last_bucket_number; | 1874 | hash = oblookup_last_bucket_number; |
| 1784 | 1875 | ||
| 1785 | if (EQ (XVECTOR (obarray)->contents[hash], tem)) | 1876 | if (EQ (XVECTOR (obarray)->contents[hash], tem)) |
| 1786 | XSETSYMBOL (XVECTOR (obarray)->contents[hash], XSYMBOL (tem)->next); | 1877 | { |
| 1878 | if (XSYMBOL (tem)->next) | ||
| 1879 | XSETSYMBOL (XVECTOR (obarray)->contents[hash], XSYMBOL (tem)->next); | ||
| 1880 | else | ||
| 1881 | XSETINT (XVECTOR (obarray)->contents[hash], 0); | ||
| 1882 | } | ||
| 1787 | else | 1883 | else |
| 1788 | { | 1884 | { |
| 1789 | Lisp_Object tail, following; | 1885 | Lisp_Object tail, following; |
| @@ -2266,6 +2362,11 @@ or variables, and cons cells `(provide . FEATURE)' and `(require . FEATURE)'."); | |||
| 2266 | The default is nil, which means use the function `read'."); | 2362 | The default is nil, which means use the function `read'."); |
| 2267 | Vload_read_function = Qnil; | 2363 | Vload_read_function = Qnil; |
| 2268 | 2364 | ||
| 2365 | DEFVAR_BOOL ("load-force-doc-strings", &load_force_doc_strings, | ||
| 2366 | "Non-nil means `load' should force-load all dynamic doc strings.\n\ | ||
| 2367 | This is useful when the file being loaded is a temporary copy."); | ||
| 2368 | load_force_doc_strings = 0; | ||
| 2369 | |||
| 2269 | load_descriptor_list = Qnil; | 2370 | load_descriptor_list = Qnil; |
| 2270 | staticpro (&load_descriptor_list); | 2371 | staticpro (&load_descriptor_list); |
| 2271 | 2372 | ||