1 /* $Id: validate.h,v 1.3 2005/11/23 05:51:53 sgt Exp $
3 * Copyright (C) 1997-1999, Greg J. Badros and Maciej Stachowiak
5 * This contains the argument validation macros for standard
6 * guile types. Other argument validation procedures
7 * appear in the type-defining header file; e.g., for validating
8 * windows, see windows.h, for colors, see colors.h.
10 * All validation procedures should look something like this
12 * VALIDATE_ARG_type_action_USE_default
13 * ^^^^ optional -- macros w/o this use 1 as position parameter
14 * ^^^^^^^ optional -- COPY/INVERT currently exist
15 * for moving scm into C variable
16 * ^^^^^^^^^^^^ optional -- default is CONTEXT/T/F/DEF
18 * "optional" is not meant to imply that all versions of the VALIDATE
19 * macro exist-- only those commonly used.
21 * All such macros use the value of FUNC_NAME when reporting errors
22 * if the function name is passed in an argument (as opposed to being
23 * statically determined by where the VALIDATE macro invocation appears)
24 * then users of the VALIDATE_ macros should do something like:
26 #define FUNC_NAME func_name_formal_parameter
31 The arguments to the macro correspond to the sub-parts of the macro name.
32 ARG is the argument position number (e.g., 1, 2, etc.)
33 type is the actual SCM object formal parameter name (e.g., window)
34 action has an argument that is the target of the action (a C lvalue)
35 default is either implicit (as for T/F [true/false]) or needs a value argument.
37 If a default value is permitted, this means to use that value if
38 the scheme object is SCM_UNDEFINED or SCM_BOOL_F -- validate macros uses
39 the UNSET_SCM(x) macro to test for this cases.
47 /* Use implied FUNC_NAME (cascaded macro) */
48 #define SCWM_WRONG_TYPE_ARG(pos,formal) \
49 do { scm_wrong_type_arg(FUNC_NAME, pos, formal); } while (0)
52 VALIDATE_ARG_BOOL_COPY(1,modified_p?,fModified);
54 NOTE: Assignments to the cvar in the error handling
55 branch of the _COPY macros are to quiet compiler
56 warnings about possibly unitialized variables.
58 #define VALIDATE_ARG_BOOL_COPY(pos,scm,f) \
60 if (scm == SCM_BOOL_T) f = True; \
61 else if (scm == SCM_BOOL_F) f = False; \
62 else { f = False; scm_wrong_type_arg(FUNC_NAME,pos,scm); } \
65 #define VALIDATE_ARG_BOOL_COPY_USE_T(pos,scm,f) \
67 if (scm == SCM_BOOL_T || scm == SCM_UNDEFINED) f = True; \
68 else if (scm == SCM_BOOL_F) f = False; \
69 else { f = False; scm_wrong_type_arg(FUNC_NAME,pos,scm); } \
72 #define VALIDATE_ARG_BOOL_COPY_USE_F(pos,scm,f) \
74 if (scm == SCM_BOOL_T) f = True; \
75 else if (scm == SCM_BOOL_F || scm == SCM_UNDEFINED) f = False; \
76 else {f = False; scm_wrong_type_arg(FUNC_NAME,pos,scm); } \
80 #define VALIDATE_ARG_BOOL_INVERT(pos,scm,f) \
82 if (scm == SCM_BOOL_F) f = True; \
83 else if (scm == SCM_BOOL_T) f = False; \
84 else { f = False; scm_wrong_type_arg(FUNC_NAME,pos,scm); } \
87 /* range is [low,high]; i.e., low and high are both okay values */
88 #define VALIDATE_ARG_INT_RANGE_COPY(pos,scm,low,high,cvar) \
90 if (!SCM_NUMBERP(scm)) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
91 cvar = scm_num2long(scm, pos, FUNC_NAME); \
92 if (cvar < low || cvar > high) \
93 scm_misc_error(FUNC_NAME,"Argument ~s must be in [~s,~s]", \
94 scm_list_n(scm_long2num(pos),scm_long2num(low),scm_long2num(high),SCM_UNDEFINED)); \
97 #define VALIDATE_ARG_INT_MIN_COPY(pos,scm,low,cvar) \
99 if (!SCM_NUMBERP(scm)) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
100 cvar = scm_num2long(scm, pos, FUNC_NAME); \
101 if (cvar < low) scm_misc_error(FUNC_NAME,"Argument ~s must be greater than ~s", \
102 scm_list_n(scm_long2num(pos),scm_long2num(low),SCM_UNDEFINED)); \
105 #define VALIDATE_ARG_INT_MAX_COPY(pos,scm,high,cvar) \
107 if (!SCM_NUMBERP(scm)) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
108 cvar = scm_num2long(scm, pos, FUNC_NAME); \
109 if (cvar > high) scm_misc_error(FUNC_NAME,"Argument ~s must be less than ~s", \
110 scm_list_n(scm_long2num(pos),scm_long2num(high),SCM_UNDEFINED)); \
113 #define VALIDATE_ARG_INT_OR_UNDEF(pos,x) \
115 if (!UNSET_SCM(x) && !SCM_NUMBERP(x)) SCWM_WRONG_TYPE_ARG(pos, x); \
120 VALIDATE_ARG_INT_COPY_USE_DEF(1,pixels,cpixMoveAmount,10);
121 [default to setting cpixMoveAmount to 10 if pixels is not set */
122 #define VALIDATE_ARG_INT_COPY_USE_DEF(pos,scm,cvar,val) \
124 if (UNSET_SCM(scm)) cvar = val; \
125 else if (SCM_NUMBERP(scm)) cvar = scm_num2int(scm, pos, FUNC_NAME); \
126 else { cvar = 0; scm_wrong_type_arg(FUNC_NAME,pos,scm); } \
130 #define VALIDATE_ARG_INT_COPY(pos,scm,cvar) \
132 if (SCM_NUMBERP(scm)) cvar = scm_num2int(scm, pos, FUNC_NAME); \
133 else scm_wrong_type_arg(FUNC_NAME,pos,scm); \
136 #define VALIDATE_ARG_WINID_COPY(pos,scm,cvar) \
138 if (SCM_NUMBERP(scm)) cvar = (Window) scm_num2ulong(scm, pos, FUNC_NAME); \
139 else scm_wrong_type_arg(FUNC_NAME,pos,scm); \
143 #define VALIDATE_ARG_DBL_MIN_COPY(pos,scm,low,cvar) \
145 if (SCM_NUMBERP(scm)) cvar = scm_num2double(scm, FUNC_NAME); \
146 else scm_wrong_type_arg(FUNC_NAME,pos,scm); \
147 if (cvar < low) scm_misc_error(FUNC_NAME,"Argument ~s must be greater than ~s", \
148 scm_list_n(scm_long2num(pos),scm_double2scm((double)low),SCM_UNDEFINED)); \
152 #define VALIDATE_ARG_DBL_COPY(pos,scm,cvar) \
154 if (SCM_NUMBERP(scm)) cvar = scm_num2double(scm, pos, FUNC_NAME); \
155 else scm_wrong_type_arg(FUNC_NAME,pos,scm); \
158 #define VALIDATE_ARG_DBL_COPY_USE_DEF(pos,scm,cvar,val) \
160 if (UNSET_SCM(scm)) cvar = val; \
161 else if (SCM_NUMBERP(scm)) cvar = scm_num2double(scm, pos, FUNC_NAME); \
162 else scm_wrong_type_arg(FUNC_NAME,pos,scm); \
165 #define VALIDATE_ARG_LIST(pos,scm) \
167 if (!scm_list_n_p(scm)) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
170 #define VALIDATE_ARG_LISTNONEMPTY(pos,scm) \
172 if (!scm_list_n_p(scm)) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
173 else if (!SCM_NFALSEP (scm_pair_p(scm))) scm_misc_error(FUNC_NAME,"List must be non-empty.",SCM_EOL); \
176 #define VALIDATE_ARG_SYM(pos,scm) \
178 if (!SCM_NFALSEP(scm_symbol_p(scm))) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
181 #define VALIDATE_ARG_SYM_USE_DEF(pos,scm,def) \
183 if (UNSET_SCM(scm)) scm = def; \
184 if (!SCM_NFALSEP(scm_symbol_p(scm))) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
188 #define VALIDATE_ARG_STR(pos,scm) \
190 if (!SCM_NFALSEP (scm_string_p(scm))) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
193 #define VALIDATE_ARG_STR_NEWCOPY(pos,scm,pch) \
195 if (SCM_NFALSEP (scm_string_p(scm))) pch = gh_scm2newstr(scm,NULL); \
196 else { pch = NULL; scm_wrong_type_arg(FUNC_NAME,pos,scm); } \
199 #define VALIDATE_ARG_STR_NEWCOPY_LEN(pos,scm,pch,len) \
201 if (SCM_NFALSEP (scm_string_p(scm))) pch = gh_scm2newstr(scm,&len); \
202 else { pch = NULL; scm_wrong_type_arg(FUNC_NAME,pos,scm); } \
205 #define VALIDATE_ARG_STR_NEWCOPY_USE_NULL(pos,scm,pch) \
207 if (UNSET_SCM(scm)) pch = NULL; \
208 else if (SCM_NFALSEP (scm_string_p(scm))) pch = gh_scm2newstr(scm,NULL); \
209 else { pch = NULL; scm_wrong_type_arg(FUNC_NAME,pos,scm); } \
213 #define VALIDATE_ARG_PROC(pos,scm) \
215 if (!SCM_NFALSEP (scm_procedure_p(scm))) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
218 /* we use UNSET_SCM instead of just testing for == SCM_UNDEFINED
219 so SCM_BOOL_F is okay -- this does do an extra assignment, though */
220 #define VALIDATE_ARG_PROC_USE_F(pos,scm) \
222 if (UNSET_SCM(scm)) scm = SCM_BOOL_F; \
223 else if (!SCM_NFALSEP (scm_procedure_p(scm))) scm_wrong_type_arg(FUNC_NAME,pos,scm); \
226 #define VALIDATE_ARG_PROC_OR_SYM_USE_F(pos,scm) \
228 if (UNSET_SCM(scm)) scm = SCM_BOOL_F; \
229 else if (!PROCEDURE_OR_SYMBOL_P(scm)) scm_wrong_type_arg(FUNC_NAME,pos,scm); \