1 |
/* Lisp parsing and input streams. |
/* Lisp parsing and input streams. |
2 |
Copyright (C) 1985, 86, 87, 88, 89, 93, 94, 95, 97, 98, 99, 2000, 2001 |
Copyright (C) 1985, 86, 87, 88, 89, 93, 94, 95, 97, 98, 99, 2000, 2001, 2002 |
3 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
4 |
|
|
5 |
This file is part of GNU Emacs. |
This file is part of GNU Emacs. |
82 |
Lisp_Object Qascii_character, Qload, Qload_file_name; |
Lisp_Object Qascii_character, Qload, Qload_file_name; |
83 |
Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; |
Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; |
84 |
Lisp_Object Qinhibit_file_name_operation; |
Lisp_Object Qinhibit_file_name_operation; |
85 |
|
Lisp_Object Qlexical_binding; |
86 |
|
|
87 |
extern Lisp_Object Qevent_symbol_element_mask; |
extern Lisp_Object Qevent_symbol_element_mask; |
88 |
extern Lisp_Object Qfile_exists_p; |
extern Lisp_Object Qfile_exists_p; |
89 |
|
extern Lisp_Object Qinternal_interpreter_environment; |
90 |
|
|
91 |
/* non-zero if inside `load' */ |
/* non-zero if inside `load' */ |
92 |
int load_in_progress; |
int load_in_progress; |
142 |
/* List of (SYMBOL . POSITION) accumulated so far. */ |
/* List of (SYMBOL . POSITION) accumulated so far. */ |
143 |
Lisp_Object Vread_symbol_positions_list; |
Lisp_Object Vread_symbol_positions_list; |
144 |
|
|
145 |
|
/* If non-nil `readevalloop' evaluates code in a lexical environment. */ |
146 |
|
Lisp_Object Vlexical_binding; |
147 |
|
|
148 |
/* List of descriptors now open for Fload. */ |
/* List of descriptors now open for Fload. */ |
149 |
static Lisp_Object load_descriptor_list; |
static Lisp_Object load_descriptor_list; |
150 |
|
|
595 |
|
|
596 |
|
|
597 |
|
|
598 |
|
|
599 |
|
/* Return true if the lisp code read using READCHARFUN defines a non-nil |
600 |
|
`lexical-binding' file variable. After returning, the stream is |
601 |
|
positioned following the first line, if it is a comment, otherwise |
602 |
|
nothing is read. */ |
603 |
|
|
604 |
|
static int |
605 |
|
lisp_file_lexically_bound_p (readcharfun) |
606 |
|
Lisp_Object readcharfun; |
607 |
|
{ |
608 |
|
int ch = READCHAR; |
609 |
|
if (ch != ';') |
610 |
|
/* The first line isn't a comment, just give up. */ |
611 |
|
{ |
612 |
|
UNREAD (ch); |
613 |
|
return 0; |
614 |
|
} |
615 |
|
else |
616 |
|
/* Look for an appropriate file-variable in the first line. */ |
617 |
|
{ |
618 |
|
int rv = 0; |
619 |
|
enum { |
620 |
|
NOMINAL, AFTER_FIRST_DASH, AFTER_ASTERIX, |
621 |
|
} beg_end_state = NOMINAL; |
622 |
|
int in_file_vars = 0; |
623 |
|
|
624 |
|
#define UPDATE_BEG_END_STATE(ch) \ |
625 |
|
if (beg_end_state == NOMINAL) \ |
626 |
|
beg_end_state = (ch == '-' ? AFTER_FIRST_DASH : NOMINAL); \ |
627 |
|
else if (beg_end_state == AFTER_FIRST_DASH) \ |
628 |
|
beg_end_state = (ch == '*' ? AFTER_ASTERIX : NOMINAL); \ |
629 |
|
else if (beg_end_state == AFTER_ASTERIX) \ |
630 |
|
{ \ |
631 |
|
if (ch == '-') \ |
632 |
|
in_file_vars = !in_file_vars; \ |
633 |
|
beg_end_state = NOMINAL; \ |
634 |
|
} |
635 |
|
|
636 |
|
/* Skip until we get to the file vars, if any. */ |
637 |
|
do |
638 |
|
{ |
639 |
|
ch = READCHAR; |
640 |
|
UPDATE_BEG_END_STATE (ch); |
641 |
|
} |
642 |
|
while (!in_file_vars && ch != '\n' && ch != EOF); |
643 |
|
|
644 |
|
while (in_file_vars) |
645 |
|
{ |
646 |
|
char var[100], *var_end, val[100], *val_end; |
647 |
|
|
648 |
|
ch = READCHAR; |
649 |
|
|
650 |
|
/* Read a variable name. */ |
651 |
|
while (ch == ' ' || ch == '\t') |
652 |
|
ch = READCHAR; |
653 |
|
|
654 |
|
var_end = var; |
655 |
|
while (ch != ':' && ch != '\n' && ch != EOF) |
656 |
|
{ |
657 |
|
if (var_end < var + sizeof var - 1) |
658 |
|
*var_end++ = ch; |
659 |
|
UPDATE_BEG_END_STATE (ch); |
660 |
|
ch = READCHAR; |
661 |
|
} |
662 |
|
|
663 |
|
while (var_end > var |
664 |
|
&& (var_end[-1] == ' ' || var_end[-1] == '\t')) |
665 |
|
var_end--; |
666 |
|
*var_end = '\0'; |
667 |
|
|
668 |
|
if (ch == ':') |
669 |
|
{ |
670 |
|
/* Read a variable value. */ |
671 |
|
ch = READCHAR; |
672 |
|
|
673 |
|
while (ch == ' ' || ch == '\t') |
674 |
|
ch = READCHAR; |
675 |
|
|
676 |
|
val_end = val; |
677 |
|
while (ch != ';' && ch != '\n' && ch != EOF && in_file_vars) |
678 |
|
{ |
679 |
|
if (val_end < val + sizeof val - 1) |
680 |
|
*val_end++ = ch; |
681 |
|
UPDATE_BEG_END_STATE (ch); |
682 |
|
ch = READCHAR; |
683 |
|
} |
684 |
|
if (! in_file_vars) |
685 |
|
/* The value was terminated by an end-marker, which |
686 |
|
remove. */ |
687 |
|
val_end -= 3; |
688 |
|
while (val_end > val |
689 |
|
&& (val_end[-1] == ' ' || val_end[-1] == '\t')) |
690 |
|
val_end--; |
691 |
|
*val_end = '\0'; |
692 |
|
|
693 |
|
if (strcmp (var, "lexical-binding") == 0) |
694 |
|
/* This is it... */ |
695 |
|
{ |
696 |
|
rv = (strcmp (val, "nil") != 0); |
697 |
|
break; |
698 |
|
} |
699 |
|
} |
700 |
|
} |
701 |
|
|
702 |
|
while (ch != '\n' && ch != EOF) |
703 |
|
ch = READCHAR; |
704 |
|
|
705 |
|
return rv; |
706 |
|
} |
707 |
|
} |
708 |
|
|
709 |
|
|
710 |
/* Value is non-zero if the file asswociated with file descriptor FD |
/* Value is non-zero if the file asswociated with file descriptor FD |
711 |
is a compiled Lisp file that's safe to load. Only files compiled |
is a compiled Lisp file that's safe to load. Only files compiled |
712 |
with Emacs are safe to load. Files compiled with XEmacs can lead |
with Emacs are safe to load. Files compiled with XEmacs can lead |
755 |
} |
} |
756 |
|
|
757 |
|
|
758 |
|
|
759 |
DEFUN ("load", Fload, Sload, 1, 5, 0, |
DEFUN ("load", Fload, Sload, 1, 5, 0, |
760 |
doc: /* Execute a file of Lisp code named FILE. |
doc: /* Execute a file of Lisp code named FILE. |
761 |
First try FILE with `.elc' appended, then try with `.el', |
First try FILE with `.elc' appended, then try with `.el', |
896 |
Vloads_in_progress = Fcons (found, Vloads_in_progress); |
Vloads_in_progress = Fcons (found, Vloads_in_progress); |
897 |
} |
} |
898 |
|
|
899 |
|
/* All loads are by default dynamic, unless the file itself specifies |
900 |
|
otherwise using a file-variable in the first line. This is bound here |
901 |
|
so that it takes effect whether or not we use |
902 |
|
Vload_source_file_function. */ |
903 |
|
specbind (Qlexical_binding, Qnil); |
904 |
|
|
905 |
if (!bcmp (&(XSTRING (found)->data[STRING_BYTES (XSTRING (found)) - 4]), |
if (!bcmp (&(XSTRING (found)->data[STRING_BYTES (XSTRING (found)) - 4]), |
906 |
".elc", 4)) |
".elc", 4)) |
907 |
/* Load .elc files directly, but not when they are |
/* Load .elc files directly, but not when they are |
1011 |
load_descriptor_list |
load_descriptor_list |
1012 |
= Fcons (make_number (fileno (stream)), load_descriptor_list); |
= Fcons (make_number (fileno (stream)), load_descriptor_list); |
1013 |
load_in_progress++; |
load_in_progress++; |
1014 |
|
|
1015 |
|
instream = stream; |
1016 |
|
if (lisp_file_lexically_bound_p (Qget_file_char)) |
1017 |
|
Fset (Qlexical_binding, Qt); |
1018 |
|
|
1019 |
readevalloop (Qget_file_char, stream, file, Feval, 0, Qnil, Qnil); |
readevalloop (Qget_file_char, stream, file, Feval, 0, Qnil, Qnil); |
1020 |
|
|
1021 |
unbind_to (count, Qnil); |
unbind_to (count, Qnil); |
1022 |
|
|
1023 |
/* Run any load-hooks for this file. */ |
/* Run any load-hooks for this file. */ |
1405 |
struct gcpro gcpro1; |
struct gcpro gcpro1; |
1406 |
struct buffer *b = 0; |
struct buffer *b = 0; |
1407 |
int continue_reading_p; |
int continue_reading_p; |
1408 |
|
Lisp_Object lex_bound; |
1409 |
|
|
1410 |
if (BUFFERP (readcharfun)) |
if (BUFFERP (readcharfun)) |
1411 |
b = XBUFFER (readcharfun); |
b = XBUFFER (readcharfun); |
1417 |
record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil); |
record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil); |
1418 |
load_convert_to_unibyte = !NILP (unibyte); |
load_convert_to_unibyte = !NILP (unibyte); |
1419 |
|
|
1420 |
|
/* If lexical binding is active (either because it was specified in |
1421 |
|
the file's header, or via a buffer-local variable), create an empty |
1422 |
|
lexical environment, otherwise, turn off lexical binding. */ |
1423 |
|
lex_bound = find_symbol_value (Qlexical_binding); |
1424 |
|
if (NILP (lex_bound) || EQ (lex_bound, Qunbound)) |
1425 |
|
specbind (Qinternal_interpreter_environment, Qnil); |
1426 |
|
else |
1427 |
|
specbind (Qinternal_interpreter_environment, Fcons (Qt, Qnil)); |
1428 |
|
|
1429 |
readchar_backlog = -1; |
readchar_backlog = -1; |
1430 |
|
|
1431 |
GCPRO1 (sourcename); |
GCPRO1 (sourcename); |
1538 |
filename = XBUFFER (buf)->filename; |
filename = XBUFFER (buf)->filename; |
1539 |
|
|
1540 |
specbind (Qstandard_output, tem); |
specbind (Qstandard_output, tem); |
1541 |
|
specbind (Qlexical_binding, Qnil); |
1542 |
record_unwind_protect (save_excursion_restore, save_excursion_save ()); |
record_unwind_protect (save_excursion_restore, save_excursion_save ()); |
1543 |
BUF_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); |
BUF_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); |
1544 |
|
if (lisp_file_lexically_bound_p (buf)) |
1545 |
|
Fset (Qlexical_binding, Qt); |
1546 |
readevalloop (buf, 0, filename, Feval, !NILP (printflag), unibyte, Qnil); |
readevalloop (buf, 0, filename, Feval, !NILP (printflag), unibyte, Qnil); |
1547 |
unbind_to (count, Qnil); |
unbind_to (count, Qnil); |
1548 |
|
|
3502 |
XMISCTYPE (val) = Lisp_Misc_Intfwd; |
XMISCTYPE (val) = Lisp_Misc_Intfwd; |
3503 |
XINTFWD (val)->intvar = address; |
XINTFWD (val)->intvar = address; |
3504 |
SET_SYMBOL_VALUE (sym, val); |
SET_SYMBOL_VALUE (sym, val); |
3505 |
|
XSYMBOL (sym)->declared_special = 1; |
3506 |
} |
} |
3507 |
|
|
3508 |
/* Similar but define a variable whose value is t if address contains 1, |
/* Similar but define a variable whose value is t if address contains 1, |
3518 |
XMISCTYPE (val) = Lisp_Misc_Boolfwd; |
XMISCTYPE (val) = Lisp_Misc_Boolfwd; |
3519 |
XBOOLFWD (val)->boolvar = address; |
XBOOLFWD (val)->boolvar = address; |
3520 |
SET_SYMBOL_VALUE (sym, val); |
SET_SYMBOL_VALUE (sym, val); |
3521 |
|
XSYMBOL (sym)->declared_special = 1; |
3522 |
Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); |
Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); |
3523 |
} |
} |
3524 |
|
|
3538 |
XMISCTYPE (val) = Lisp_Misc_Objfwd; |
XMISCTYPE (val) = Lisp_Misc_Objfwd; |
3539 |
XOBJFWD (val)->objvar = address; |
XOBJFWD (val)->objvar = address; |
3540 |
SET_SYMBOL_VALUE (sym, val); |
SET_SYMBOL_VALUE (sym, val); |
3541 |
|
XSYMBOL (sym)->declared_special = 1; |
3542 |
} |
} |
3543 |
|
|
3544 |
void |
void |
3572 |
XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd; |
XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd; |
3573 |
XBUFFER_OBJFWD (val)->offset = offset; |
XBUFFER_OBJFWD (val)->offset = offset; |
3574 |
SET_SYMBOL_VALUE (sym, val); |
SET_SYMBOL_VALUE (sym, val); |
3575 |
|
XSYMBOL (sym)->declared_special = 1; |
3576 |
PER_BUFFER_SYMBOL (offset) = sym; |
PER_BUFFER_SYMBOL (offset) = sym; |
3577 |
PER_BUFFER_TYPE (offset) = type; |
PER_BUFFER_TYPE (offset) = type; |
3578 |
|
|
3597 |
XMISCTYPE (val) = Lisp_Misc_Kboard_Objfwd; |
XMISCTYPE (val) = Lisp_Misc_Kboard_Objfwd; |
3598 |
XKBOARD_OBJFWD (val)->offset = offset; |
XKBOARD_OBJFWD (val)->offset = offset; |
3599 |
SET_SYMBOL_VALUE (sym, val); |
SET_SYMBOL_VALUE (sym, val); |
3600 |
|
XSYMBOL (sym)->declared_special = 1; |
3601 |
} |
} |
3602 |
|
|
3603 |
/* Record the value of load-path used at the start of dumping |
/* Record the value of load-path used at the start of dumping |
3987 |
Vbytecomp_version_regexp |
Vbytecomp_version_regexp |
3988 |
= build_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)"); |
= build_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)"); |
3989 |
|
|
3990 |
|
Qlexical_binding = intern ("lexical-binding"); |
3991 |
|
staticpro (&Qlexical_binding); |
3992 |
|
DEFVAR_LISP ("lexical-binding", &Vlexical_binding, |
3993 |
|
doc: /* If non-nil, use lexical binding when evaluating code. |
3994 |
|
This only applies to code evaluated by `eval-buffer' and `eval-region'. |
3995 |
|
This variable is automatically set from the file variables of an interpreted |
3996 |
|
lisp file read using `load'. |
3997 |
|
This variable automatically becomes buffer-local when set. */); |
3998 |
|
Fmake_variable_buffer_local (Qlexical_binding); |
3999 |
|
|
4000 |
/* Vsource_directory was initialized in init_lread. */ |
/* Vsource_directory was initialized in init_lread. */ |
4001 |
|
|
4002 |
load_descriptor_list = Qnil; |
load_descriptor_list = Qnil; |