diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/doc.c | 14 | ||||
| -rw-r--r-- | src/lread.c | 67 |
3 files changed, 54 insertions, 33 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 420cb5aed63..46f872ba29d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2013-02-08 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * lread.c (skip_dyn_bytes): New function (bug#12598). | ||
| 4 | (read1): Use it. Use getc instead of READCHAR to read bytes. | ||
| 5 | (load_each_byte): Remove. Update users. | ||
| 6 | |||
| 1 | 2013-02-08 Dmitry Antipov <dmantipov@yandex.ru> | 7 | 2013-02-08 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 8 | ||
| 3 | * search.c (scan_buffer): Calculate end byte position just once. | 9 | * search.c (scan_buffer): Calculate end byte position just once. |
| @@ -176,9 +176,9 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) | |||
| 176 | if (space_left <= 0) | 176 | if (space_left <= 0) |
| 177 | { | 177 | { |
| 178 | ptrdiff_t in_buffer = p - get_doc_string_buffer; | 178 | ptrdiff_t in_buffer = p - get_doc_string_buffer; |
| 179 | get_doc_string_buffer = | 179 | get_doc_string_buffer |
| 180 | xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size, | 180 | = xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size, |
| 181 | 16 * 1024, -1, 1); | 181 | 16 * 1024, -1, 1); |
| 182 | p = get_doc_string_buffer + in_buffer; | 182 | p = get_doc_string_buffer + in_buffer; |
| 183 | space_left = (get_doc_string_buffer_size - 1 | 183 | space_left = (get_doc_string_buffer_size - 1 |
| 184 | - (p - get_doc_string_buffer)); | 184 | - (p - get_doc_string_buffer)); |
| @@ -279,10 +279,10 @@ Invalid data in documentation file -- %c followed by code %03o", | |||
| 279 | else | 279 | else |
| 280 | { | 280 | { |
| 281 | /* The data determines whether the string is multibyte. */ | 281 | /* The data determines whether the string is multibyte. */ |
| 282 | ptrdiff_t nchars = | 282 | ptrdiff_t nchars |
| 283 | multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer | 283 | = multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer |
| 284 | + offset), | 284 | + offset), |
| 285 | to - (get_doc_string_buffer + offset)); | 285 | to - (get_doc_string_buffer + offset)); |
| 286 | return make_string_from_bytes (get_doc_string_buffer + offset, | 286 | return make_string_from_bytes (get_doc_string_buffer + offset, |
| 287 | nchars, | 287 | nchars, |
| 288 | to - (get_doc_string_buffer + offset)); | 288 | to - (get_doc_string_buffer + offset)); |
diff --git a/src/lread.c b/src/lread.c index 09eccb0fb30..c62c62a5e5a 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -96,11 +96,6 @@ static Lisp_Object Qload_in_progress; | |||
| 96 | It must be set to nil before all top-level calls to read0. */ | 96 | It must be set to nil before all top-level calls to read0. */ |
| 97 | static Lisp_Object read_objects; | 97 | static Lisp_Object read_objects; |
| 98 | 98 | ||
| 99 | /* True means READCHAR should read bytes one by one (not character) | ||
| 100 | when READCHARFUN is Qget_file_char or Qget_emacs_mule_file_char. | ||
| 101 | This is set by read1 temporarily while handling #@NUMBER. */ | ||
| 102 | static bool load_each_byte; | ||
| 103 | |||
| 104 | /* List of descriptors now open for Fload. */ | 99 | /* List of descriptors now open for Fload. */ |
| 105 | static Lisp_Object load_descriptor_list; | 100 | static Lisp_Object load_descriptor_list; |
| 106 | 101 | ||
| @@ -328,7 +323,7 @@ readchar (Lisp_Object readcharfun, bool *multibyte) | |||
| 328 | return c; | 323 | return c; |
| 329 | } | 324 | } |
| 330 | c = (*readbyte) (-1, readcharfun); | 325 | c = (*readbyte) (-1, readcharfun); |
| 331 | if (c < 0 || load_each_byte) | 326 | if (c < 0) |
| 332 | return c; | 327 | return c; |
| 333 | if (multibyte) | 328 | if (multibyte) |
| 334 | *multibyte = 1; | 329 | *multibyte = 1; |
| @@ -353,6 +348,30 @@ readchar (Lisp_Object readcharfun, bool *multibyte) | |||
| 353 | return STRING_CHAR (buf); | 348 | return STRING_CHAR (buf); |
| 354 | } | 349 | } |
| 355 | 350 | ||
| 351 | static void | ||
| 352 | skip_dyn_bytes (Lisp_Object readcharfun, ptrdiff_t n) | ||
| 353 | { | ||
| 354 | if (EQ (readcharfun, Qget_file_char) | ||
| 355 | || EQ (readcharfun, Qget_emacs_mule_file_char)) | ||
| 356 | { | ||
| 357 | block_input (); /* FIXME: Not sure if it's needed. */ | ||
| 358 | fseek (instream, n, SEEK_CUR); | ||
| 359 | unblock_input (); | ||
| 360 | } | ||
| 361 | else | ||
| 362 | { /* We're not reading directly from a file. In that case, it's difficult | ||
| 363 | to reliably count bytes, since these are usually meant for the file's | ||
| 364 | encoding, whereas we're now typically in the internal encoding. | ||
| 365 | But luckily, skip_dyn_bytes is used to skip over a single | ||
| 366 | dynamic-docstring (or dynamic byte-code) which is always quoted such | ||
| 367 | that \037 is the final char. */ | ||
| 368 | int c; | ||
| 369 | do { | ||
| 370 | c = READCHAR; | ||
| 371 | } while (c >= 0 && c != '\037'); | ||
| 372 | } | ||
| 373 | } | ||
| 374 | |||
| 356 | /* Unread the character C in the way appropriate for the stream READCHARFUN. | 375 | /* Unread the character C in the way appropriate for the stream READCHARFUN. |
| 357 | If the stream is a user function, call it with the char as argument. */ | 376 | If the stream is a user function, call it with the char as argument. */ |
| 358 | 377 | ||
| @@ -407,14 +426,7 @@ unreadchar (Lisp_Object readcharfun, int c) | |||
| 407 | else if (EQ (readcharfun, Qget_file_char) | 426 | else if (EQ (readcharfun, Qget_file_char) |
| 408 | || EQ (readcharfun, Qget_emacs_mule_file_char)) | 427 | || EQ (readcharfun, Qget_emacs_mule_file_char)) |
| 409 | { | 428 | { |
| 410 | if (load_each_byte) | 429 | unread_char = c; |
| 411 | { | ||
| 412 | block_input (); | ||
| 413 | ungetc (c, instream); | ||
| 414 | unblock_input (); | ||
| 415 | } | ||
| 416 | else | ||
| 417 | unread_char = c; | ||
| 418 | } | 430 | } |
| 419 | else | 431 | else |
| 420 | call1 (readcharfun, make_number (c)); | 432 | call1 (readcharfun, make_number (c)); |
| @@ -2388,7 +2400,6 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2388 | bool multibyte; | 2400 | bool multibyte; |
| 2389 | 2401 | ||
| 2390 | *pch = 0; | 2402 | *pch = 0; |
| 2391 | load_each_byte = 0; | ||
| 2392 | 2403 | ||
| 2393 | retry: | 2404 | retry: |
| 2394 | 2405 | ||
| @@ -2598,7 +2609,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2598 | return tmp; | 2609 | return tmp; |
| 2599 | } | 2610 | } |
| 2600 | 2611 | ||
| 2601 | /* #@NUMBER is used to skip NUMBER following characters. | 2612 | /* #@NUMBER is used to skip NUMBER following bytes. |
| 2602 | That's used in .elc files to skip over doc strings | 2613 | That's used in .elc files to skip over doc strings |
| 2603 | and function definitions. */ | 2614 | and function definitions. */ |
| 2604 | if (c == '@') | 2615 | if (c == '@') |
| @@ -2606,7 +2617,6 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2606 | enum { extra = 100 }; | 2617 | enum { extra = 100 }; |
| 2607 | ptrdiff_t i, nskip = 0; | 2618 | ptrdiff_t i, nskip = 0; |
| 2608 | 2619 | ||
| 2609 | load_each_byte = 1; | ||
| 2610 | /* Read a decimal integer. */ | 2620 | /* Read a decimal integer. */ |
| 2611 | while ((c = READCHAR) >= 0 | 2621 | while ((c = READCHAR) >= 0 |
| 2612 | && c >= '0' && c <= '9') | 2622 | && c >= '0' && c <= '9') |
| @@ -2616,8 +2626,15 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2616 | nskip *= 10; | 2626 | nskip *= 10; |
| 2617 | nskip += c - '0'; | 2627 | nskip += c - '0'; |
| 2618 | } | 2628 | } |
| 2619 | UNREAD (c); | 2629 | if (nskip > 0) |
| 2620 | 2630 | /* We can't use UNREAD here, because in the code below we side-step | |
| 2631 | READCHAR. Instead, assume the first char after #@NNN occupies | ||
| 2632 | a single byte, which is the case normally since it's just | ||
| 2633 | a space. */ | ||
| 2634 | nskip--; | ||
| 2635 | else | ||
| 2636 | UNREAD (c); | ||
| 2637 | |||
| 2621 | if (load_force_doc_strings | 2638 | if (load_force_doc_strings |
| 2622 | && (EQ (readcharfun, Qget_file_char) | 2639 | && (EQ (readcharfun, Qget_file_char) |
| 2623 | || EQ (readcharfun, Qget_emacs_mule_file_char))) | 2640 | || EQ (readcharfun, Qget_emacs_mule_file_char))) |
| @@ -2659,19 +2676,17 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) | |||
| 2659 | saved_doc_string_position = file_tell (instream); | 2676 | saved_doc_string_position = file_tell (instream); |
| 2660 | 2677 | ||
| 2661 | /* Copy that many characters into saved_doc_string. */ | 2678 | /* Copy that many characters into saved_doc_string. */ |
| 2679 | block_input (); | ||
| 2662 | for (i = 0; i < nskip && c >= 0; i++) | 2680 | for (i = 0; i < nskip && c >= 0; i++) |
| 2663 | saved_doc_string[i] = c = READCHAR; | 2681 | saved_doc_string[i] = c = getc (instream); |
| 2682 | unblock_input (); | ||
| 2664 | 2683 | ||
| 2665 | saved_doc_string_length = i; | 2684 | saved_doc_string_length = i; |
| 2666 | } | 2685 | } |
| 2667 | else | 2686 | else |
| 2668 | { | 2687 | /* Skip that many bytes. */ |
| 2669 | /* Skip that many characters. */ | 2688 | skip_dyn_bytes (readcharfun, nskip); |
| 2670 | for (i = 0; i < nskip && c >= 0; i++) | ||
| 2671 | c = READCHAR; | ||
| 2672 | } | ||
| 2673 | 2689 | ||
| 2674 | load_each_byte = 0; | ||
| 2675 | goto retry; | 2690 | goto retry; |
| 2676 | } | 2691 | } |
| 2677 | if (c == '!') | 2692 | if (c == '!') |