diff options
| author | Paul Eggert | 2011-04-01 13:19:36 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-04-01 13:19:36 -0700 |
| commit | 6ddae4efd9e8a3035eb610c39fb2c8f79e7f9893 (patch) | |
| tree | 1b704b34e4f2f2bd4a6f13e4d1dd058c61c8a6ff /src/lread.c | |
| parent | 0b918413f336dbfa9a9c266ae857bce103556c57 (diff) | |
| parent | 034086489cff2a23cb4d9f8c536e18456be617ef (diff) | |
| download | emacs-6ddae4efd9e8a3035eb610c39fb2c8f79e7f9893.tar.gz emacs-6ddae4efd9e8a3035eb610c39fb2c8f79e7f9893.zip | |
Merge from mainline.
Diffstat (limited to 'src/lread.c')
| -rw-r--r-- | src/lread.c | 162 |
1 files changed, 154 insertions, 8 deletions
diff --git a/src/lread.c b/src/lread.c index a5fd1513c39..6a24569f552 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -73,6 +73,7 @@ Lisp_Object Qascii_character, Qload, Qload_file_name; | |||
| 73 | Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; | 73 | Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; |
| 74 | Lisp_Object Qinhibit_file_name_operation; | 74 | Lisp_Object Qinhibit_file_name_operation; |
| 75 | Lisp_Object Qeval_buffer_list; | 75 | Lisp_Object Qeval_buffer_list; |
| 76 | Lisp_Object Qlexical_binding; | ||
| 76 | Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */ | 77 | Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */ |
| 77 | 78 | ||
| 78 | /* Used instead of Qget_file_char while loading *.elc files compiled | 79 | /* Used instead of Qget_file_char while loading *.elc files compiled |
| @@ -81,6 +82,8 @@ static Lisp_Object Qget_emacs_mule_file_char; | |||
| 81 | 82 | ||
| 82 | static Lisp_Object Qload_force_doc_strings; | 83 | static Lisp_Object Qload_force_doc_strings; |
| 83 | 84 | ||
| 85 | extern Lisp_Object Qinternal_interpreter_environment; | ||
| 86 | |||
| 84 | static Lisp_Object Qload_in_progress; | 87 | static Lisp_Object Qload_in_progress; |
| 85 | 88 | ||
| 86 | /* The association list of objects read with the #n=object form. | 89 | /* The association list of objects read with the #n=object form. |
| @@ -147,8 +150,7 @@ static Lisp_Object Vloads_in_progress; | |||
| 147 | static int read_emacs_mule_char (int, int (*) (int, Lisp_Object), | 150 | static int read_emacs_mule_char (int, int (*) (int, Lisp_Object), |
| 148 | Lisp_Object); | 151 | Lisp_Object); |
| 149 | 152 | ||
| 150 | static void readevalloop (Lisp_Object, FILE*, Lisp_Object, | 153 | static void readevalloop (Lisp_Object, FILE*, Lisp_Object, int, |
| 151 | Lisp_Object (*) (Lisp_Object), int, | ||
| 152 | Lisp_Object, Lisp_Object, | 154 | Lisp_Object, Lisp_Object, |
| 153 | Lisp_Object, Lisp_Object); | 155 | Lisp_Object, Lisp_Object); |
| 154 | static Lisp_Object load_unwind (Lisp_Object); | 156 | static Lisp_Object load_unwind (Lisp_Object); |
| @@ -769,6 +771,116 @@ DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 0, 0, | |||
| 769 | 771 | ||
| 770 | 772 | ||
| 771 | 773 | ||
| 774 | |||
| 775 | /* Return true if the lisp code read using READCHARFUN defines a non-nil | ||
| 776 | `lexical-binding' file variable. After returning, the stream is | ||
| 777 | positioned following the first line, if it is a comment, otherwise | ||
| 778 | nothing is read. */ | ||
| 779 | |||
| 780 | static int | ||
| 781 | lisp_file_lexically_bound_p (Lisp_Object readcharfun) | ||
| 782 | { | ||
| 783 | int ch = READCHAR; | ||
| 784 | if (ch != ';') | ||
| 785 | /* The first line isn't a comment, just give up. */ | ||
| 786 | { | ||
| 787 | UNREAD (ch); | ||
| 788 | return 0; | ||
| 789 | } | ||
| 790 | else | ||
| 791 | /* Look for an appropriate file-variable in the first line. */ | ||
| 792 | { | ||
| 793 | int rv = 0; | ||
| 794 | enum { | ||
| 795 | NOMINAL, AFTER_FIRST_DASH, AFTER_ASTERIX, | ||
| 796 | } beg_end_state = NOMINAL; | ||
| 797 | int in_file_vars = 0; | ||
| 798 | |||
| 799 | #define UPDATE_BEG_END_STATE(ch) \ | ||
| 800 | if (beg_end_state == NOMINAL) \ | ||
| 801 | beg_end_state = (ch == '-' ? AFTER_FIRST_DASH : NOMINAL); \ | ||
| 802 | else if (beg_end_state == AFTER_FIRST_DASH) \ | ||
| 803 | beg_end_state = (ch == '*' ? AFTER_ASTERIX : NOMINAL); \ | ||
| 804 | else if (beg_end_state == AFTER_ASTERIX) \ | ||
| 805 | { \ | ||
| 806 | if (ch == '-') \ | ||
| 807 | in_file_vars = !in_file_vars; \ | ||
| 808 | beg_end_state = NOMINAL; \ | ||
| 809 | } | ||
| 810 | |||
| 811 | /* Skip until we get to the file vars, if any. */ | ||
| 812 | do | ||
| 813 | { | ||
| 814 | ch = READCHAR; | ||
| 815 | UPDATE_BEG_END_STATE (ch); | ||
| 816 | } | ||
| 817 | while (!in_file_vars && ch != '\n' && ch != EOF); | ||
| 818 | |||
| 819 | while (in_file_vars) | ||
| 820 | { | ||
| 821 | char var[100], *var_end, val[100], *val_end; | ||
| 822 | |||
| 823 | ch = READCHAR; | ||
| 824 | |||
| 825 | /* Read a variable name. */ | ||
| 826 | while (ch == ' ' || ch == '\t') | ||
| 827 | ch = READCHAR; | ||
| 828 | |||
| 829 | var_end = var; | ||
| 830 | while (ch != ':' && ch != '\n' && ch != EOF) | ||
| 831 | { | ||
| 832 | if (var_end < var + sizeof var - 1) | ||
| 833 | *var_end++ = ch; | ||
| 834 | UPDATE_BEG_END_STATE (ch); | ||
| 835 | ch = READCHAR; | ||
| 836 | } | ||
| 837 | |||
| 838 | while (var_end > var | ||
| 839 | && (var_end[-1] == ' ' || var_end[-1] == '\t')) | ||
| 840 | var_end--; | ||
| 841 | *var_end = '\0'; | ||
| 842 | |||
| 843 | if (ch == ':') | ||
| 844 | { | ||
| 845 | /* Read a variable value. */ | ||
| 846 | ch = READCHAR; | ||
| 847 | |||
| 848 | while (ch == ' ' || ch == '\t') | ||
| 849 | ch = READCHAR; | ||
| 850 | |||
| 851 | val_end = val; | ||
| 852 | while (ch != ';' && ch != '\n' && ch != EOF && in_file_vars) | ||
| 853 | { | ||
| 854 | if (val_end < val + sizeof val - 1) | ||
| 855 | *val_end++ = ch; | ||
| 856 | UPDATE_BEG_END_STATE (ch); | ||
| 857 | ch = READCHAR; | ||
| 858 | } | ||
| 859 | if (! in_file_vars) | ||
| 860 | /* The value was terminated by an end-marker, which | ||
| 861 | remove. */ | ||
| 862 | val_end -= 3; | ||
| 863 | while (val_end > val | ||
| 864 | && (val_end[-1] == ' ' || val_end[-1] == '\t')) | ||
| 865 | val_end--; | ||
| 866 | *val_end = '\0'; | ||
| 867 | |||
| 868 | if (strcmp (var, "lexical-binding") == 0) | ||
| 869 | /* This is it... */ | ||
| 870 | { | ||
| 871 | rv = (strcmp (val, "nil") != 0); | ||
| 872 | break; | ||
| 873 | } | ||
| 874 | } | ||
| 875 | } | ||
| 876 | |||
| 877 | while (ch != '\n' && ch != EOF) | ||
| 878 | ch = READCHAR; | ||
| 879 | |||
| 880 | return rv; | ||
| 881 | } | ||
| 882 | } | ||
| 883 | |||
| 772 | /* Value is a version number of byte compiled code if the file | 884 | /* Value is a version number of byte compiled code if the file |
| 773 | associated with file descriptor FD is a compiled Lisp file that's | 885 | associated with file descriptor FD is a compiled Lisp file that's |
| 774 | safe to load. Only files compiled with Emacs are safe to load. | 886 | safe to load. Only files compiled with Emacs are safe to load. |
| @@ -1033,6 +1145,12 @@ Return t if the file exists and loads successfully. */) | |||
| 1033 | Vloads_in_progress = Fcons (found, Vloads_in_progress); | 1145 | Vloads_in_progress = Fcons (found, Vloads_in_progress); |
| 1034 | } | 1146 | } |
| 1035 | 1147 | ||
| 1148 | /* All loads are by default dynamic, unless the file itself specifies | ||
| 1149 | otherwise using a file-variable in the first line. This is bound here | ||
| 1150 | so that it takes effect whether or not we use | ||
| 1151 | Vload_source_file_function. */ | ||
| 1152 | specbind (Qlexical_binding, Qnil); | ||
| 1153 | |||
| 1036 | /* Get the name for load-history. */ | 1154 | /* Get the name for load-history. */ |
| 1037 | hist_file_name = (! NILP (Vpurify_flag) | 1155 | hist_file_name = (! NILP (Vpurify_flag) |
| 1038 | ? Fconcat (2, (tmp[0] = Ffile_name_directory (file), | 1156 | ? Fconcat (2, (tmp[0] = Ffile_name_directory (file), |
| @@ -1157,15 +1275,20 @@ Return t if the file exists and loads successfully. */) | |||
| 1157 | load_descriptor_list | 1275 | load_descriptor_list |
| 1158 | = Fcons (make_number (fileno (stream)), load_descriptor_list); | 1276 | = Fcons (make_number (fileno (stream)), load_descriptor_list); |
| 1159 | specbind (Qload_in_progress, Qt); | 1277 | specbind (Qload_in_progress, Qt); |
| 1278 | |||
| 1279 | instream = stream; | ||
| 1280 | if (lisp_file_lexically_bound_p (Qget_file_char)) | ||
| 1281 | Fset (Qlexical_binding, Qt); | ||
| 1282 | |||
| 1160 | if (! version || version >= 22) | 1283 | if (! version || version >= 22) |
| 1161 | readevalloop (Qget_file_char, stream, hist_file_name, | 1284 | readevalloop (Qget_file_char, stream, hist_file_name, |
| 1162 | Feval, 0, Qnil, Qnil, Qnil, Qnil); | 1285 | 0, Qnil, Qnil, Qnil, Qnil); |
| 1163 | else | 1286 | else |
| 1164 | { | 1287 | { |
| 1165 | /* We can't handle a file which was compiled with | 1288 | /* We can't handle a file which was compiled with |
| 1166 | byte-compile-dynamic by older version of Emacs. */ | 1289 | byte-compile-dynamic by older version of Emacs. */ |
| 1167 | specbind (Qload_force_doc_strings, Qt); | 1290 | specbind (Qload_force_doc_strings, Qt); |
| 1168 | readevalloop (Qget_emacs_mule_file_char, stream, hist_file_name, Feval, | 1291 | readevalloop (Qget_emacs_mule_file_char, stream, hist_file_name, |
| 1169 | 0, Qnil, Qnil, Qnil, Qnil); | 1292 | 0, Qnil, Qnil, Qnil, Qnil); |
| 1170 | } | 1293 | } |
| 1171 | unbind_to (count, Qnil); | 1294 | unbind_to (count, Qnil); |
| @@ -1535,7 +1658,6 @@ static void | |||
| 1535 | readevalloop (Lisp_Object readcharfun, | 1658 | readevalloop (Lisp_Object readcharfun, |
| 1536 | FILE *stream, | 1659 | FILE *stream, |
| 1537 | Lisp_Object sourcename, | 1660 | Lisp_Object sourcename, |
| 1538 | Lisp_Object (*evalfun) (Lisp_Object), | ||
| 1539 | int printflag, | 1661 | int printflag, |
| 1540 | Lisp_Object unibyte, Lisp_Object readfun, | 1662 | Lisp_Object unibyte, Lisp_Object readfun, |
| 1541 | Lisp_Object start, Lisp_Object end) | 1663 | Lisp_Object start, Lisp_Object end) |
| @@ -1546,6 +1668,7 @@ readevalloop (Lisp_Object readcharfun, | |||
| 1546 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 1668 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 1547 | struct buffer *b = 0; | 1669 | struct buffer *b = 0; |
| 1548 | int continue_reading_p; | 1670 | int continue_reading_p; |
| 1671 | Lisp_Object lex_bound; | ||
| 1549 | /* Nonzero if reading an entire buffer. */ | 1672 | /* Nonzero if reading an entire buffer. */ |
| 1550 | int whole_buffer = 0; | 1673 | int whole_buffer = 0; |
| 1551 | /* 1 on the first time around. */ | 1674 | /* 1 on the first time around. */ |
| @@ -1571,6 +1694,14 @@ readevalloop (Lisp_Object readcharfun, | |||
| 1571 | record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil); | 1694 | record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil); |
| 1572 | load_convert_to_unibyte = !NILP (unibyte); | 1695 | load_convert_to_unibyte = !NILP (unibyte); |
| 1573 | 1696 | ||
| 1697 | /* If lexical binding is active (either because it was specified in | ||
| 1698 | the file's header, or via a buffer-local variable), create an empty | ||
| 1699 | lexical environment, otherwise, turn off lexical binding. */ | ||
| 1700 | lex_bound = find_symbol_value (Qlexical_binding); | ||
| 1701 | specbind (Qinternal_interpreter_environment, | ||
| 1702 | NILP (lex_bound) || EQ (lex_bound, Qunbound) | ||
| 1703 | ? Qnil : Fcons (Qt, Qnil)); | ||
| 1704 | |||
| 1574 | GCPRO4 (sourcename, readfun, start, end); | 1705 | GCPRO4 (sourcename, readfun, start, end); |
| 1575 | 1706 | ||
| 1576 | /* Try to ensure sourcename is a truename, except whilst preloading. */ | 1707 | /* Try to ensure sourcename is a truename, except whilst preloading. */ |
| @@ -1672,7 +1803,7 @@ readevalloop (Lisp_Object readcharfun, | |||
| 1672 | unbind_to (count1, Qnil); | 1803 | unbind_to (count1, Qnil); |
| 1673 | 1804 | ||
| 1674 | /* Now eval what we just read. */ | 1805 | /* Now eval what we just read. */ |
| 1675 | val = (*evalfun) (val); | 1806 | val = eval_sub (val); |
| 1676 | 1807 | ||
| 1677 | if (printflag) | 1808 | if (printflag) |
| 1678 | { | 1809 | { |
| @@ -1732,7 +1863,8 @@ This function preserves the position of point. */) | |||
| 1732 | specbind (Qstandard_output, tem); | 1863 | specbind (Qstandard_output, tem); |
| 1733 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); | 1864 | record_unwind_protect (save_excursion_restore, save_excursion_save ()); |
| 1734 | BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); | 1865 | BUF_TEMP_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf))); |
| 1735 | readevalloop (buf, 0, filename, Feval, | 1866 | specbind (Qlexical_binding, lisp_file_lexically_bound_p (buf) ? Qt : Qnil); |
| 1867 | readevalloop (buf, 0, filename, | ||
| 1736 | !NILP (printflag), unibyte, Qnil, Qnil, Qnil); | 1868 | !NILP (printflag), unibyte, Qnil, Qnil, Qnil); |
| 1737 | unbind_to (count, Qnil); | 1869 | unbind_to (count, Qnil); |
| 1738 | 1870 | ||
| @@ -1753,6 +1885,7 @@ which is the input stream for reading characters. | |||
| 1753 | This function does not move point. */) | 1885 | This function does not move point. */) |
| 1754 | (Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object read_function) | 1886 | (Lisp_Object start, Lisp_Object end, Lisp_Object printflag, Lisp_Object read_function) |
| 1755 | { | 1887 | { |
| 1888 | /* FIXME: Do the eval-sexp-add-defvars danse! */ | ||
| 1756 | int count = SPECPDL_INDEX (); | 1889 | int count = SPECPDL_INDEX (); |
| 1757 | Lisp_Object tem, cbuf; | 1890 | Lisp_Object tem, cbuf; |
| 1758 | 1891 | ||
| @@ -1766,7 +1899,7 @@ This function does not move point. */) | |||
| 1766 | specbind (Qeval_buffer_list, Fcons (cbuf, Veval_buffer_list)); | 1899 | specbind (Qeval_buffer_list, Fcons (cbuf, Veval_buffer_list)); |
| 1767 | 1900 | ||
| 1768 | /* readevalloop calls functions which check the type of start and end. */ | 1901 | /* readevalloop calls functions which check the type of start and end. */ |
| 1769 | readevalloop (cbuf, 0, BVAR (XBUFFER (cbuf), filename), Feval, | 1902 | readevalloop (cbuf, 0, BVAR (XBUFFER (cbuf), filename), |
| 1770 | !NILP (printflag), Qnil, read_function, | 1903 | !NILP (printflag), Qnil, read_function, |
| 1771 | start, end); | 1904 | start, end); |
| 1772 | 1905 | ||
| @@ -3838,6 +3971,7 @@ defvar_int (struct Lisp_Intfwd *i_fwd, | |||
| 3838 | sym = intern_c_string (namestring); | 3971 | sym = intern_c_string (namestring); |
| 3839 | i_fwd->type = Lisp_Fwd_Int; | 3972 | i_fwd->type = Lisp_Fwd_Int; |
| 3840 | i_fwd->intvar = address; | 3973 | i_fwd->intvar = address; |
| 3974 | XSYMBOL (sym)->declared_special = 1; | ||
| 3841 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 3975 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; |
| 3842 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); | 3976 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); |
| 3843 | } | 3977 | } |
| @@ -3852,6 +3986,7 @@ defvar_bool (struct Lisp_Boolfwd *b_fwd, | |||
| 3852 | sym = intern_c_string (namestring); | 3986 | sym = intern_c_string (namestring); |
| 3853 | b_fwd->type = Lisp_Fwd_Bool; | 3987 | b_fwd->type = Lisp_Fwd_Bool; |
| 3854 | b_fwd->boolvar = address; | 3988 | b_fwd->boolvar = address; |
| 3989 | XSYMBOL (sym)->declared_special = 1; | ||
| 3855 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 3990 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; |
| 3856 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); | 3991 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); |
| 3857 | Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); | 3992 | Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); |
| @@ -3870,6 +4005,7 @@ defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd, | |||
| 3870 | sym = intern_c_string (namestring); | 4005 | sym = intern_c_string (namestring); |
| 3871 | o_fwd->type = Lisp_Fwd_Obj; | 4006 | o_fwd->type = Lisp_Fwd_Obj; |
| 3872 | o_fwd->objvar = address; | 4007 | o_fwd->objvar = address; |
| 4008 | XSYMBOL (sym)->declared_special = 1; | ||
| 3873 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 4009 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; |
| 3874 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); | 4010 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); |
| 3875 | } | 4011 | } |
| @@ -3893,6 +4029,7 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd, | |||
| 3893 | sym = intern_c_string (namestring); | 4029 | sym = intern_c_string (namestring); |
| 3894 | ko_fwd->type = Lisp_Fwd_Kboard_Obj; | 4030 | ko_fwd->type = Lisp_Fwd_Kboard_Obj; |
| 3895 | ko_fwd->offset = offset; | 4031 | ko_fwd->offset = offset; |
| 4032 | XSYMBOL (sym)->declared_special = 1; | ||
| 3896 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 4033 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; |
| 3897 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); | 4034 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); |
| 3898 | } | 4035 | } |
| @@ -4320,6 +4457,15 @@ to load. See also `load-dangerous-libraries'. */); | |||
| 4320 | Vbytecomp_version_regexp | 4457 | Vbytecomp_version_regexp |
| 4321 | = make_pure_c_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)"); | 4458 | = make_pure_c_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)"); |
| 4322 | 4459 | ||
| 4460 | Qlexical_binding = intern ("lexical-binding"); | ||
| 4461 | staticpro (&Qlexical_binding); | ||
| 4462 | DEFVAR_LISP ("lexical-binding", Vlexical_binding, | ||
| 4463 | doc: /* If non-nil, use lexical binding when evaluating code. | ||
| 4464 | This only applies to code evaluated by `eval-buffer' and `eval-region'. | ||
| 4465 | This variable is automatically set from the file variables of an interpreted | ||
| 4466 | Lisp file read using `load'. */); | ||
| 4467 | Fmake_variable_buffer_local (Qlexical_binding); | ||
| 4468 | |||
| 4323 | DEFVAR_LISP ("eval-buffer-list", Veval_buffer_list, | 4469 | DEFVAR_LISP ("eval-buffer-list", Veval_buffer_list, |
| 4324 | doc: /* List of buffers being read from by calls to `eval-buffer' and `eval-region'. */); | 4470 | doc: /* List of buffers being read from by calls to `eval-buffer' and `eval-region'. */); |
| 4325 | Veval_buffer_list = Qnil; | 4471 | Veval_buffer_list = Qnil; |