X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;ds=sidebyside;f=src%2Fvalidator.c;fp=src%2Fvalidator.c;h=4e38929e1d42f9411468af53676f7b8b49233e9b;hb=9c72f6584bd95dd6e9c7dcb314a6583f7130362f;hp=5f6a6d36e73e81ec841cd047916a4d0efd119dd0;hpb=3bca631112f4865510ea91c85e8c820c4465fc14;p=m6w6%2Fext-psi diff --git a/src/validator.c b/src/validator.c index 5f6a6d3..4e38929 100644 --- a/src/validator.c +++ b/src/validator.c @@ -43,8 +43,6 @@ static int validate_lib(PSI_Validator *V) { if (!ptr) { /* FIXME: assume stdlib */ return 1; - fprintf(stderr, "No import library defined;" - " use 'lib \"\";' statement.\n"); } else if (!strchr(ptr, '/')) { #ifdef DARWIN len = snprintf(lib, MAXPATHLEN, "lib%s.dylib", ptr); @@ -52,13 +50,13 @@ static int validate_lib(PSI_Validator *V) { len = snprintf(lib, MAXPATHLEN, "lib%s.so", ptr); #endif if (MAXPATHLEN == len) { - fprintf(stderr, "Library name too long: '%s'\n", ptr); + V->error(PSI_WARNING, "Library name too long: '%s'", ptr); } lib[len] = 0; ptr = lib; } if (!(V->dlopened = dlopen(ptr, RTLD_LAZY|RTLD_LOCAL))) { - fprintf(stderr, "Could not open library '%s': %s.\n", V->lib, dlerror()); + V->error(PSI_WARNING, "Could not open library '%s': %s.", V->lib, dlerror()); return 0; } return 1; @@ -79,12 +77,11 @@ static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) { } static inline int validate_decl_type(PSI_Validator *V, decl_arg *arg, decl_type *type) { if (type->type == PSI_T_NAME) { - size_t i; - if (!V->defs || !locate_decl_type_alias(V->defs, type)) { - fprintf(stderr, "Cannot use '%s' as type for '%s';" - " Use 'typedef ;' statement.\n", + V->error(PSI_WARNING, "Cannot use '%s' as type for '%s';" + " Use 'typedef ;' statement", type->name, arg->var->name); + return 0; } } return 1; @@ -92,7 +89,7 @@ static inline int validate_decl_type(PSI_Validator *V, decl_arg *arg, decl_type static inline int validate_typedef(PSI_Validator *V, decl_typedef *def) { /* FIXME: check def->alias */ if (def->type->type == PSI_T_NAME) { - fprintf(stderr, "Type '%s' cannot be aliased to '%s'\n", + V->error(PSI_WARNING, "Type '%s' cannot be aliased to '%s'", def->type->name, def->alias); return 0; } @@ -111,10 +108,8 @@ static inline int validate_typedefs(PSI_Validator *V) { } static inline int validate_decl_func(PSI_Validator *V, decl *decl, decl_arg *func) { - void *dlptr; - if (!strcmp(func->var->name, "dlsym")) { - fprintf(stderr, "Cannot dlsym dlsym (sic!)\n"); + V->error(PSI_WARNING, "Cannot dlsym dlsym (sic!)"); return 0; } @@ -124,14 +119,14 @@ static inline int validate_decl_func(PSI_Validator *V, decl *decl, decl_arg *fun decl->dlptr = dlsym(V->dlopened, func->var->name); if (!decl->dlptr) { - fprintf(stderr, "Failed to located symbol '%s': %s\n", + V->error(PSI_WARNING, "Failed to located symbol '%s': %s", func->var->name, dlerror()); } return 1; } static inline int validate_decl_abi(PSI_Validator *V, decl_abi *abi) { if (strcasecmp(abi->convention, "default")) { - fprintf(stderr, "Invalid calling convention: '%s'\n", abi->convention); + V->error(PSI_WARNING, "Invalid calling convention: '%s'", abi->convention); return 0; } /* FIXME */ @@ -213,6 +208,7 @@ static inline decl *locate_impl_decl(decls *decls, ret_stmt *ret) { } return NULL; } + static inline int validate_impl_stmts(PSI_Validator *V, impl *impl, impl_stmts *stmts) { /* okay, * - we must have exactly one ret stmt delcaring the native func to call and which type cast to apply @@ -222,18 +218,20 @@ static inline int validate_impl_stmts(PSI_Validator *V, impl *impl, impl_stmts * size_t i, j; ret_stmt *ret; decl *decl; - int *check; if (!stmts) { - fprintf(stderr, "Missing body for implementation %s!\n", impl->func->name); + V->error(PSI_WARNING, "Missing body for implementation %s!", + impl->func->name); return 0; } if (stmts->ret.count != 1) { if (stmts->ret.count > 1) { - fprintf(stderr, "Too many `ret` statements for implmentation %s; found %zu, exactly one is needed.\n", - impl->func->name, stmts->ret.count); + V->error(PSI_WARNING, "Too many `ret` statements for implmentation %s;" + "found %zu, exactly one is needed", + impl->func->name, stmts->ret.count); } else { - fprintf(stderr, "Missing `ret` statement for implementation %s.\n", impl->func->name); + V->error(PSI_WARNING, "Missing `ret` statement for implementation %s", + impl->func->name); } return 0; } @@ -241,31 +239,56 @@ static inline int validate_impl_stmts(PSI_Validator *V, impl *impl, impl_stmts * ret = stmts->ret.list[0]; decl = locate_impl_decl(V->decls, ret); if (!decl) { - fprintf(stderr, "Missing declaration for implementation %s.\n", impl->func->name); + V->error(PSI_WARNING, "Missing declaration for implementation %s", + impl->func->name); return 0; } /* check that we have a let stmt for every decl arg */ - check = calloc(decl->args->count, sizeof(int)); - for (i = 0; i < stmts->let.count; ++i) { - let_stmt *let = stmts->let.list[i]; + for (i = 0; i < decl->args->count; ++i) { + decl_arg *darg = decl->args->args[i]; + int check = 0; - for (j = 0; j < decl->args->count; ++j) { - if (!strcmp(decl->args->args[j]->var->name, let->var->name)) { - check[j] = 1; + for (j = 0; j < stmts->let.count; ++j) { + let_stmt *let = stmts->let.list[j]; + + if (!strcmp(let->var->name, darg->var->name)) { + darg->let = let; + check = 1; break; } } - } - for (i = 0; i < decl->args->count; ++i) { - if (!check[i]) { - fprintf(stderr, "Missing `let` statement for arg '%s %.*s%s' of declaration '%s' for implementation '%s'.\n", - 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); - free(check); + if (!check) { + V->error(PSI_WARNING, "Missing `let` statement for arg '%s %.*s%s'" + "of declaration '%s' for implementation '%s'", + darg->type->name, (int) darg->var->pointer_level, "*****", + darg->var->name, decl->func->var->name, impl->func->name); return 0; } } - free(check); + /* check that the let_value references a known variable or NULL */ + for (i = 0; i < stmts->let.count; ++i) { + let_stmt *let = stmts->let.list[i]; + int check = 0; + + if (let->val->var) { + for (j = 0; j < impl->func->args->count; ++j) { + impl_arg *iarg = impl->func->args->args[j]; + + if (!strcmp(let->val->var->name, iarg->var->name)) { + let->arg = iarg; + check = 1; + break; + } + } + if (!check) { + V->error(PSI_WARNING, "Unknown value '$%s' of `let` statement" + " for variable '%s' of implementation '%s'", + let->val->var->name, let->var->name, impl->func->name); + return 0; + } + } + } impl->decl = decl;