Mercurial > hg > xemacs-beta
comparison src/lisp.h @ 5095:cb4f2e1bacc4
merge
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Thu, 04 Mar 2010 02:46:38 -0600 |
parents | 33bc58a32dc2 6afe991b8135 |
children | 4a6b680a9577 |
comparison
equal
deleted
inserted
replaced
5094:ebee7d1e58bd | 5095:cb4f2e1bacc4 |
---|---|
4011 | 4011 |
4012 #define CHECK_FUNCTION(fun) do { \ | 4012 #define CHECK_FUNCTION(fun) do { \ |
4013 while (NILP (Ffunctionp (fun))) \ | 4013 while (NILP (Ffunctionp (fun))) \ |
4014 signal_invalid_function_error (fun); \ | 4014 signal_invalid_function_error (fun); \ |
4015 } while (0) | 4015 } while (0) |
4016 | |
4017 /************************************************************************/ | |
4018 /* Parsing keyword arguments */ | |
4019 /************************************************************************/ | |
4020 | |
4021 /* The C subr must have been declared with MANY as its max args, and this | |
4022 PARSE_KEYWORDS call must come before any statements. | |
4023 | |
4024 FUNCTION is the name of the current function, as a symbol. | |
4025 | |
4026 NARGS is the count of arguments supplied to FUNCTION. | |
4027 | |
4028 ARGS is a pointer to the argument vector (not a Lisp vector) supplied to | |
4029 FUNCTION. | |
4030 | |
4031 KEYWORDS_OFFSET is the offset into ARGS where the keyword arguments start. | |
4032 | |
4033 KEYWORD_COUNT is the number of keywords FUNCTION is normally prepared to | |
4034 handle. | |
4035 | |
4036 KEYWORDS is a parenthesised list of those keywords, without the initial | |
4037 Q_. | |
4038 | |
4039 KEYWORD_DEFAULTS allows you to set non-nil defaults. Put (keywordname = | |
4040 initial_value) in this parameter, a collection of C statements surrounded | |
4041 by parentheses and separated by the comma operator. If you don't need | |
4042 this, supply NULL as KEYWORD_DEFAULTS. | |
4043 | |
4044 ALLOW_OTHER_KEYS corresponds to the &allow-other-keys argument list | |
4045 entry in defun*; it is 1 if other keys are normally allowed, 0 | |
4046 otherwise. This may be overridden in the caller by specifying | |
4047 :allow-other-keys t in the argument list. | |
4048 | |
4049 For keywords which appear multiple times in the called argument list, the | |
4050 leftmost one overrides, as specified in section 7.1.1 of the CLHS. | |
4051 | |
4052 If you want to check whether a given keyword argument was set (as in the | |
4053 SVAR argument to defun*), supply Qunbound as its default in | |
4054 KEYWORD_DEFAULTS, and examine it once PARSE_KEYWORDS is done. Lisp code | |
4055 cannot supply Qunbound as an argument, so if it is still Qunbound, it was | |
4056 not set. | |
4057 | |
4058 There is no elegant way with this macro to have one name for the keyword | |
4059 and an unrelated name for the local variable, as is possible with the | |
4060 ((:keyword unrelated-var)) syntax in defun* and in Common Lisp. That | |
4061 shouldn't matter in practice. */ | |
4062 | |
4063 #define PARSE_KEYWORDS(function, nargs, args, keywords_offset, \ | |
4064 keyword_count, keywords, keyword_defaults, \ | |
4065 allow_other_keys) \ | |
4066 DECLARE_N_KEYWORDS_##keyword_count keywords; \ | |
4067 \ | |
4068 do \ | |
4069 { \ | |
4070 Lisp_Object pk_key, pk_value; \ | |
4071 Elemcount pk_i = nargs - 1; \ | |
4072 Boolint pk_allow_other_keys = allow_other_keys; \ | |
4073 \ | |
4074 if ((nargs - keywords_offset) & 1) \ | |
4075 { \ | |
4076 if (!allow_other_keys \ | |
4077 && !(pk_allow_other_keys \ | |
4078 = non_nil_allow_other_keys_p (keywords_offset, \ | |
4079 nargs, args))) \ | |
4080 { \ | |
4081 signal_wrong_number_of_arguments_error (function, nargs); \ | |
4082 } \ | |
4083 else \ | |
4084 { \ | |
4085 /* Ignore the trailing arg; so below always sees an even \ | |
4086 number of arguments. */ \ | |
4087 pk_i -= 1; \ | |
4088 } \ | |
4089 } \ | |
4090 \ | |
4091 (void)(keyword_defaults); \ | |
4092 \ | |
4093 /* Start from the end, because the leftmost element overrides. */ \ | |
4094 while (pk_i > keywords_offset) \ | |
4095 { \ | |
4096 pk_value = args[pk_i--]; \ | |
4097 pk_key = args[pk_i--]; \ | |
4098 \ | |
4099 if (0) {} \ | |
4100 CHECK_N_KEYWORDS_##keyword_count keywords \ | |
4101 else if (allow_other_keys || pk_allow_other_keys) \ | |
4102 { \ | |
4103 continue; \ | |
4104 } \ | |
4105 else if (!(pk_allow_other_keys \ | |
4106 = non_nil_allow_other_keys_p (keywords_offset, \ | |
4107 nargs, args))) \ | |
4108 { \ | |
4109 invalid_keyword_argument (function, pk_key); \ | |
4110 } \ | |
4111 } \ | |
4112 } while (0) | |
4113 | |
4114 #define DECLARE_N_KEYWORDS_1(a) \ | |
4115 Lisp_Object a = Qnil | |
4116 #define DECLARE_N_KEYWORDS_2(a,b) \ | |
4117 DECLARE_N_KEYWORDS_1(a), b = Qnil | |
4118 #define DECLARE_N_KEYWORDS_3(a,b,c) \ | |
4119 DECLARE_N_KEYWORDS_2(a,b), c = Qnil | |
4120 #define DECLARE_N_KEYWORDS_4(a,b,c,d) \ | |
4121 DECLARE_N_KEYWORDS_3(a,b,c), d = Qnil | |
4122 #define DECLARE_N_KEYWORDS_5(a,b,c,d,e) \ | |
4123 DECLARE_N_KEYWORDS_4(a,b,c,d), e = Qnil | |
4124 #define DECLARE_N_KEYWORDS_6(a,b,c,d,e,f) \ | |
4125 DECLARE_N_KEYWORDS_5(a,b,c,d,e), f = Qnil | |
4126 #define DECLARE_N_KEYWORDS_7(a,b,c,d,e,f,g) \ | |
4127 DECLARE_N_KEYWORDS_6(a,b,c,d,e,f), g = Qnil | |
4128 | |
4129 #define CHECK_N_KEYWORDS_1(a) \ | |
4130 else if (EQ (pk_key, Q_##a)) { a = pk_value; } | |
4131 #define CHECK_N_KEYWORDS_2(a,b) CHECK_N_KEYWORDS_1(a) \ | |
4132 else if (EQ (pk_key, Q_##b)) { b = pk_value; } | |
4133 #define CHECK_N_KEYWORDS_3(a,b,c) CHECK_N_KEYWORDS_2(a,b) \ | |
4134 else if (EQ (pk_key, Q_##c)) { c = pk_value; } | |
4135 #define CHECK_N_KEYWORDS_4(a,b,c,d) CHECK_N_KEYWORDS_3(a,b,c) \ | |
4136 else if (EQ (pk_key, Q_##d)) { d = pk_value; } | |
4137 #define CHECK_N_KEYWORDS_5(a,b,c,d,e) CHECK_N_KEYWORDS_4(a,b,c,d) \ | |
4138 else if (EQ (pk_key, Q_##e)) { e = pk_value; } | |
4139 #define CHECK_N_KEYWORDS_6(a,b,c,d,e,f) CHECK_N_KEYWORDS_5(a,b,c,d,e) \ | |
4140 else if (EQ (pk_key, Q_##f)) { f = pk_value; } | |
4141 #define CHECK_N_KEYWORDS_7(a,b,c,d,e,f,g) CHECK_N_KEYWORDS_6(a,b,c,d,e,f) \ | |
4142 else if (EQ (pk_key, Q_##g)) { g = pk_value; } | |
4143 | |
4144 Boolint non_nil_allow_other_keys_p (Elemcount offset, int nargs, | |
4145 Lisp_Object *args); | |
4016 | 4146 |
4017 | 4147 |
4018 /************************************************************************/ | 4148 /************************************************************************/ |
4019 /* Checking for QUIT */ | 4149 /* Checking for QUIT */ |
4020 /************************************************************************/ | 4150 /************************************************************************/ |
4868 | 4998 |
4869 extern Lisp_Object Qarith_error, Qbeginning_of_buffer, Qbuffer_read_only, | 4999 extern Lisp_Object Qarith_error, Qbeginning_of_buffer, Qbuffer_read_only, |
4870 Qcircular_list, Qcircular_property_list, Qconversion_error, | 5000 Qcircular_list, Qcircular_property_list, Qconversion_error, |
4871 Qcyclic_variable_indirection, Qdomain_error, Qediting_error, | 5001 Qcyclic_variable_indirection, Qdomain_error, Qediting_error, |
4872 Qend_of_buffer, Qend_of_file, Qerror, Qfile_error, Qinternal_error, | 5002 Qend_of_buffer, Qend_of_file, Qerror, Qfile_error, Qinternal_error, |
4873 Qinvalid_change, Qinvalid_constant, Qinvalid_function, Qinvalid_operation, | 5003 Qinvalid_change, Qinvalid_constant, Qinvalid_function, |
5004 Qinvalid_keyword_argument, Qinvalid_operation, | |
4874 Qinvalid_read_syntax, Qinvalid_state, Qio_error, Qlist_formation_error, | 5005 Qinvalid_read_syntax, Qinvalid_state, Qio_error, Qlist_formation_error, |
4875 Qmalformed_list, Qmalformed_property_list, Qno_catch, Qout_of_memory, | 5006 Qmalformed_list, Qmalformed_property_list, Qno_catch, Qout_of_memory, |
4876 Qoverflow_error, Qprinting_unreadable_object, Qquit, Qrange_error, | 5007 Qoverflow_error, Qprinting_unreadable_object, Qquit, Qrange_error, |
4877 Qsetting_constant, Qsingularity_error, Qstack_overflow, | 5008 Qsetting_constant, Qsingularity_error, Qstack_overflow, |
4878 Qstructure_formation_error, Qtext_conversion_error, Qunderflow_error, | 5009 Qstructure_formation_error, Qtext_conversion_error, Qunderflow_error, |
5096 MODULE_API DECLARE_DOESNT_RETURN (invalid_argument_2 (const Ascbyte *reason, | 5227 MODULE_API DECLARE_DOESNT_RETURN (invalid_argument_2 (const Ascbyte *reason, |
5097 Lisp_Object frob1, | 5228 Lisp_Object frob1, |
5098 Lisp_Object frob2)); | 5229 Lisp_Object frob2)); |
5099 void maybe_invalid_argument (const Ascbyte *, Lisp_Object, Lisp_Object, | 5230 void maybe_invalid_argument (const Ascbyte *, Lisp_Object, Lisp_Object, |
5100 Error_Behavior); | 5231 Error_Behavior); |
5232 MODULE_API DECLARE_DOESNT_RETURN (invalid_keyword_argument (Lisp_Object fun, | |
5233 Lisp_Object kw)); | |
5101 MODULE_API DECLARE_DOESNT_RETURN (invalid_operation (const Ascbyte *reason, | 5234 MODULE_API DECLARE_DOESNT_RETURN (invalid_operation (const Ascbyte *reason, |
5102 Lisp_Object frob)); | 5235 Lisp_Object frob)); |
5103 MODULE_API DECLARE_DOESNT_RETURN (invalid_operation_2 (const Ascbyte *reason, | 5236 MODULE_API DECLARE_DOESNT_RETURN (invalid_operation_2 (const Ascbyte *reason, |
5104 Lisp_Object frob1, | 5237 Lisp_Object frob1, |
5105 Lisp_Object frob2)); | 5238 Lisp_Object frob2)); |