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.
This commit is contained in:
parent
05b44e9027
commit
c15cfd1faa
1 changed files with 124 additions and 13 deletions
137
src/lread.c
137
src/lread.c
|
@ -142,8 +142,7 @@ static int read_from_string_limit;
|
|||
that `readchar' has already advanced over. */
|
||||
static int readchar_backlog;
|
||||
|
||||
/* This contains the last string skipped with #@, but only on some systems.
|
||||
On other systems we can't put the string here. */
|
||||
/* This contains the last string skipped with #@. */
|
||||
static char *saved_doc_string;
|
||||
/* Length of buffer allocated in saved_doc_string. */
|
||||
static int saved_doc_string_size;
|
||||
|
@ -152,6 +151,17 @@ static int saved_doc_string_length;
|
|||
/* This is the file position that string came from. */
|
||||
static int saved_doc_string_position;
|
||||
|
||||
/* This contains the previous string skipped with #@.
|
||||
We copy it from saved_doc_string when a new string
|
||||
is put in saved_doc_string. */
|
||||
static char *prev_saved_doc_string;
|
||||
/* Length of buffer allocated in prev_saved_doc_string. */
|
||||
static int prev_saved_doc_string_size;
|
||||
/* Length of actual data in prev_saved_doc_string. */
|
||||
static int prev_saved_doc_string_length;
|
||||
/* This is the file position that string came from. */
|
||||
static int prev_saved_doc_string_position;
|
||||
|
||||
/* Nonzero means inside a new-style backquote
|
||||
with no surrounding parentheses.
|
||||
Fread initializes this to zero, so we need not specbind it
|
||||
|
@ -703,6 +713,11 @@ Return t if file exists.")
|
|||
saved_doc_string = 0;
|
||||
saved_doc_string_size = 0;
|
||||
|
||||
if (prev_saved_doc_string)
|
||||
free (prev_saved_doc_string);
|
||||
prev_saved_doc_string = 0;
|
||||
prev_saved_doc_string_size = 0;
|
||||
|
||||
if (!noninteractive && NILP (nomessage))
|
||||
{
|
||||
if (!compiled)
|
||||
|
@ -1519,7 +1534,7 @@ read1 (readcharfun, pch, first_in_list)
|
|||
return read_list (0, readcharfun);
|
||||
|
||||
case '[':
|
||||
return read_vector (readcharfun);
|
||||
return read_vector (readcharfun, 0);
|
||||
|
||||
case ')':
|
||||
case ']':
|
||||
|
@ -1536,7 +1551,7 @@ read1 (readcharfun, pch, first_in_list)
|
|||
if (c == '[')
|
||||
{
|
||||
Lisp_Object tmp;
|
||||
tmp = read_vector (readcharfun);
|
||||
tmp = read_vector (readcharfun, 0);
|
||||
if (XVECTOR (tmp)->size < CHAR_TABLE_STANDARD_SLOTS
|
||||
|| XVECTOR (tmp)->size > CHAR_TABLE_STANDARD_SLOTS + 10)
|
||||
error ("Invalid size char-table");
|
||||
|
@ -1550,7 +1565,7 @@ read1 (readcharfun, pch, first_in_list)
|
|||
if (c == '[')
|
||||
{
|
||||
Lisp_Object tmp;
|
||||
tmp = read_vector (readcharfun);
|
||||
tmp = read_vector (readcharfun, 0);
|
||||
if (XVECTOR (tmp)->size != SUB_CHAR_TABLE_STANDARD_SLOTS)
|
||||
error ("Invalid size char-table");
|
||||
XSETCHAR_TABLE (tmp, XCHAR_TABLE (tmp));
|
||||
|
@ -1601,7 +1616,7 @@ read1 (readcharfun, pch, first_in_list)
|
|||
/* Accept compiled functions at read-time so that we don't have to
|
||||
build them using function calls. */
|
||||
Lisp_Object tmp;
|
||||
tmp = read_vector (readcharfun);
|
||||
tmp = read_vector (readcharfun, 1);
|
||||
return Fmake_byte_code (XVECTOR (tmp)->size,
|
||||
XVECTOR (tmp)->contents);
|
||||
}
|
||||
|
@ -1656,12 +1671,31 @@ read1 (readcharfun, pch, first_in_list)
|
|||
if (c >= 0)
|
||||
UNREAD (c);
|
||||
|
||||
#ifndef WINDOWSNT /* I don't know if filepos works right on Windoze. */
|
||||
if (load_force_doc_strings && EQ (readcharfun, Qget_file_char))
|
||||
{
|
||||
/* If we are supposed to force doc strings into core right now,
|
||||
record the last string that we skipped,
|
||||
and record where in the file it comes from. */
|
||||
|
||||
/* But first exchange saved_doc_string
|
||||
with prev_saved_doc_string, so we save two strings. */
|
||||
{
|
||||
char *temp = saved_doc_string;
|
||||
int temp_size = saved_doc_string_size;
|
||||
int temp_pos = saved_doc_string_position;
|
||||
int temp_len = saved_doc_string_length;
|
||||
|
||||
saved_doc_string = prev_saved_doc_string;
|
||||
saved_doc_string_size = prev_saved_doc_string_size;
|
||||
saved_doc_string_position = prev_saved_doc_string_position;
|
||||
saved_doc_string_length = prev_saved_doc_string_length;
|
||||
|
||||
prev_saved_doc_string = temp;
|
||||
prev_saved_doc_string_size = temp_size;
|
||||
prev_saved_doc_string_position = temp_pos;
|
||||
prev_saved_doc_string_length = temp_len;
|
||||
}
|
||||
|
||||
if (saved_doc_string_size == 0)
|
||||
{
|
||||
saved_doc_string_size = nskip + 100;
|
||||
|
@ -1683,7 +1717,6 @@ read1 (readcharfun, pch, first_in_list)
|
|||
saved_doc_string_length = i;
|
||||
}
|
||||
else
|
||||
#endif /* not WINDOWSNT */
|
||||
{
|
||||
/* Skip that many characters. */
|
||||
for (i = 0; i < nskip && c >= 0; i++)
|
||||
|
@ -2134,13 +2167,14 @@ isfloat_string (cp)
|
|||
#endif /* LISP_FLOAT_TYPE */
|
||||
|
||||
static Lisp_Object
|
||||
read_vector (readcharfun)
|
||||
read_vector (readcharfun, bytecodeflag)
|
||||
Lisp_Object readcharfun;
|
||||
int bytecodeflag;
|
||||
{
|
||||
register int i;
|
||||
register int size;
|
||||
register Lisp_Object *ptr;
|
||||
register Lisp_Object tem, vector;
|
||||
register Lisp_Object tem, item, vector;
|
||||
register struct Lisp_Cons *otem;
|
||||
Lisp_Object len;
|
||||
|
||||
|
@ -2148,12 +2182,55 @@ read_vector (readcharfun)
|
|||
len = Flength (tem);
|
||||
vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil));
|
||||
|
||||
|
||||
size = XVECTOR (vector)->size;
|
||||
ptr = XVECTOR (vector)->contents;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
ptr[i] = read_pure ? Fpurecopy (Fcar (tem)) : Fcar (tem);
|
||||
item = Fcar (tem);
|
||||
/* If `load-force-doc-strings' is t when reading a lazily-loaded
|
||||
bytecode object, the docstring containing the bytecode and
|
||||
constants values must be treated as unibyte and passed to
|
||||
Fread, to get the actual bytecode string and constants vector. */
|
||||
if (bytecodeflag && load_force_doc_strings)
|
||||
{
|
||||
if (i == COMPILED_BYTECODE)
|
||||
{
|
||||
if (!STRINGP (item))
|
||||
error ("invalid byte code");
|
||||
|
||||
/* Delay handling the bytecode slot until we know whether
|
||||
it is lazily-loaded (we can tell by whether the
|
||||
constants slot is nil). */
|
||||
ptr[COMPILED_CONSTANTS] = item;
|
||||
item = Qnil;
|
||||
}
|
||||
else if (i == COMPILED_CONSTANTS)
|
||||
{
|
||||
Lisp_Object bytestr = ptr[COMPILED_CONSTANTS];
|
||||
|
||||
if (NILP (item))
|
||||
{
|
||||
/* Coerce string to unibyte (like string-as-unibyte,
|
||||
but without generating extra garbage and
|
||||
guaranteeing no change in the contents). */
|
||||
XSTRING (bytestr)->size = STRING_BYTES (XSTRING (bytestr));
|
||||
SET_STRING_BYTES (XSTRING (bytestr), -1);
|
||||
|
||||
item = Fread (bytestr);
|
||||
if (!CONSP (item))
|
||||
error ("invalid byte code");
|
||||
|
||||
otem = XCONS (item);
|
||||
bytestr = XCONS (item)->car;
|
||||
item = XCONS (item)->cdr;
|
||||
free_cons (otem);
|
||||
}
|
||||
|
||||
/* Now handle the bytecode slot. */
|
||||
ptr[COMPILED_BYTECODE] = read_pure ? Fpurecopy (bytestr) : bytestr;
|
||||
}
|
||||
}
|
||||
ptr[i] = read_pure ? Fpurecopy (item) : item;
|
||||
otem = XCONS (tem);
|
||||
tem = Fcdr (tem);
|
||||
free_cons (otem);
|
||||
|
@ -2251,6 +2328,8 @@ read_list (flag, readcharfun)
|
|||
/* Get a doc string from the file we are loading.
|
||||
If it's in saved_doc_string, get it from there. */
|
||||
int pos = XINT (XCONS (val)->cdr);
|
||||
/* Position is negative for user variables. */
|
||||
if (pos < 0) pos = -pos;
|
||||
if (pos >= saved_doc_string_position
|
||||
&& pos < (saved_doc_string_position
|
||||
+ saved_doc_string_length))
|
||||
|
@ -2282,8 +2361,40 @@ read_list (flag, readcharfun)
|
|||
return make_string (saved_doc_string + start,
|
||||
to - start);
|
||||
}
|
||||
/* Look in prev_saved_doc_string the same way. */
|
||||
else if (pos >= prev_saved_doc_string_position
|
||||
&& pos < (prev_saved_doc_string_position
|
||||
+ prev_saved_doc_string_length))
|
||||
{
|
||||
int start = pos - prev_saved_doc_string_position;
|
||||
int from, to;
|
||||
|
||||
/* Process quoting with ^A,
|
||||
and find the end of the string,
|
||||
which is marked with ^_ (037). */
|
||||
for (from = start, to = start;
|
||||
prev_saved_doc_string[from] != 037;)
|
||||
{
|
||||
int c = prev_saved_doc_string[from++];
|
||||
if (c == 1)
|
||||
{
|
||||
c = prev_saved_doc_string[from++];
|
||||
if (c == 1)
|
||||
prev_saved_doc_string[to++] = c;
|
||||
else if (c == '0')
|
||||
prev_saved_doc_string[to++] = 0;
|
||||
else if (c == '_')
|
||||
prev_saved_doc_string[to++] = 037;
|
||||
}
|
||||
else
|
||||
prev_saved_doc_string[to++] = c;
|
||||
}
|
||||
|
||||
return make_string (prev_saved_doc_string + start,
|
||||
to - start);
|
||||
}
|
||||
else
|
||||
return read_doc_string (val);
|
||||
return get_doc_string (val, 0);
|
||||
}
|
||||
|
||||
return val;
|
||||
|
|
Loading…
Add table
Reference in a new issue