diff options
| author | Colin Walters | 2002-05-28 16:24:55 +0000 |
|---|---|---|
| committer | Colin Walters | 2002-05-28 16:24:55 +0000 |
| commit | abb13b09f457bbf32e3a75d9cabd66d2d8df494d (patch) | |
| tree | 95da1f359cb56600b74b3a3e43bbe7de4824f238 /src/lread.c | |
| parent | b44ec8e346cd5128bf6a31d902beea5ca6414e8e (diff) | |
| download | emacs-abb13b09f457bbf32e3a75d9cabd66d2d8df494d.tar.gz emacs-abb13b09f457bbf32e3a75d9cabd66d2d8df494d.zip | |
lread.c (readchar_count): New variable.
(readchar): Increment it.
(unreadchar): Decrement it.
(read_multibyte): Decrement it.
(Vread_with_symbol_positions): New variable.
(Vread_symbol_positions_list): New variable.
(read_internal_start): New function, created from Fread and
Fread_from_string. Handle Vread_symbol_positions_list and
Vread_with_symbol_positions.
(readevalloop, Fread, Fread_from_string): Use it.
(read1): Use readchar_count to add symbol positions to
Vread_symbol_positions_list if Vread_with_symbol_positions is
non-nil.
(syms_of_lread): DEFVAR_LISP and initialize them.
Diffstat (limited to 'src/lread.c')
| -rw-r--r-- | src/lread.c | 192 |
1 files changed, 141 insertions, 51 deletions
diff --git a/src/lread.c b/src/lread.c index 03ced7c4323..4d275a6877d 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -133,6 +133,13 @@ Lisp_Object Vload_source_file_function; | |||
| 133 | /* List of all DEFVAR_BOOL variables. Used by the byte optimizer. */ | 133 | /* List of all DEFVAR_BOOL variables. Used by the byte optimizer. */ |
| 134 | Lisp_Object Vbyte_boolean_vars; | 134 | Lisp_Object Vbyte_boolean_vars; |
| 135 | 135 | ||
| 136 | /* Whether or not to add a `read-positions' property to symbols | ||
| 137 | read. */ | ||
| 138 | Lisp_Object Vread_with_symbol_positions; | ||
| 139 | |||
| 140 | /* List of (SYMBOL . POSITION) accumulated so far. */ | ||
| 141 | Lisp_Object Vread_symbol_positions_list; | ||
| 142 | |||
| 136 | /* List of descriptors now open for Fload. */ | 143 | /* List of descriptors now open for Fload. */ |
| 137 | static Lisp_Object load_descriptor_list; | 144 | static Lisp_Object load_descriptor_list; |
| 138 | 145 | ||
| @@ -150,6 +157,9 @@ static int read_from_string_limit; | |||
| 150 | /* Number of bytes left to read in the buffer character | 157 | /* Number of bytes left to read in the buffer character |
| 151 | that `readchar' has already advanced over. */ | 158 | that `readchar' has already advanced over. */ |
| 152 | static int readchar_backlog; | 159 | static int readchar_backlog; |
| 160 | /* Number of characters read in the current call to Fread or | ||
| 161 | Fread_from_string. */ | ||
| 162 | static int readchar_count; | ||
| 153 | 163 | ||
| 154 | /* This contains the last string skipped with #@. */ | 164 | /* This contains the last string skipped with #@. */ |
| 155 | static char *saved_doc_string; | 165 | static char *saved_doc_string; |
| @@ -202,8 +212,14 @@ static Lisp_Object load_descriptor_unwind P_ ((Lisp_Object)); | |||
| 202 | Write READCHAR to read a character, | 212 | Write READCHAR to read a character, |
| 203 | UNREAD(c) to unread c to be read again. | 213 | UNREAD(c) to unread c to be read again. |
| 204 | 214 | ||
| 205 | These macros actually read/unread a byte code, multibyte characters | 215 | The READCHAR and UNREAD macros are meant for reading/unreading a |
| 206 | are not handled here. The caller should manage them if necessary. | 216 | byte code; they do not handle multibyte characters. The caller |
| 217 | should manage them if necessary. | ||
| 218 | |||
| 219 | [ Actually that seems to be a lie; READCHAR will definitely read | ||
| 220 | multibyte characters from buffer sources, at least. Is the | ||
| 221 | comment just out of date? | ||
| 222 | -- Colin Walters <walters@gnu.org>, 22 May 2002 16:36:50 -0400 ] | ||
| 207 | */ | 223 | */ |
| 208 | 224 | ||
| 209 | #define READCHAR readchar (readcharfun) | 225 | #define READCHAR readchar (readcharfun) |
| @@ -216,6 +232,8 @@ readchar (readcharfun) | |||
| 216 | Lisp_Object tem; | 232 | Lisp_Object tem; |
| 217 | register int c; | 233 | register int c; |
| 218 | 234 | ||
| 235 | readchar_count++; | ||
| 236 | |||
| 219 | if (BUFFERP (readcharfun)) | 237 | if (BUFFERP (readcharfun)) |
| 220 | { | 238 | { |
| 221 | register struct buffer *inbuffer = XBUFFER (readcharfun); | 239 | register struct buffer *inbuffer = XBUFFER (readcharfun); |
| @@ -335,6 +353,7 @@ unreadchar (readcharfun, c) | |||
| 335 | Lisp_Object readcharfun; | 353 | Lisp_Object readcharfun; |
| 336 | int c; | 354 | int c; |
| 337 | { | 355 | { |
| 356 | readchar_count--; | ||
| 338 | if (c == -1) | 357 | if (c == -1) |
| 339 | /* Don't back up the pointer if we're unreading the end-of-input mark, | 358 | /* Don't back up the pointer if we're unreading the end-of-input mark, |
| 340 | since readchar didn't advance it when we read it. */ | 359 | since readchar didn't advance it when we read it. */ |
| @@ -389,10 +408,20 @@ unreadchar (readcharfun, c) | |||
| 389 | call1 (readcharfun, make_number (c)); | 408 | call1 (readcharfun, make_number (c)); |
| 390 | } | 409 | } |
| 391 | 410 | ||
| 392 | static Lisp_Object read0 (), read1 (), read_list (), read_vector (); | 411 | static Lisp_Object read_internal_start P_ ((Lisp_Object, Lisp_Object, |
| 393 | static int read_multibyte (); | 412 | Lisp_Object)); |
| 394 | static Lisp_Object substitute_object_recurse (); | 413 | static Lisp_Object read0 P_ ((Lisp_Object)); |
| 395 | static void substitute_object_in_subtree (), substitute_in_interval (); | 414 | static Lisp_Object read1 P_ ((Lisp_Object, int *, int)); |
| 415 | |||
| 416 | static Lisp_Object read_list P_ ((int, Lisp_Object)); | ||
| 417 | static Lisp_Object read_vector P_ ((Lisp_Object, int)); | ||
| 418 | static int read_multibyte P_ ((int, Lisp_Object)); | ||
| 419 | |||
| 420 | static Lisp_Object substitute_object_recurse P_ ((Lisp_Object, Lisp_Object, | ||
| 421 | Lisp_Object)); | ||
| 422 | static void substitute_object_in_subtree P_ ((Lisp_Object, | ||
| 423 | Lisp_Object)); | ||
| 424 | static void substitute_in_interval P_ ((INTERVAL, Lisp_Object)); | ||
| 396 | 425 | ||
| 397 | 426 | ||
| 398 | /* Get a character from the tty. */ | 427 | /* Get a character from the tty. */ |
| @@ -1310,7 +1339,7 @@ readevalloop (readcharfun, stream, sourcename, evalfun, printflag, unibyte, read | |||
| 1310 | else if (! NILP (Vload_read_function)) | 1339 | else if (! NILP (Vload_read_function)) |
| 1311 | val = call1 (Vload_read_function, readcharfun); | 1340 | val = call1 (Vload_read_function, readcharfun); |
| 1312 | else | 1341 | else |
| 1313 | val = read0 (readcharfun); | 1342 | val = read_internal_start (readcharfun, Qnil, Qnil); |
| 1314 | } | 1343 | } |
| 1315 | 1344 | ||
| 1316 | val = (*evalfun) (val); | 1345 | val = (*evalfun) (val); |
| @@ -1432,23 +1461,15 @@ STREAM or the value of `standard-input' may be: | |||
| 1432 | Lisp_Object stream; | 1461 | Lisp_Object stream; |
| 1433 | { | 1462 | { |
| 1434 | extern Lisp_Object Fread_minibuffer (); | 1463 | extern Lisp_Object Fread_minibuffer (); |
| 1435 | 1464 | Lisp_Object tem; | |
| 1436 | if (NILP (stream)) | 1465 | if (NILP (stream)) |
| 1437 | stream = Vstandard_input; | 1466 | stream = Vstandard_input; |
| 1438 | if (EQ (stream, Qt)) | 1467 | if (EQ (stream, Qt)) |
| 1439 | stream = Qread_char; | 1468 | stream = Qread_char; |
| 1440 | |||
| 1441 | readchar_backlog = -1; | ||
| 1442 | new_backquote_flag = 0; | ||
| 1443 | read_objects = Qnil; | ||
| 1444 | |||
| 1445 | if (EQ (stream, Qread_char)) | 1469 | if (EQ (stream, Qread_char)) |
| 1446 | return Fread_minibuffer (build_string ("Lisp expression: "), Qnil); | 1470 | return Fread_minibuffer (build_string ("Lisp expression: "), Qnil); |
| 1447 | 1471 | ||
| 1448 | if (STRINGP (stream)) | 1472 | return read_internal_start (stream, Qnil, Qnil); |
| 1449 | return Fcar (Fread_from_string (stream, Qnil, Qnil)); | ||
| 1450 | |||
| 1451 | return read0 (stream); | ||
| 1452 | } | 1473 | } |
| 1453 | 1474 | ||
| 1454 | DEFUN ("read-from-string", Fread_from_string, Sread_from_string, 1, 3, 0, | 1475 | DEFUN ("read-from-string", Fread_from_string, Sread_from_string, 1, 3, 0, |
| @@ -1459,40 +1480,61 @@ START and END optionally delimit a substring of STRING from which to read; | |||
| 1459 | (string, start, end) | 1480 | (string, start, end) |
| 1460 | Lisp_Object string, start, end; | 1481 | Lisp_Object string, start, end; |
| 1461 | { | 1482 | { |
| 1462 | int startval, endval; | ||
| 1463 | Lisp_Object tem; | ||
| 1464 | |||
| 1465 | CHECK_STRING (string); | 1483 | CHECK_STRING (string); |
| 1484 | return Fcons (read_internal_start (string, start, end), | ||
| 1485 | make_number (read_from_string_index)); | ||
| 1486 | } | ||
| 1466 | 1487 | ||
| 1467 | if (NILP (end)) | 1488 | /* Function to set up the global context we need in toplevel read |
| 1468 | endval = XSTRING (string)->size; | 1489 | calls. */ |
| 1469 | else | 1490 | static Lisp_Object |
| 1470 | { | 1491 | read_internal_start (stream, start, end) |
| 1471 | CHECK_NUMBER (end); | 1492 | Lisp_Object stream; |
| 1472 | endval = XINT (end); | 1493 | Lisp_Object start; /* Only used when stream is a string. */ |
| 1473 | if (endval < 0 || endval > XSTRING (string)->size) | 1494 | Lisp_Object end; /* Only used when stream is a string. */ |
| 1474 | args_out_of_range (string, end); | 1495 | { |
| 1475 | } | 1496 | Lisp_Object retval; |
| 1476 | |||
| 1477 | if (NILP (start)) | ||
| 1478 | startval = 0; | ||
| 1479 | else | ||
| 1480 | { | ||
| 1481 | CHECK_NUMBER (start); | ||
| 1482 | startval = XINT (start); | ||
| 1483 | if (startval < 0 || startval > endval) | ||
| 1484 | args_out_of_range (string, start); | ||
| 1485 | } | ||
| 1486 | |||
| 1487 | read_from_string_index = startval; | ||
| 1488 | read_from_string_index_byte = string_char_to_byte (string, startval); | ||
| 1489 | read_from_string_limit = endval; | ||
| 1490 | 1497 | ||
| 1498 | readchar_backlog = -1; | ||
| 1499 | readchar_count = 0; | ||
| 1491 | new_backquote_flag = 0; | 1500 | new_backquote_flag = 0; |
| 1492 | read_objects = Qnil; | 1501 | read_objects = Qnil; |
| 1502 | if (EQ (Vread_with_symbol_positions, Qt) | ||
| 1503 | || EQ (Vread_with_symbol_positions, stream)) | ||
| 1504 | Vread_symbol_positions_list = Qnil; | ||
| 1505 | |||
| 1506 | if (STRINGP (stream)) | ||
| 1507 | { | ||
| 1508 | int startval, endval; | ||
| 1509 | if (NILP (end)) | ||
| 1510 | endval = XSTRING (stream)->size; | ||
| 1511 | else | ||
| 1512 | { | ||
| 1513 | CHECK_NUMBER (end); | ||
| 1514 | endval = XINT (end); | ||
| 1515 | if (endval < 0 || endval > XSTRING (stream)->size) | ||
| 1516 | args_out_of_range (stream, end); | ||
| 1517 | } | ||
| 1493 | 1518 | ||
| 1494 | tem = read0 (string); | 1519 | if (NILP (start)) |
| 1495 | return Fcons (tem, make_number (read_from_string_index)); | 1520 | startval = 0; |
| 1521 | else | ||
| 1522 | { | ||
| 1523 | CHECK_NUMBER (start); | ||
| 1524 | startval = XINT (start); | ||
| 1525 | if (startval < 0 || startval > endval) | ||
| 1526 | args_out_of_range (stream, start); | ||
| 1527 | } | ||
| 1528 | read_from_string_index = startval; | ||
| 1529 | read_from_string_index_byte = string_char_to_byte (stream, startval); | ||
| 1530 | read_from_string_limit = endval; | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | retval = read0 (stream); | ||
| 1534 | if (EQ (Vread_with_symbol_positions, Qt) | ||
| 1535 | || EQ (Vread_with_symbol_positions, stream)) | ||
| 1536 | Vread_symbol_positions_list = Fnreverse (Vread_symbol_positions_list); | ||
| 1537 | return retval; | ||
| 1496 | } | 1538 | } |
| 1497 | 1539 | ||
| 1498 | /* Use this for recursive reads, in contexts where internal tokens | 1540 | /* Use this for recursive reads, in contexts where internal tokens |
| @@ -1532,10 +1574,16 @@ read_multibyte (c, readcharfun) | |||
| 1532 | int len = 0; | 1574 | int len = 0; |
| 1533 | int bytes; | 1575 | int bytes; |
| 1534 | 1576 | ||
| 1577 | if (c < 0) | ||
| 1578 | return c; | ||
| 1579 | |||
| 1535 | str[len++] = c; | 1580 | str[len++] = c; |
| 1536 | while ((c = READCHAR) >= 0xA0 | 1581 | while ((c = READCHAR) >= 0xA0 |
| 1537 | && len < MAX_MULTIBYTE_LENGTH) | 1582 | && len < MAX_MULTIBYTE_LENGTH) |
| 1538 | str[len++] = c; | 1583 | { |
| 1584 | str[len++] = c; | ||
| 1585 | readchar_count--; | ||
| 1586 | } | ||
| 1539 | UNREAD (c); | 1587 | UNREAD (c); |
| 1540 | if (UNIBYTE_STR_AS_MULTIBYTE_P (str, len, bytes)) | 1588 | if (UNIBYTE_STR_AS_MULTIBYTE_P (str, len, bytes)) |
| 1541 | return STRING_CHAR (str, len); | 1589 | return STRING_CHAR (str, len); |
| @@ -2314,6 +2362,11 @@ read1 (readcharfun, pch, first_in_list) | |||
| 2314 | separate characters, treat them as separate characters now. */ | 2362 | separate characters, treat them as separate characters now. */ |
| 2315 | ; | 2363 | ; |
| 2316 | 2364 | ||
| 2365 | /* We want readchar_count to be the number of characters, not | ||
| 2366 | bytes. Hence we adjust for multibyte characters in the | ||
| 2367 | string. ... But it doesn't seem to be necessary, because | ||
| 2368 | READCHAR *does* read multibyte characters from buffers. */ | ||
| 2369 | /* readchar_count -= (p - read_buffer) - nchars; */ | ||
| 2317 | if (read_pure) | 2370 | if (read_pure) |
| 2318 | return make_pure_string (read_buffer, nchars, p - read_buffer, | 2371 | return make_pure_string (read_buffer, nchars, p - read_buffer, |
| 2319 | is_multibyte); | 2372 | is_multibyte); |
| @@ -2449,11 +2502,19 @@ read1 (readcharfun, pch, first_in_list) | |||
| 2449 | return make_float (negative ? - value : value); | 2502 | return make_float (negative ? - value : value); |
| 2450 | } | 2503 | } |
| 2451 | } | 2504 | } |
| 2452 | 2505 | { | |
| 2453 | if (uninterned_symbol) | 2506 | Lisp_Object result = uninterned_symbol ? make_symbol (read_buffer) |
| 2454 | return make_symbol (read_buffer); | 2507 | : intern (read_buffer); |
| 2455 | else | 2508 | if (EQ (Vread_with_symbol_positions, Qt) |
| 2456 | return intern (read_buffer); | 2509 | || EQ (Vread_with_symbol_positions, readcharfun)) |
| 2510 | Vread_symbol_positions_list = | ||
| 2511 | /* Kind of a hack; this will probably fail if characters | ||
| 2512 | in the symbol name were escaped. Not really a big | ||
| 2513 | deal, though. */ | ||
| 2514 | Fcons (Fcons (result, readchar_count - Flength (Fsymbol_name (result))), | ||
| 2515 | Vread_symbol_positions_list); | ||
| 2516 | return result; | ||
| 2517 | } | ||
| 2457 | } | 2518 | } |
| 2458 | } | 2519 | } |
| 2459 | } | 2520 | } |
| @@ -3633,6 +3694,35 @@ Order is reverse chronological. */); | |||
| 3633 | See documentation of `read' for possible values. */); | 3694 | See documentation of `read' for possible values. */); |
| 3634 | Vstandard_input = Qt; | 3695 | Vstandard_input = Qt; |
| 3635 | 3696 | ||
| 3697 | DEFVAR_LISP ("read-with-symbol-positions", &Vread_with_symbol_positions, | ||
| 3698 | doc: /* If non-nil, add position of read symbols to `read-symbol-positions-list'. | ||
| 3699 | |||
| 3700 | If this variable is a buffer, then only forms read from that buffer | ||
| 3701 | will be added to `read-symbol-positions-list'. | ||
| 3702 | If this variable is t, then all read forms will be added. | ||
| 3703 | The effect of all other values other than nil are not currently | ||
| 3704 | defined, although they may be in the future. | ||
| 3705 | |||
| 3706 | The positions are relative to the last call to `read' or | ||
| 3707 | `read-from-string'. It is probably a bad idea to set this variable at | ||
| 3708 | the toplevel; bind it instead. */); | ||
| 3709 | Vread_with_symbol_positions = Qnil; | ||
| 3710 | |||
| 3711 | DEFVAR_LISP ("read-symbol-positions-list", &Vread_symbol_positions_list, | ||
| 3712 | doc: /* An list mapping read symbols to their positions. | ||
| 3713 | This variable is modified during calls to `read' or | ||
| 3714 | `read-from-string', but only when `read-with-symbol-positions' is | ||
| 3715 | non-nil. | ||
| 3716 | |||
| 3717 | Each element of the list looks like (SYMBOL . CHAR-POSITION), where | ||
| 3718 | CHAR-POSITION is an integer giving the offset of that occurence of the | ||
| 3719 | symbol from the position where `read' or `read-from-string' started. | ||
| 3720 | |||
| 3721 | Note that a symbol will appear multiple times in this list, if it was | ||
| 3722 | read multiple times. The list is in the same order as the symbols | ||
| 3723 | were read in. */); | ||
| 3724 | Vread_symbol_positions_list = Qnil; | ||
| 3725 | |||
| 3636 | DEFVAR_LISP ("load-path", &Vload_path, | 3726 | DEFVAR_LISP ("load-path", &Vload_path, |
| 3637 | doc: /* *List of directories to search for files to load. | 3727 | doc: /* *List of directories to search for files to load. |
| 3638 | Each element is a string (directory name) or nil (try default directory). | 3728 | Each element is a string (directory name) or nil (try default directory). |