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));