191124a18104db18965db8397b4a09097f51bcef
11 PSI_Validator
*PSI_ValidatorInit(PSI_Validator
*V
, PSI_Parser
*P
)
14 V
= malloc(sizeof(*V
));
16 memset(V
, 0, sizeof(*V
));
18 PSI_DataExchange((PSI_Data
*) V
, (PSI_Data
*) P
);
23 void PSI_ValidatorDtor(PSI_Validator
*V
)
25 PSI_DataDtor((PSI_Data
*) V
);
26 memset(V
, 0, sizeof(*V
));
29 void PSI_ValidatorFree(PSI_Validator
**V
)
32 PSI_ValidatorDtor(*V
);
38 static int validate_lib(PSI_Validator
*V
) {
40 const char *ptr
= V
->lib
;
44 /* FIXME: assume stdlib */
46 fprintf(stderr
, "No import library defined;"
47 " use 'lib \"<libname>\";' statement.\n");
48 } else if (!strchr(ptr
, '/')) {
50 len
= snprintf(lib
, MAXPATHLEN
, "lib%s.dylib", ptr
);
52 len
= snprintf(lib
, MAXPATHLEN
, "lib%s.so", ptr
);
54 if (MAXPATHLEN
== len
) {
55 fprintf(stderr
, "Library name too long: '%s'\n", ptr
);
60 if (!(V
->dlopened
= dlopen(ptr
, RTLD_LAZY
|RTLD_LOCAL
))) {
61 fprintf(stderr
, "Could not open library '%s': %s.\n", V
->lib
, dlerror());
66 static inline int locate_decl_type_alias(decl_typedefs
*defs
, decl_type
*type
) {
72 for (i
= 0; i
< defs
->count
; ++i
) {
73 if (!strcmp(defs
->list
[i
]->alias
, type
->name
)) {
74 type
->real
= defs
->list
[i
]->type
;
80 static inline int validate_decl_type(PSI_Validator
*V
, decl_arg
*arg
, decl_type
*type
) {
81 if (type
->type
== PSI_T_NAME
) {
84 if (!V
->defs
|| !locate_decl_type_alias(V
->defs
, type
)) {
85 fprintf(stderr
, "Cannot use '%s' as type for '%s';"
86 " Use 'typedef <type> <basic_type>;' statement.\n",
87 type
->name
, arg
->var
->name
);
92 static inline int validate_typedef(PSI_Validator
*V
, decl_typedef
*def
) {
93 /* FIXME: check def->alias */
94 if (def
->type
->type
== PSI_T_NAME
) {
95 fprintf(stderr
, "Type '%s' cannot be aliased to '%s'\n",
96 def
->type
->name
, def
->alias
);
101 static inline int validate_typedefs(PSI_Validator
*V
) {
104 for (i
= 0; i
< V
->defs
->count
; ++i
) {
105 if (!validate_typedef(V
, V
->defs
->list
[i
])) {
112 static inline int validate_decl_func(PSI_Validator
*V
, decl
*decl
, decl_arg
*func
)
116 if (!strcmp(func
->var
->name
, "dlsym")) {
117 fprintf(stderr
, "Cannot dlsym dlsym (sic!)\n");
121 if (!validate_decl_type(V
, func
, func
->type
)) {
125 decl
->dlptr
= dlsym(V
->dlopened
?: RTLD_DEFAULT
, func
->var
->name
);
127 fprintf(stderr
, "Failed to located symbol '%s': %s\n",
128 func
->var
->name
, dlerror());
132 static inline int validate_decl_abi(PSI_Validator
*V
, decl_abi
*abi
) {
133 if (strcasecmp(abi
->convention
, "default")) {
134 fprintf(stderr
, "Invalid calling convention: '%s'\n", abi
->convention
);
140 static inline int validate_decl_arg(PSI_Validator
*V
, decl
*decl
, decl_arg
*arg
) {
141 if (!validate_decl_type(V
, arg
, arg
->type
)) {
146 static inline int validate_decl_args(PSI_Validator
*V
, decl
*decl
, decl_args
*args
) {
149 for (i
= 0; i
< args
->count
; ++i
) {
150 if (!validate_decl_arg(V
, decl
, args
->args
[i
])) {
156 static inline int validate_decl(PSI_Validator
*V
, decl
*decl
) {
157 if (!validate_decl_abi(V
, decl
->abi
)) {
160 if (!validate_decl_func(V
, decl
, decl
->func
)) {
163 if (decl
->args
&& !validate_decl_args(V
, decl
, decl
->args
)) {
168 static inline int validate_decls(PSI_Validator
*V
) {
171 for (i
= 0; i
< V
->decls
->count
; ++i
) {
172 if (!validate_decl(V
, V
->decls
->list
[i
])) {
179 static inline int validate_impl_type(PSI_Validator
*V
, impl
*impl
, impl_type
*type
) {
183 static inline int validate_impl_arg(PSI_Validator
*V
, impl
*impl
, impl_arg
*arg
) {
186 static inline int validate_impl_args(PSI_Validator
*V
, impl
*impl
, impl_args
*args
) {
189 for (i
= 0; i
< args
->count
; ++i
) {
190 if (!validate_impl_arg(V
, impl
, args
->args
[i
])) {
196 static inline int validate_impl_func(PSI_Validator
*V
, impl
*impl
, impl_func
*func
) {
197 /* FIXME: does name need any validation? */
198 if (!validate_impl_type(V
, impl
, func
->return_type
)) {
201 if (func
->args
&& !validate_impl_args(V
, impl
, func
->args
)) {
206 static inline decl
*locate_impl_decl(decls
*decls
, ret_stmt
*ret
) {
209 for (i
= 0; i
< decls
->count
; ++i
) {
210 if (!strcmp(decls
->list
[i
]->func
->var
->name
, ret
->decl
->name
)) {
211 return decls
->list
[i
];
216 static inline int validate_impl_stmts(PSI_Validator
*V
, impl
*impl
, impl_stmts
*stmts
) {
218 * - we must have exactly one ret stmt delcaring the native func to call and which type cast to apply
219 * - we can have multiple let stmts; every arg of the ret stmts var (the function to call) must have one
220 * - we can have any count of set stmts; processing out vars, etc.
228 fprintf(stderr
, "Missing body for implementation %s!\n", impl
->func
->name
);
231 if (stmts
->ret
.count
!= 1) {
232 if (stmts
->ret
.count
> 1) {
233 fprintf(stderr
, "Too many `ret` statements for implmentation %s; found %zu, exactly one is needed.\n",
234 impl
->func
->name
, stmts
->ret
.count
);
236 fprintf(stderr
, "Missing `ret` statement for implementation %s.\n", impl
->func
->name
);
241 ret
= stmts
->ret
.list
[0];
242 decl
= locate_impl_decl(V
->decls
, ret
);
244 fprintf(stderr
, "Missing declaration for implementation %s.\n", impl
->func
->name
);
248 /* check that we have a let stmt for every decl arg */
249 check
= calloc(decl
->args
->count
, sizeof(int));
250 for (i
= 0; i
< stmts
->let
.count
; ++i
) {
251 let_stmt
*let
= stmts
->let
.list
[i
];
253 for (j
= 0; j
< decl
->args
->count
; ++j
) {
254 if (!strcmp(decl
->args
->args
[j
]->var
->name
, let
->var
->name
)) {
260 for (i
= 0; i
< decl
->args
->count
; ++i
) {
262 fprintf(stderr
, "Missing `let` statement for arg '%s %.*s%s' of declaration '%s' for implementation '%s'.\n",
263 decl
->args
->args
[i
]->type
->name
, (int) decl
->args
->args
[i
]->var
->pointer_level
, "*****", decl
->args
->args
[i
]->var
->name
, decl
->func
->var
->name
, impl
->func
->name
);
275 static inline int validate_impl(PSI_Validator
*V
, impl
*impl
) {
276 if (!validate_impl_func(V
, impl
, impl
->func
)) {
279 if (!validate_impl_stmts(V
, impl
, impl
->stmts
)) {
284 static inline int validate_impls(PSI_Validator
*V
) {
287 for (i
= 0; i
< V
->impls
->count
; ++i
) {
288 if (!validate_impl(V
, V
->impls
->list
[i
])) {
295 int PSI_ValidatorValidate(PSI_Validator
*V
)
297 if (!validate_lib(V
)) {
300 if (V
->defs
&& !validate_typedefs(V
)) {
303 if (V
->decls
&& !validate_decls(V
)) {
306 if (V
->impls
&& !validate_impls(V
)) {