X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fdata.c;h=0fb98164ea1629cdd94be97380a8834acdb547a1;hp=102c02239912538f3761389d0a5b402a8a4295ba;hb=a7ac1c0a3c855321f21682c127a4b707de33a303;hpb=18ca609e4fa08a1c8fcdbb58e9aeb5fe55538b3c diff --git a/src/data.c b/src/data.c index 102c022..0fb9816 100644 --- a/src/data.c +++ b/src/data.c @@ -27,18 +27,81 @@ #include "data.h" #include "php_globals.h" +#include "php_network.h" #include +#include + +static void psi_data_ctor_internal(struct psi_data *data, + psi_error_cb error, unsigned flags) +{ + data->error = error; + data->flags = flags; + + if (data->flags & PSI_DEBUG) { + char *debug = getenv("PSI_DEBUG"); + + if (debug) { + int fd = -1; + char *addr = strstr(debug, "://"); + + if (addr) { + addr += 3; + } + if (addr && *addr) { + struct sockaddr_storage sa = {0}; + socklen_t ss = 0; + int rc = php_network_parse_network_address_with_port(addr, + strlen(addr), (struct sockaddr *) &sa, &ss); + + if (SUCCESS == rc) { + int styp = strncmp(debug, "udp:", 4) + ? SOCK_STREAM + : SOCK_DGRAM; + int sfam = sa.ss_family == AF_INET6 + ? ((struct sockaddr_in6 *) &sa)->sin6_family + : ((struct sockaddr_in *) &sa)->sin_family; + + fd = socket(sfam, styp, 0); + + if (fd > 0 && 0 != connect(fd, (struct sockaddr *) &sa, ss)) { + perror(debug); + close(fd); + fd = -1; + } + } + } else if (!strcmp(debug, "stdout")) { + fd = STDOUT_FILENO; + } else if (!strcmp(debug, "stderr")) { + fd = STDERR_FILENO; + } else if (!(fd = atoi(debug))) { + fd = open(debug, O_WRONLY|O_APPEND|O_CREAT|O_CLOEXEC, 0664); + } + + if (fd > 0) { + data->debug_fd = fd; + } else { + data->debug_fd = STDERR_FILENO; + } + } + } +} struct psi_data *psi_data_ctor_with_dtors(struct psi_data *data, psi_error_cb error, unsigned flags) { if (!data) { - data = calloc(1, sizeof(*data)); + data = pecalloc(1, sizeof(*data), 1); } - data->error = error; - data->flags = flags; + psi_data_ctor_internal(data, error, flags); + + if (!data->file.libnames) { + data->file.libnames = psi_plist_init((psi_plist_dtor) psi_names_free); + } + if (!data->file.dlopened) { + data->file.dlopened = psi_plist_init((psi_plist_dtor) psi_libs_free); + } if (!data->consts) { data->consts = psi_plist_init((psi_plist_dtor) psi_const_free); @@ -58,12 +121,12 @@ struct psi_data *psi_data_ctor_with_dtors(struct psi_data *data, if (!data->decls) { data->decls = psi_plist_init((psi_plist_dtor) psi_decl_free); } + if (!data->vars) { + data->vars = psi_plist_init((psi_plist_dtor) psi_decl_extvar_free); + } if (!data->impls) { data->impls = psi_plist_init((psi_plist_dtor) psi_impl_free); } - if (!data->libs) { - data->libs = psi_plist_init((psi_plist_dtor) psi_libs_free); - } return data; } @@ -71,11 +134,17 @@ struct psi_data *psi_data_ctor(struct psi_data *data, psi_error_cb error, unsigned flags) { if (!data) { - data = calloc(1, sizeof(*data)); + data = pecalloc(1, sizeof(*data), 1); } - data->error = error; - data->flags = flags; + psi_data_ctor_internal(data, error, flags); + + if (!data->file.libnames) { + data->file.libnames = psi_plist_init(NULL); + } + if (!data->file.dlopened) { + data->file.dlopened = psi_plist_init(NULL); + } if (!data->consts) { data->consts = psi_plist_init(NULL); @@ -95,19 +164,19 @@ struct psi_data *psi_data_ctor(struct psi_data *data, psi_error_cb error, if (!data->decls) { data->decls = psi_plist_init(NULL); } + if (!data->vars) { + data->vars = psi_plist_init(NULL); + } if (!data->impls) { data->impls = psi_plist_init(NULL); } - if (!data->libs) { - data->libs = psi_plist_init(NULL); - } return data; } struct psi_data *psi_data_exchange(struct psi_data *dest, struct psi_data *src) { if (!dest) { - dest = malloc(sizeof(*dest)); + dest = pemalloc(sizeof(*dest), 1); } *dest = *src; memset(src, 0, sizeof(*src)); @@ -116,6 +185,9 @@ struct psi_data *psi_data_exchange(struct psi_data *dest, struct psi_data *src) void psi_data_dtor(struct psi_data *data) { + if (data->debug_fd) { + close(data->debug_fd); + } if (data->consts) { psi_plist_free(data->consts); } @@ -134,36 +206,37 @@ void psi_data_dtor(struct psi_data *data) if (data->decls) { psi_plist_free(data->decls); } + if (data->vars) { + psi_plist_free(data->vars); + } if (data->impls) { psi_plist_free(data->impls); } - if (data->libs) { - psi_plist_free(data->libs); - } psi_decl_file_dtor(&data->file); } -void psi_data_dump(int fd, struct psi_data *D) +void psi_data_dump(struct psi_dump *dump, struct psi_data *D) { - if (D->file.fn) { - dprintf(fd, "// filename=%s (%u errors)\n", D->file.fn, D->errors); - if (D->file.ln) { - dprintf(fd, "lib \"%s\";\n", D->file.ln); - } - } else { - dprintf(fd, "// builtin predef\n"); + size_t i = 0; + char *libname; + + if (D->file.filename) { + PSI_DUMP(dump, "// filename=%s (%u errors)\n", D->file.filename->val, D->errors); + } + while (psi_plist_get(D->file.libnames, i++, &libname)) { + PSI_DUMP(dump, "lib \"%s\";\n", libname); } if (psi_plist_count(D->types)) { size_t i = 0; struct psi_decl_arg *def; while (psi_plist_get(D->types, i++, &def)) { - dprintf(fd, "typedef "); - psi_decl_arg_dump(fd, def, 0); - dprintf(fd, ";\n"); + PSI_DUMP(dump, "typedef "); + psi_decl_arg_dump(dump, def, 0); + PSI_DUMP(dump, ";\n"); } - dprintf(fd, "\n"); + PSI_DUMP(dump, "\n"); } if (psi_plist_count(D->unions)) { size_t i = 0; @@ -172,10 +245,10 @@ void psi_data_dump(int fd, struct psi_data *D) while (psi_plist_get(D->unions, i++, &unn)) { if (!psi_decl_type_is_anon(unn->name, "union")) { psi_decl_union_dump(fd, unn); - dprintf(fd, "\n"); + PSI_DUMP(dump, "\n"); } } - dprintf(fd, "\n"); + PSI_DUMP(dump, "\n"); } if (psi_plist_count(D->structs)) { size_t i = 0; @@ -183,11 +256,11 @@ void psi_data_dump(int fd, struct psi_data *D) while (psi_plist_get(D->structs, i++, &strct)) { if (!psi_decl_type_is_anon(strct->name, "struct")) { - psi_decl_struct_dump(fd, strct); - dprintf(fd, "\n"); + psi_decl_struct_dump(dump, strct); + PSI_DUMP(dump, "\n"); } } - dprintf(fd, "\n"); + PSI_DUMP(dump, "\n"); } if (psi_plist_count(D->enums)) { size_t i = 0; @@ -195,245 +268,55 @@ void psi_data_dump(int fd, struct psi_data *D) while (psi_plist_get(D->enums, i++, &enm)) { if (!psi_decl_type_is_anon(enm->name, "enum")) { - psi_decl_enum_dump(fd, enm, 0); - dprintf(fd, "\n"); + psi_decl_enum_dump(dump, enm, 0); + PSI_DUMP(dump, "\n"); } } - dprintf(fd, "\n"); + PSI_DUMP(dump, "\n"); } if (psi_plist_count(D->consts)) { size_t i = 0; struct psi_const *c; while (psi_plist_get(D->consts, i++, &c)) { - psi_const_dump(fd, c); - dprintf(fd, "\n"); + psi_const_dump(dump, c); + PSI_DUMP(dump, "\n"); } - dprintf(fd, "\n"); + PSI_DUMP(dump, "\n"); } if (psi_plist_count(D->decls)) { size_t i = 0; struct psi_decl *decl; while (psi_plist_get(D->decls, i++, &decl)) { - psi_decl_dump(fd, decl); - dprintf(fd, "\n"); - } - dprintf(fd, "\n"); - } - if (psi_plist_count(D->impls)) { - size_t i = 0; - struct psi_impl *impl; - - while (psi_plist_get(D->impls, i++, &impl)) { - psi_impl_dump(fd, impl); - dprintf(fd, "\n"); - } - dprintf(fd, "\n"); - } -} - -bool psi_data_validate(struct psi_data *dst, struct psi_data *src) -{ - void *dlopened = NULL; - size_t check_count = ~0; - struct psi_plist *check_types = src->types; - struct psi_plist *check_structs = src->structs; - struct psi_plist *check_unions = src->unions; - struct psi_plist *check_enums = src->enums; - unsigned flags = dst->flags; - unsigned errors = src->errors; - struct psi_validate_stack type_stack; - - /* fail early if library is not found */ - if (!psi_decl_file_validate(dst, src, &dlopened)) { - return false; - } - - psi_validate_stack_ctor(&type_stack); - - dst->flags |= PSI_SILENT; - - while (check_count) { - struct psi_plist *recheck_types; - struct psi_plist *recheck_structs; - struct psi_plist *recheck_unions; - struct psi_plist *recheck_enums; - size_t count_types = psi_plist_count(check_types); - size_t count_structs = psi_plist_count(check_structs); - size_t count_unions = psi_plist_count(check_unions); - size_t count_enums = psi_plist_count(check_enums); - size_t count_all = count_types + count_structs + count_unions - + count_enums; - - if (check_count == count_all) { - /* nothing changed; bail out */ - if (count_all && (dst->flags & PSI_SILENT) && !(flags & PSI_SILENT)) { - /* one last error-spitting round, if not explicitly suppressed */ - dst->flags ^= PSI_SILENT; - check_count = ~0; - - PSI_DEBUG_PRINT(dst, "PSI: validation bail out with %zu" - " type checks remaining, errors follow\n", count_all); - continue; + if (decl->extvar) { + PSI_DUMP(dump, "/* extvar accessor\n"); } - check_count = 0; - } else { - recheck_types = count_types ? psi_plist_init(NULL) : NULL; - recheck_structs = count_structs ? psi_plist_init(NULL) : NULL; - recheck_unions = count_unions ? psi_plist_init(NULL) : NULL; - recheck_enums = count_enums ? psi_plist_init(NULL) : NULL; - - check_count = count_all; - src->errors = errors + check_count; - - PSI_DEBUG_PRINT(dst, "PSI: validate data(%p) %zu type checks remaining\n", - src, check_count); - - if (count_types) { - size_t i = 0; - struct psi_decl_arg *def; - - while (psi_plist_get(check_types, i++, &def)) { - *dst->last_error = 0; - dst->types = psi_plist_add(dst->types, &def); - PSI_DEBUG_PRINT(dst, "PSI: validate typedef %s ", def->var->name); - if (psi_decl_arg_validate_typedef(PSI_DATA(dst), def, &type_stack)) { - PSI_DEBUG_PRINT(dst, "%s\n", "✔"); - } else { - PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); - recheck_types = psi_plist_add(recheck_types, &def); - psi_plist_pop(dst->types, NULL); - } - } - } - if (count_structs) { - size_t i = 0; - struct psi_decl_struct *str; - - while (psi_plist_get(check_structs, i++, &str)) { - *dst->last_error = 0; - dst->structs = psi_plist_add(dst->structs, &str); - PSI_DEBUG_PRINT(dst, "PSI: validate struct %s ", str->name); - if (psi_decl_struct_validate(PSI_DATA(dst), str, &type_stack)) { - PSI_DEBUG_PRINT(dst, "%s ::(%zu, %zu)\n", "✔", str->align, str->size); - } else { - PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); - recheck_structs = psi_plist_add(recheck_structs, &str); - psi_plist_pop(dst->structs, NULL); - } - } - } - if (count_unions) { - size_t i = 0; - struct psi_decl_union *unn; - - while (psi_plist_get(check_unions, i++, &unn)) { - *dst->last_error = 0; - dst->unions = psi_plist_add(dst->unions, &unn); - PSI_DEBUG_PRINT(dst, "PSI: validate union %s ", unn->name); - if (psi_decl_union_validate(PSI_DATA(dst), unn, &type_stack)) { - PSI_DEBUG_PRINT(dst, "%s ::(%zu, %zu)\n", "✔", unn->align, unn->size); - - } else { - PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); - recheck_unions = psi_plist_add(recheck_unions, &unn); - psi_plist_pop(dst->unions, NULL); - } - } - } - if (count_enums) { - size_t i = 0; - struct psi_decl_enum *enm; - - while (psi_plist_get(check_enums, i++, &enm)) { - *dst->last_error = 0; - PSI_DEBUG_PRINT(dst, "PSI: validate enum %s ", enm->name); - if (psi_decl_enum_validate(PSI_DATA(dst), enm)) { - PSI_DEBUG_PRINT(dst, "%s\n", "✔"); - dst->enums = psi_plist_add(dst->enums, &enm); - } else { - PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); - recheck_enums = psi_plist_add(recheck_enums, &enm); - } - } - } - } - - if (check_types && check_types != src->types) { - psi_plist_free(check_types); - } - check_types = recheck_types; - if (check_structs && check_structs != src->structs) { - psi_plist_free(check_structs); - } - check_structs = recheck_structs; - if (check_unions && check_unions != src->unions) { - psi_plist_free(check_unions); - } - check_unions = recheck_unions; - if (check_enums && check_enums != src->enums) { - psi_plist_free(check_enums); - } - check_enums = recheck_enums; - } - - /* reset original flags */ - dst->flags = flags; - - if (src->consts) { - size_t i = 0; - struct psi_const *cnst; - - while (psi_plist_get(src->consts, i++, &cnst)) { - *dst->last_error = 0; - PSI_DEBUG_PRINT(dst, "PSI: validate const %s ", cnst->name); - if (psi_const_validate(PSI_DATA(dst), cnst)) { - PSI_DEBUG_PRINT(dst, "%s\n", "✔"); - dst->consts = psi_plist_add(dst->consts, &cnst); - } else { - PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); - ++src->errors; + psi_decl_dump(dump, decl); + PSI_DUMP(dump, "\n"); + if (decl->extvar) { + PSI_DUMP(dump, " extvar accessor */\n"); } } + PSI_DUMP(dump, "\n"); } - - if (src->decls) { + if (psi_plist_count(D->vars)) { size_t i = 0; - struct psi_decl *decl; + struct psi_decl_extvar *evar; - while (psi_plist_get(src->decls, i++, &decl)) { - *dst->last_error = 0; - PSI_DEBUG_PRINT(dst, "PSI: validate decl %s ", decl->func->var->name); - if (psi_decl_validate(PSI_DATA(dst), decl, dlopened, &type_stack)) { - PSI_DEBUG_PRINT(dst, "%s\n", "✔"); - dst->decls = psi_plist_add(dst->decls, &decl); - } else { - PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); - ++src->errors; - } + while (psi_plist_get(D->vars, i++, &evar)) { + psi_decl_extvar_dump(dump, evar); } + PSI_DUMP(dump, "\n"); } - - if (src->impls) { + if (psi_plist_count(D->impls)) { size_t i = 0; struct psi_impl *impl; - while (psi_plist_get(src->impls, i++, &impl)) { - *dst->last_error = 0; - PSI_DEBUG_PRINT(dst, "PSI: validate impl %s ", impl->func->name); - if (psi_impl_validate(PSI_DATA(dst), impl)) { - PSI_DEBUG_PRINT(dst, "%s\n", "✔"); - dst->impls = psi_plist_add(dst->impls, &impl); - } else { - PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); - ++src->errors; - } + while (psi_plist_get(D->impls, i++, &impl)) { + psi_impl_dump(dump, impl); + PSI_DUMP(dump, "\n"); } + PSI_DUMP(dump, "\n"); } - - psi_validate_stack_dtor(&type_stack); - - return true; } -