if (space_left <= 0)
{
ptrdiff_t in_buffer = p - get_doc_string_buffer;
- get_doc_string_buffer =
- xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size,
- 16 * 1024, -1, 1);
+ get_doc_string_buffer
+ = xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size,
+ 16 * 1024, -1, 1);
p = get_doc_string_buffer + in_buffer;
space_left = (get_doc_string_buffer_size - 1
- (p - get_doc_string_buffer));
else
{
/* The data determines whether the string is multibyte. */
- ptrdiff_t nchars =
- multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer
- + offset),
- to - (get_doc_string_buffer + offset));
+ ptrdiff_t nchars
+ = multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer
+ + offset),
+ to - (get_doc_string_buffer + offset));
return make_string_from_bytes (get_doc_string_buffer + offset,
nchars,
to - (get_doc_string_buffer + offset));
It must be set to nil before all top-level calls to read0. */
static Lisp_Object read_objects;
-/* True means READCHAR should read bytes one by one (not character)
- when READCHARFUN is Qget_file_char or Qget_emacs_mule_file_char.
- This is set by read1 temporarily while handling #@NUMBER. */
-static bool load_each_byte;
-
/* List of descriptors now open for Fload. */
static Lisp_Object load_descriptor_list;
return c;
}
c = (*readbyte) (-1, readcharfun);
- if (c < 0 || load_each_byte)
+ if (c < 0)
return c;
if (multibyte)
*multibyte = 1;
return STRING_CHAR (buf);
}
+static void
+skip_dyn_bytes (Lisp_Object readcharfun, ptrdiff_t n)
+{
+ if (EQ (readcharfun, Qget_file_char)
+ || EQ (readcharfun, Qget_emacs_mule_file_char))
+ {
+ block_input (); /* FIXME: Not sure if it's needed. */
+ fseek (instream, n, SEEK_CUR);
+ unblock_input ();
+ }
+ else
+ { /* We're not reading directly from a file. In that case, it's difficult
+ to reliably count bytes, since these are usually meant for the file's
+ encoding, whereas we're now typically in the internal encoding.
+ But luckily, skip_dyn_bytes is used to skip over a single
+ dynamic-docstring (or dynamic byte-code) which is always quoted such
+ that \037 is the final char. */
+ int c;
+ do {
+ c = READCHAR;
+ } while (c >= 0 && c != '\037');
+ }
+}
+
/* Unread the character C in the way appropriate for the stream READCHARFUN.
If the stream is a user function, call it with the char as argument. */
else if (EQ (readcharfun, Qget_file_char)
|| EQ (readcharfun, Qget_emacs_mule_file_char))
{
- if (load_each_byte)
- {
- block_input ();
- ungetc (c, instream);
- unblock_input ();
- }
- else
- unread_char = c;
+ unread_char = c;
}
else
call1 (readcharfun, make_number (c));
bool multibyte;
*pch = 0;
- load_each_byte = 0;
retry:
return tmp;
}
- /* #@NUMBER is used to skip NUMBER following characters.
+ /* #@NUMBER is used to skip NUMBER following bytes.
That's used in .elc files to skip over doc strings
and function definitions. */
if (c == '@')
enum { extra = 100 };
ptrdiff_t i, nskip = 0;
- load_each_byte = 1;
/* Read a decimal integer. */
while ((c = READCHAR) >= 0
&& c >= '0' && c <= '9')
nskip *= 10;
nskip += c - '0';
}
- UNREAD (c);
-
+ if (nskip > 0)
+ /* We can't use UNREAD here, because in the code below we side-step
+ READCHAR. Instead, assume the first char after #@NNN occupies
+ a single byte, which is the case normally since it's just
+ a space. */
+ nskip--;
+ else
+ UNREAD (c);
+
if (load_force_doc_strings
&& (EQ (readcharfun, Qget_file_char)
|| EQ (readcharfun, Qget_emacs_mule_file_char)))
saved_doc_string_position = file_tell (instream);
/* Copy that many characters into saved_doc_string. */
+ block_input ();
for (i = 0; i < nskip && c >= 0; i++)
- saved_doc_string[i] = c = READCHAR;
+ saved_doc_string[i] = c = getc (instream);
+ unblock_input ();
saved_doc_string_length = i;
}
else
- {
- /* Skip that many characters. */
- for (i = 0; i < nskip && c >= 0; i++)
- c = READCHAR;
- }
+ /* Skip that many bytes. */
+ skip_dyn_bytes (readcharfun, nskip);
- load_each_byte = 0;
goto retry;
}
if (c == '!')