1 /* $Id: validate.h,v 1.3 2005/11/23 05:51:53 sgt Exp $ 2 * validate.h 3 * Copyright (C) 1997-1999, Greg J. Badros and Maciej Stachowiak 4 * 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. 9 * 10 * All validation procedures should look something like this 11 * 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 17 * 18 * "optional" is not meant to imply that all versions of the VALIDATE 19 * macro exist-- only those commonly used. 20 * 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: 25 26 #define FUNC_NAME func_name_formal_parameter 27 VALIDATE_... 28 VALIDATE_... 29 #undef FUNC_NAME 30 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. 36 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. 40 41 */ 42 43 #ifndef VALIDATE_H__ 44 #define VALIDATE_H__ 45 46 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) 50 51 /* Sample Usage: 52 VALIDATE_ARG_BOOL_COPY(1,modified_p?,fModified); 53 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. 57 */ 58 #define VALIDATE_ARG_BOOL_COPY(pos,scm,f) \ 59 do { \ 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); } \ 63 } while (0) 64 65 #define VALIDATE_ARG_BOOL_COPY_USE_T(pos,scm,f) \ 66 do { \ 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); } \ 70 } while (0) 71 72 #define VALIDATE_ARG_BOOL_COPY_USE_F(pos,scm,f) \ 73 do { \ 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); } \ 77 } while (0) 78 79 80 #define VALIDATE_ARG_BOOL_INVERT(pos,scm,f) \ 81 do { \ 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); } \ 85 } while (0) 86 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) \ 89 do { \ 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)); \ 95 } while (0) 96 97 #define VALIDATE_ARG_INT_MIN_COPY(pos,scm,low,cvar) \ 98 do { \ 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)); \ 103 } while (0) 104 105 #define VALIDATE_ARG_INT_MAX_COPY(pos,scm,high,cvar) \ 106 do { \ 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)); \ 111 } while (0) 112 113 #define VALIDATE_ARG_INT_OR_UNDEF(pos,x) \ 114 do { \ 115 if (!UNSET_SCM(x) && !SCM_NUMBERP(x)) SCWM_WRONG_TYPE_ARG(pos, x); \ 116 } while (0) 117 118 119 /* Sample Usage: 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) \ 123 do { \ 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); } \ 127 } while (0) 128 129 130 #define VALIDATE_ARG_INT_COPY(pos,scm,cvar) \ 131 do { \ 132 if (SCM_NUMBERP(scm)) cvar = scm_num2int(scm, pos, FUNC_NAME); \ 133 else scm_wrong_type_arg(FUNC_NAME,pos,scm); \ 134 } while (0) 135 136 #define VALIDATE_ARG_WINID_COPY(pos,scm,cvar) \ 137 do { \ 138 if (SCM_NUMBERP(scm)) cvar = (Window) scm_num2ulong(scm, pos, FUNC_NAME); \ 139 else scm_wrong_type_arg(FUNC_NAME,pos,scm); \ 140 } while (0) 141 142 143 #define VALIDATE_ARG_DBL_MIN_COPY(pos,scm,low,cvar) \ 144 do { \ 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)); \ 149 } while (0) 150 151 152 #define VALIDATE_ARG_DBL_COPY(pos,scm,cvar) \ 153 do { \ 154 if (SCM_NUMBERP(scm)) cvar = scm_num2double(scm, pos, FUNC_NAME); \ 155 else scm_wrong_type_arg(FUNC_NAME,pos,scm); \ 156 } while (0) 157 158 #define VALIDATE_ARG_DBL_COPY_USE_DEF(pos,scm,cvar,val) \ 159 do { \ 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); \ 163 } while (0) 164 165 #define VALIDATE_ARG_LIST(pos,scm) \ 166 do { \ 167 if (!scm_list_n_p(scm)) scm_wrong_type_arg(FUNC_NAME,pos,scm); \ 168 } while (0) 169 170 #define VALIDATE_ARG_LISTNONEMPTY(pos,scm) \ 171 do { \ 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); \ 174 } while (0) 175 176 #define VALIDATE_ARG_SYM(pos,scm) \ 177 do { \ 178 if (!SCM_NFALSEP(scm_symbol_p(scm))) scm_wrong_type_arg(FUNC_NAME,pos,scm); \ 179 } while (0) 180 181 #define VALIDATE_ARG_SYM_USE_DEF(pos,scm,def) \ 182 do { \ 183 if (UNSET_SCM(scm)) scm = def; \ 184 if (!SCM_NFALSEP(scm_symbol_p(scm))) scm_wrong_type_arg(FUNC_NAME,pos,scm); \ 185 } while (0) 186 187 188 #define VALIDATE_ARG_STR(pos,scm) \ 189 do { \ 190 if (!SCM_NFALSEP (scm_string_p(scm))) scm_wrong_type_arg(FUNC_NAME,pos,scm); \ 191 } while (0) 192 193 #define VALIDATE_ARG_STR_NEWCOPY(pos,scm,pch) \ 194 do { \ 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); } \ 197 } while (0) 198 199 #define VALIDATE_ARG_STR_NEWCOPY_LEN(pos,scm,pch,len) \ 200 do { \ 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); } \ 203 } while (0) 204 205 #define VALIDATE_ARG_STR_NEWCOPY_USE_NULL(pos,scm,pch) \ 206 do { \ 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); } \ 210 } while (0) 211 212 213 #define VALIDATE_ARG_PROC(pos,scm) \ 214 do { \ 215 if (!SCM_NFALSEP (scm_procedure_p(scm))) scm_wrong_type_arg(FUNC_NAME,pos,scm); \ 216 } while (0) 217 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) \ 221 do { \ 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); \ 224 } while (0) 225 226 #define VALIDATE_ARG_PROC_OR_SYM_USE_F(pos,scm) \ 227 do { \ 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); \ 230 } while (0) 231 232 #endif 233