diff options
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 78 |
1 files changed, 71 insertions, 7 deletions
diff --git a/src/data.c b/src/data.c index 4e95494d593..df85ef254ea 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -37,7 +37,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 37 | Lisp_Object Qnil, Qt, Qquote, Qlambda, Qsubr, Qunbound; | 37 | Lisp_Object Qnil, Qt, Qquote, Qlambda, Qsubr, Qunbound; |
| 38 | Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; | 38 | Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; |
| 39 | Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range; | 39 | Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range; |
| 40 | Lisp_Object Qvoid_variable, Qvoid_function; | 40 | Lisp_Object Qvoid_variable, Qvoid_function, Qcyclic_function_indirection; |
| 41 | Lisp_Object Qsetting_constant, Qinvalid_read_syntax; | 41 | Lisp_Object Qsetting_constant, Qinvalid_read_syntax; |
| 42 | Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch; | 42 | Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch; |
| 43 | Lisp_Object Qend_of_file, Qarith_error; | 43 | Lisp_Object Qend_of_file, Qarith_error; |
| @@ -480,13 +480,13 @@ DEFUN ("fmakunbound", Ffmakunbound, Sfmakunbound, 1, 1, 0, "Make SYMBOL's functi | |||
| 480 | 480 | ||
| 481 | DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, | 481 | DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, |
| 482 | "Return SYMBOL's function definition. Error if that is void.") | 482 | "Return SYMBOL's function definition. Error if that is void.") |
| 483 | (sym) | 483 | (symbol) |
| 484 | register Lisp_Object sym; | 484 | register Lisp_Object symbol; |
| 485 | { | 485 | { |
| 486 | CHECK_SYMBOL (sym, 0); | 486 | CHECK_SYMBOL (symbol, 0); |
| 487 | if (EQ (XSYMBOL (sym)->function, Qunbound)) | 487 | if (EQ (XSYMBOL (symbol)->function, Qunbound)) |
| 488 | return Fsignal (Qvoid_function, Fcons (sym, Qnil)); | 488 | return Fsignal (Qvoid_function, Fcons (symbol, Qnil)); |
| 489 | return XSYMBOL (sym)->function; | 489 | return XSYMBOL (symbol)->function; |
| 490 | } | 490 | } |
| 491 | 491 | ||
| 492 | DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, "Return SYMBOL's property list.") | 492 | DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, "Return SYMBOL's property list.") |
| @@ -530,6 +530,7 @@ DEFUN ("setplist", Fsetplist, Ssetplist, 2, 2, 0, | |||
| 530 | XSYMBOL (sym)->plist = newplist; | 530 | XSYMBOL (sym)->plist = newplist; |
| 531 | return newplist; | 531 | return newplist; |
| 532 | } | 532 | } |
| 533 | |||
| 533 | 534 | ||
| 534 | /* Getting and setting values of symbols */ | 535 | /* Getting and setting values of symbols */ |
| 535 | 536 | ||
| @@ -1094,6 +1095,61 @@ From now on the default value will apply in this buffer.") | |||
| 1094 | return sym; | 1095 | return sym; |
| 1095 | } | 1096 | } |
| 1096 | 1097 | ||
| 1098 | /* Find the function at the end of a chain of symbol function indirections. */ | ||
| 1099 | |||
| 1100 | /* If OBJECT is a symbol, find the end of its function chain and | ||
| 1101 | return the value found there. If OBJECT is not a symbol, just | ||
| 1102 | return it. If there is a cycle in the function chain, signal a | ||
| 1103 | cyclic-function-indirection error. | ||
| 1104 | |||
| 1105 | This is like Findirect_function, except that it doesn't signal an | ||
| 1106 | error if the chain ends up unbound. */ | ||
| 1107 | Lisp_Object | ||
| 1108 | indirect_function (object, error) | ||
| 1109 | register Lisp_Object object; | ||
| 1110 | { | ||
| 1111 | Lisp_Object tortise, hare; | ||
| 1112 | |||
| 1113 | hare = tortise = object; | ||
| 1114 | |||
| 1115 | for (;;) | ||
| 1116 | { | ||
| 1117 | if (XTYPE (hare) != Lisp_Symbol || EQ (hare, Qunbound)) | ||
| 1118 | break; | ||
| 1119 | hare = XSYMBOL (hare)->function; | ||
| 1120 | if (XTYPE (hare) != Lisp_Symbol || EQ (hare, Qunbound)) | ||
| 1121 | break; | ||
| 1122 | hare = XSYMBOL (hare)->function; | ||
| 1123 | |||
| 1124 | tortise = XSYMBOL (tortise)->function; | ||
| 1125 | |||
| 1126 | if (EQ (hare, tortise)) | ||
| 1127 | Fsignal (Qcyclic_function_indirection, Fcons (object, Qnil)); | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | return hare; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 1, 0, | ||
| 1134 | "Return the function at the end of OBJECT's function chain.\n\ | ||
| 1135 | If OBJECT is a symbol, follow all function indirections and return the final\n\ | ||
| 1136 | function binding.\n\ | ||
| 1137 | If OBJECT is not a symbol, just return it.\n\ | ||
| 1138 | Signal a void-function error if the final symbol is unbound.\n\ | ||
| 1139 | Signal a cyclic-function-indirection error if there is a loop in the\n\ | ||
| 1140 | function chain of symbols.") | ||
| 1141 | (object) | ||
| 1142 | register Lisp_Object object; | ||
| 1143 | { | ||
| 1144 | Lisp_Object result; | ||
| 1145 | |||
| 1146 | result = indirect_function (object); | ||
| 1147 | |||
| 1148 | if (EQ (result, Qunbound)) | ||
| 1149 | return Fsignal (Qvoid_function, Fcons (object, Qnil)); | ||
| 1150 | return result; | ||
| 1151 | } | ||
| 1152 | |||
| 1097 | /* Extract and set vector and string elements */ | 1153 | /* Extract and set vector and string elements */ |
| 1098 | 1154 | ||
| 1099 | DEFUN ("aref", Faref, Saref, 2, 2, 0, | 1155 | DEFUN ("aref", Faref, Saref, 2, 2, 0, |
| @@ -1698,6 +1754,7 @@ syms_of_data () | |||
| 1698 | Qwrong_type_argument = intern ("wrong-type-argument"); | 1754 | Qwrong_type_argument = intern ("wrong-type-argument"); |
| 1699 | Qargs_out_of_range = intern ("args-out-of-range"); | 1755 | Qargs_out_of_range = intern ("args-out-of-range"); |
| 1700 | Qvoid_function = intern ("void-function"); | 1756 | Qvoid_function = intern ("void-function"); |
| 1757 | Qcyclic_function_indirection = intern ("cyclic-function-indirection"); | ||
| 1701 | Qvoid_variable = intern ("void-variable"); | 1758 | Qvoid_variable = intern ("void-variable"); |
| 1702 | Qsetting_constant = intern ("setting-constant"); | 1759 | Qsetting_constant = intern ("setting-constant"); |
| 1703 | Qinvalid_read_syntax = intern ("invalid-read-syntax"); | 1760 | Qinvalid_read_syntax = intern ("invalid-read-syntax"); |
| @@ -1762,6 +1819,11 @@ syms_of_data () | |||
| 1762 | Fput (Qvoid_function, Qerror_message, | 1819 | Fput (Qvoid_function, Qerror_message, |
| 1763 | build_string ("Symbol's function definition is void")); | 1820 | build_string ("Symbol's function definition is void")); |
| 1764 | 1821 | ||
| 1822 | Fput (Qcyclic_function_indirection, Qerror_conditions, | ||
| 1823 | Fcons (Qcyclic_function_indirection, Fcons (Qerror, Qnil))); | ||
| 1824 | Fput (Qcyclic_function_indirection, Qerror_message, | ||
| 1825 | build_string ("Symbol's chain of function indirections contains a loop")); | ||
| 1826 | |||
| 1765 | Fput (Qvoid_variable, Qerror_conditions, | 1827 | Fput (Qvoid_variable, Qerror_conditions, |
| 1766 | Fcons (Qvoid_variable, Fcons (Qerror, Qnil))); | 1828 | Fcons (Qvoid_variable, Fcons (Qerror, Qnil))); |
| 1767 | Fput (Qvoid_variable, Qerror_message, | 1829 | Fput (Qvoid_variable, Qerror_message, |
| @@ -1832,6 +1894,7 @@ syms_of_data () | |||
| 1832 | staticpro (&Qwrong_type_argument); | 1894 | staticpro (&Qwrong_type_argument); |
| 1833 | staticpro (&Qargs_out_of_range); | 1895 | staticpro (&Qargs_out_of_range); |
| 1834 | staticpro (&Qvoid_function); | 1896 | staticpro (&Qvoid_function); |
| 1897 | staticpro (&Qcyclic_function_indirection); | ||
| 1835 | staticpro (&Qvoid_variable); | 1898 | staticpro (&Qvoid_variable); |
| 1836 | staticpro (&Qsetting_constant); | 1899 | staticpro (&Qsetting_constant); |
| 1837 | staticpro (&Qinvalid_read_syntax); | 1900 | staticpro (&Qinvalid_read_syntax); |
| @@ -1898,6 +1961,7 @@ syms_of_data () | |||
| 1898 | defsubr (&Ssetcar); | 1961 | defsubr (&Ssetcar); |
| 1899 | defsubr (&Ssetcdr); | 1962 | defsubr (&Ssetcdr); |
| 1900 | defsubr (&Ssymbol_function); | 1963 | defsubr (&Ssymbol_function); |
| 1964 | defsubr (&Sindirect_function); | ||
| 1901 | defsubr (&Ssymbol_plist); | 1965 | defsubr (&Ssymbol_plist); |
| 1902 | defsubr (&Ssymbol_name); | 1966 | defsubr (&Ssymbol_name); |
| 1903 | defsubr (&Smakunbound); | 1967 | defsubr (&Smakunbound); |