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