diff options
| author | Richard M. Stallman | 1998-06-01 21:03:23 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1998-06-01 21:03:23 +0000 |
| commit | c15cfd1faa5b677ae69f39c6c902e5a9c8f680be (patch) | |
| tree | 772b7a465c47ab24d1afbe8854014c5439856576 /src | |
| parent | 05b44e9027426c791f218f1e9d36d74dde1a2981 (diff) | |
| download | emacs-c15cfd1faa5b677ae69f39c6c902e5a9c8f680be.tar.gz emacs-c15cfd1faa5b677ae69f39c6c902e5a9c8f680be.zip | |
Remember the last TWO strings skipped with #@.
(prev_saved_doc_string*): New variables.
(Fload): Initalize prev_saved_doc_string.
(read1): Copy saved_doc_string to prev_saved_doc_string
before storing a new string in saved_doc_string.
(read_list): Look in prev_saved_doc_string as well as
in saved_doc_string.
(read1): Swap saved_doc_string_length and
prev_saved_doc_string_length.
(read_list): Negate docstring position if negative before checking
against saved_doc_string_length et al.
(read_vector): Add bytecodeflag parameter, which is
nonzero when reading a bytecode object. If
`load-force-doc-strings' is t when reading a lazily-loaded
bytecode vector, the loaded docstring must be treated as unibyte
and passed to Fread to obtain the actual bytecode string and
constants vector.
(read1): Add extra parameter to read_vector calls.
(read1): Enable saving of doc strings on WINDOWSNT.
(read_list): Call get_doc_string instead of read_doc_string, when
forced to load doc strings.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lread.c | 137 |
1 files changed, 124 insertions, 13 deletions
diff --git a/src/lread.c b/src/lread.c index 3eb56a2c35a..fb49268d679 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -142,8 +142,7 @@ static int read_from_string_limit; | |||
| 142 | that `readchar' has already advanced over. */ | 142 | that `readchar' has already advanced over. */ |
| 143 | static int readchar_backlog; | 143 | static int readchar_backlog; |
| 144 | 144 | ||
| 145 | /* This contains the last string skipped with #@, but only on some systems. | 145 | /* This contains the last string skipped with #@. */ |
| 146 | On other systems we can't put the string here. */ | ||
| 147 | static char *saved_doc_string; | 146 | static char *saved_doc_string; |
| 148 | /* Length of buffer allocated in saved_doc_string. */ | 147 | /* Length of buffer allocated in saved_doc_string. */ |
| 149 | static int saved_doc_string_size; | 148 | static int saved_doc_string_size; |
| @@ -152,6 +151,17 @@ static int saved_doc_string_length; | |||
| 152 | /* This is the file position that string came from. */ | 151 | /* This is the file position that string came from. */ |
| 153 | static int saved_doc_string_position; | 152 | static int saved_doc_string_position; |
| 154 | 153 | ||
| 154 | /* This contains the previous string skipped with #@. | ||
| 155 | We copy it from saved_doc_string when a new string | ||
| 156 | is put in saved_doc_string. */ | ||
| 157 | static char *prev_saved_doc_string; | ||
| 158 | /* Length of buffer allocated in prev_saved_doc_string. */ | ||
| 159 | static int prev_saved_doc_string_size; | ||
| 160 | /* Length of actual data in prev_saved_doc_string. */ | ||
| 161 | static int prev_saved_doc_string_length; | ||
| 162 | /* This is the file position that string came from. */ | ||
| 163 | static int prev_saved_doc_string_position; | ||
| 164 | |||
| 155 | /* Nonzero means inside a new-style backquote | 165 | /* Nonzero means inside a new-style backquote |
| 156 | with no surrounding parentheses. | 166 | with no surrounding parentheses. |
| 157 | Fread initializes this to zero, so we need not specbind it | 167 | Fread initializes this to zero, so we need not specbind it |
| @@ -703,6 +713,11 @@ Return t if file exists.") | |||
| 703 | saved_doc_string = 0; | 713 | saved_doc_string = 0; |
| 704 | saved_doc_string_size = 0; | 714 | saved_doc_string_size = 0; |
| 705 | 715 | ||
| 716 | if (prev_saved_doc_string) | ||
| 717 | free (prev_saved_doc_string); | ||
| 718 | prev_saved_doc_string = 0; | ||
| 719 | prev_saved_doc_string_size = 0; | ||
| 720 | |||
| 706 | if (!noninteractive && NILP (nomessage)) | 721 | if (!noninteractive && NILP (nomessage)) |
| 707 | { | 722 | { |
| 708 | if (!compiled) | 723 | if (!compiled) |
| @@ -1519,7 +1534,7 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1519 | return read_list (0, readcharfun); | 1534 | return read_list (0, readcharfun); |
| 1520 | 1535 | ||
| 1521 | case '[': | 1536 | case '[': |
| 1522 | return read_vector (readcharfun); | 1537 | return read_vector (readcharfun, 0); |
| 1523 | 1538 | ||
| 1524 | case ')': | 1539 | case ')': |
| 1525 | case ']': | 1540 | case ']': |
| @@ -1536,7 +1551,7 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1536 | if (c == '[') | 1551 | if (c == '[') |
| 1537 | { | 1552 | { |
| 1538 | Lisp_Object tmp; | 1553 | Lisp_Object tmp; |
| 1539 | tmp = read_vector (readcharfun); | 1554 | tmp = read_vector (readcharfun, 0); |
| 1540 | if (XVECTOR (tmp)->size < CHAR_TABLE_STANDARD_SLOTS | 1555 | if (XVECTOR (tmp)->size < CHAR_TABLE_STANDARD_SLOTS |
| 1541 | || XVECTOR (tmp)->size > CHAR_TABLE_STANDARD_SLOTS + 10) | 1556 | || XVECTOR (tmp)->size > CHAR_TABLE_STANDARD_SLOTS + 10) |
| 1542 | error ("Invalid size char-table"); | 1557 | error ("Invalid size char-table"); |
| @@ -1550,7 +1565,7 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1550 | if (c == '[') | 1565 | if (c == '[') |
| 1551 | { | 1566 | { |
| 1552 | Lisp_Object tmp; | 1567 | Lisp_Object tmp; |
| 1553 | tmp = read_vector (readcharfun); | 1568 | tmp = read_vector (readcharfun, 0); |
| 1554 | if (XVECTOR (tmp)->size != SUB_CHAR_TABLE_STANDARD_SLOTS) | 1569 | if (XVECTOR (tmp)->size != SUB_CHAR_TABLE_STANDARD_SLOTS) |
| 1555 | error ("Invalid size char-table"); | 1570 | error ("Invalid size char-table"); |
| 1556 | XSETCHAR_TABLE (tmp, XCHAR_TABLE (tmp)); | 1571 | XSETCHAR_TABLE (tmp, XCHAR_TABLE (tmp)); |
| @@ -1601,7 +1616,7 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1601 | /* Accept compiled functions at read-time so that we don't have to | 1616 | /* Accept compiled functions at read-time so that we don't have to |
| 1602 | build them using function calls. */ | 1617 | build them using function calls. */ |
| 1603 | Lisp_Object tmp; | 1618 | Lisp_Object tmp; |
| 1604 | tmp = read_vector (readcharfun); | 1619 | tmp = read_vector (readcharfun, 1); |
| 1605 | return Fmake_byte_code (XVECTOR (tmp)->size, | 1620 | return Fmake_byte_code (XVECTOR (tmp)->size, |
| 1606 | XVECTOR (tmp)->contents); | 1621 | XVECTOR (tmp)->contents); |
| 1607 | } | 1622 | } |
| @@ -1656,12 +1671,31 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1656 | if (c >= 0) | 1671 | if (c >= 0) |
| 1657 | UNREAD (c); | 1672 | UNREAD (c); |
| 1658 | 1673 | ||
| 1659 | #ifndef WINDOWSNT /* I don't know if filepos works right on Windoze. */ | ||
| 1660 | if (load_force_doc_strings && EQ (readcharfun, Qget_file_char)) | 1674 | if (load_force_doc_strings && EQ (readcharfun, Qget_file_char)) |
| 1661 | { | 1675 | { |
| 1662 | /* If we are supposed to force doc strings into core right now, | 1676 | /* If we are supposed to force doc strings into core right now, |
| 1663 | record the last string that we skipped, | 1677 | record the last string that we skipped, |
| 1664 | and record where in the file it comes from. */ | 1678 | and record where in the file it comes from. */ |
| 1679 | |||
| 1680 | /* But first exchange saved_doc_string | ||
| 1681 | with prev_saved_doc_string, so we save two strings. */ | ||
| 1682 | { | ||
| 1683 | char *temp = saved_doc_string; | ||
| 1684 | int temp_size = saved_doc_string_size; | ||
| 1685 | int temp_pos = saved_doc_string_position; | ||
| 1686 | int temp_len = saved_doc_string_length; | ||
| 1687 | |||
| 1688 | saved_doc_string = prev_saved_doc_string; | ||
| 1689 | saved_doc_string_size = prev_saved_doc_string_size; | ||
| 1690 | saved_doc_string_position = prev_saved_doc_string_position; | ||
| 1691 | saved_doc_string_length = prev_saved_doc_string_length; | ||
| 1692 | |||
| 1693 | prev_saved_doc_string = temp; | ||
| 1694 | prev_saved_doc_string_size = temp_size; | ||
| 1695 | prev_saved_doc_string_position = temp_pos; | ||
| 1696 | prev_saved_doc_string_length = temp_len; | ||
| 1697 | } | ||
| 1698 | |||
| 1665 | if (saved_doc_string_size == 0) | 1699 | if (saved_doc_string_size == 0) |
| 1666 | { | 1700 | { |
| 1667 | saved_doc_string_size = nskip + 100; | 1701 | saved_doc_string_size = nskip + 100; |
| @@ -1683,7 +1717,6 @@ read1 (readcharfun, pch, first_in_list) | |||
| 1683 | saved_doc_string_length = i; | 1717 | saved_doc_string_length = i; |
| 1684 | } | 1718 | } |
| 1685 | else | 1719 | else |
| 1686 | #endif /* not WINDOWSNT */ | ||
| 1687 | { | 1720 | { |
| 1688 | /* Skip that many characters. */ | 1721 | /* Skip that many characters. */ |
| 1689 | for (i = 0; i < nskip && c >= 0; i++) | 1722 | for (i = 0; i < nskip && c >= 0; i++) |
| @@ -2134,13 +2167,14 @@ isfloat_string (cp) | |||
| 2134 | #endif /* LISP_FLOAT_TYPE */ | 2167 | #endif /* LISP_FLOAT_TYPE */ |
| 2135 | 2168 | ||
| 2136 | static Lisp_Object | 2169 | static Lisp_Object |
| 2137 | read_vector (readcharfun) | 2170 | read_vector (readcharfun, bytecodeflag) |
| 2138 | Lisp_Object readcharfun; | 2171 | Lisp_Object readcharfun; |
| 2172 | int bytecodeflag; | ||
| 2139 | { | 2173 | { |
| 2140 | register int i; | 2174 | register int i; |
| 2141 | register int size; | 2175 | register int size; |
| 2142 | register Lisp_Object *ptr; | 2176 | register Lisp_Object *ptr; |
| 2143 | register Lisp_Object tem, vector; | 2177 | register Lisp_Object tem, item, vector; |
| 2144 | register struct Lisp_Cons *otem; | 2178 | register struct Lisp_Cons *otem; |
| 2145 | Lisp_Object len; | 2179 | Lisp_Object len; |
| 2146 | 2180 | ||
| @@ -2148,12 +2182,55 @@ read_vector (readcharfun) | |||
| 2148 | len = Flength (tem); | 2182 | len = Flength (tem); |
| 2149 | vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil)); | 2183 | vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil)); |
| 2150 | 2184 | ||
| 2151 | |||
| 2152 | size = XVECTOR (vector)->size; | 2185 | size = XVECTOR (vector)->size; |
| 2153 | ptr = XVECTOR (vector)->contents; | 2186 | ptr = XVECTOR (vector)->contents; |
| 2154 | for (i = 0; i < size; i++) | 2187 | for (i = 0; i < size; i++) |
| 2155 | { | 2188 | { |
| 2156 | ptr[i] = read_pure ? Fpurecopy (Fcar (tem)) : Fcar (tem); | 2189 | item = Fcar (tem); |
| 2190 | /* If `load-force-doc-strings' is t when reading a lazily-loaded | ||
| 2191 | bytecode object, the docstring containing the bytecode and | ||
| 2192 | constants values must be treated as unibyte and passed to | ||
| 2193 | Fread, to get the actual bytecode string and constants vector. */ | ||
| 2194 | if (bytecodeflag && load_force_doc_strings) | ||
| 2195 | { | ||
| 2196 | if (i == COMPILED_BYTECODE) | ||
| 2197 | { | ||
| 2198 | if (!STRINGP (item)) | ||
| 2199 | error ("invalid byte code"); | ||
| 2200 | |||
| 2201 | /* Delay handling the bytecode slot until we know whether | ||
| 2202 | it is lazily-loaded (we can tell by whether the | ||
| 2203 | constants slot is nil). */ | ||
| 2204 | ptr[COMPILED_CONSTANTS] = item; | ||
| 2205 | item = Qnil; | ||
| 2206 | } | ||
| 2207 | else if (i == COMPILED_CONSTANTS) | ||
| 2208 | { | ||
| 2209 | Lisp_Object bytestr = ptr[COMPILED_CONSTANTS]; | ||
| 2210 | |||
| 2211 | if (NILP (item)) | ||
| 2212 | { | ||
| 2213 | /* Coerce string to unibyte (like string-as-unibyte, | ||
| 2214 | but without generating extra garbage and | ||
| 2215 | guaranteeing no change in the contents). */ | ||
| 2216 | XSTRING (bytestr)->size = STRING_BYTES (XSTRING (bytestr)); | ||
| 2217 | SET_STRING_BYTES (XSTRING (bytestr), -1); | ||
| 2218 | |||
| 2219 | item = Fread (bytestr); | ||
| 2220 | if (!CONSP (item)) | ||
| 2221 | error ("invalid byte code"); | ||
| 2222 | |||
| 2223 | otem = XCONS (item); | ||
| 2224 | bytestr = XCONS (item)->car; | ||
| 2225 | item = XCONS (item)->cdr; | ||
| 2226 | free_cons (otem); | ||
| 2227 | } | ||
| 2228 | |||
| 2229 | /* Now handle the bytecode slot. */ | ||
| 2230 | ptr[COMPILED_BYTECODE] = read_pure ? Fpurecopy (bytestr) : bytestr; | ||
| 2231 | } | ||
| 2232 | } | ||
| 2233 | ptr[i] = read_pure ? Fpurecopy (item) : item; | ||
| 2157 | otem = XCONS (tem); | 2234 | otem = XCONS (tem); |
| 2158 | tem = Fcdr (tem); | 2235 | tem = Fcdr (tem); |
| 2159 | free_cons (otem); | 2236 | free_cons (otem); |
| @@ -2251,6 +2328,8 @@ read_list (flag, readcharfun) | |||
| 2251 | /* Get a doc string from the file we are loading. | 2328 | /* Get a doc string from the file we are loading. |
| 2252 | If it's in saved_doc_string, get it from there. */ | 2329 | If it's in saved_doc_string, get it from there. */ |
| 2253 | int pos = XINT (XCONS (val)->cdr); | 2330 | int pos = XINT (XCONS (val)->cdr); |
| 2331 | /* Position is negative for user variables. */ | ||
| 2332 | if (pos < 0) pos = -pos; | ||
| 2254 | if (pos >= saved_doc_string_position | 2333 | if (pos >= saved_doc_string_position |
| 2255 | && pos < (saved_doc_string_position | 2334 | && pos < (saved_doc_string_position |
| 2256 | + saved_doc_string_length)) | 2335 | + saved_doc_string_length)) |
| @@ -2282,8 +2361,40 @@ read_list (flag, readcharfun) | |||
| 2282 | return make_string (saved_doc_string + start, | 2361 | return make_string (saved_doc_string + start, |
| 2283 | to - start); | 2362 | to - start); |
| 2284 | } | 2363 | } |
| 2364 | /* Look in prev_saved_doc_string the same way. */ | ||
| 2365 | else if (pos >= prev_saved_doc_string_position | ||
| 2366 | && pos < (prev_saved_doc_string_position | ||
| 2367 | + prev_saved_doc_string_length)) | ||
| 2368 | { | ||
| 2369 | int start = pos - prev_saved_doc_string_position; | ||
| 2370 | int from, to; | ||
| 2371 | |||
| 2372 | /* Process quoting with ^A, | ||
| 2373 | and find the end of the string, | ||
| 2374 | which is marked with ^_ (037). */ | ||
| 2375 | for (from = start, to = start; | ||
| 2376 | prev_saved_doc_string[from] != 037;) | ||
| 2377 | { | ||
| 2378 | int c = prev_saved_doc_string[from++]; | ||
| 2379 | if (c == 1) | ||
| 2380 | { | ||
| 2381 | c = prev_saved_doc_string[from++]; | ||
| 2382 | if (c == 1) | ||
| 2383 | prev_saved_doc_string[to++] = c; | ||
| 2384 | else if (c == '0') | ||
| 2385 | prev_saved_doc_string[to++] = 0; | ||
| 2386 | else if (c == '_') | ||
| 2387 | prev_saved_doc_string[to++] = 037; | ||
| 2388 | } | ||
| 2389 | else | ||
| 2390 | prev_saved_doc_string[to++] = c; | ||
| 2391 | } | ||
| 2392 | |||
| 2393 | return make_string (prev_saved_doc_string + start, | ||
| 2394 | to - start); | ||
| 2395 | } | ||
| 2285 | else | 2396 | else |
| 2286 | return read_doc_string (val); | 2397 | return get_doc_string (val, 0); |
| 2287 | } | 2398 | } |
| 2288 | 2399 | ||
| 2289 | return val; | 2400 | return val; |