From: Michael Wallner Date: Tue, 12 Jan 2016 14:38:14 +0000 (+0100) Subject: flush X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=commitdiff_plain;h=7ecbe886921997a9ea3c990071c2efb97f13ac21 flush --- diff --git a/m4/netdb.m4 b/m4/netdb.m4 index 4043210..b14b54f 100644 --- a/m4/netdb.m4 +++ b/m4/netdb.m4 @@ -57,6 +57,9 @@ AC_DEFUN(PSI_CHECK_NETDB, [ PSI_CONST(NI_NUMERICSCOPE, int) PSI_CONST(NI_DGRAM, int) + PSI_CONST(NI_MAXHOST, int) + PSI_CONST(NI_MAXSERV, int) + PSI_CONST(EAI_AGAIN, int) PSI_CONST(EAI_BADFLAGS, int) PSI_CONST(EAI_FAIL, int) @@ -76,7 +79,7 @@ AC_DEFUN(PSI_CHECK_NETDB, [ PSI_DECL(char *gai_strerror, [(int errcode)]) PSI_DECL(int getaddrinfo, [(char *node, char *service, struct addrinfo *hints, struct addrinfo **res)]) PSI_DECL(struct hostent *gethostent, [(void)]) - PSI_DECL(int getnameinfo, [(struct sockaddr *sa, socklen_t salen, char *host, socklen_t host_len, char *serv, socklen_t servlen, int flags)]) + PSI_DECL(int getnameinfo, [(struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)]) PSI_DECL(struct netent *getnetbyaddr, [(uint32_t net, int type)]) PSI_DECL(struct netent *getnetbyname, [(char *name)]) PSI_DECL(struct netent *getnetent, [(void)]) diff --git a/psi.d/netdb.psi b/psi.d/netdb.psi index dd81ed8..259fcec 100644 --- a/psi.d/netdb.psi +++ b/psi.d/netdb.psi @@ -43,7 +43,7 @@ function psi\gai_strerror(int $errcode) : string { return to_string(gai_strerror); } -// extern int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); +// extern int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) function psi\getaddrinfo(string $node, string $service, array $hints, object &$res = NULL) : int { let node = strval($node); let service = strval($service); @@ -61,4 +61,18 @@ function psi\getaddrinfo(string $node, string $service, array $hints, object &$r to_array(*ai_next, ...) ); free freeaddrinfo(res); -} \ No newline at end of file +} + +// extern int getnameinfo(struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags) +function psi\getnameinfo(string $addr, string &$host = NULL, string &$service = NULL, int $flags = 0) : int { + let sa = strval($addr); + let salen = strlen($addr); + let hostlen = psi\NI_MAXHOST; + let host = calloc(hostlen, psi\SIZEOF_CHAR); + let servlen = psi\NI_MAXSERV; + let serv = calloc(servlen, psi\SIZEOF_CHAR); + let flags = intval($flags); + return to_int(getnameinfo); + set $host = to_string(host); + set $service = to_string(serv); +} diff --git a/src/context.c b/src/context.c index c3f1cb1..4a4f472 100644 --- a/src/context.c +++ b/src/context.c @@ -957,6 +957,33 @@ static inline int validate_impl_stmts(PSI_Data *data, impl *impl) { return 1; } +static inline int validate_impl_args(PSI_Data *data, impl *impl) { + int def = 0; + size_t i; + + for (i = 0; i < impl->func->args->count; ++i) { + impl_arg *iarg = impl->func->args->args[i]; + + if (iarg->def) { + def = 1; + } else if (def) { + data->error(impl->func->token, PSI_WARNING, + "Non-optional argument %zu '$%s' of implementation '%s'" + " follows optional argument", + i+1, iarg->var->name, impl->func->name); + return 0; + } + } + + return 1; +} +static inline int validate_impl(PSI_Data *data, impl *impl) { + if (!validate_impl_args(data, impl)) { + return 0; + } + return validate_impl_stmts(data, impl); +} + PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error) { size_t i; @@ -1153,7 +1180,7 @@ int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P) size_t i; for (i = 0; i < D->impls->count; ++i) { - if (validate_impl_stmts(PSI_DATA(C), D->impls->list[i])) { + if (validate_impl(PSI_DATA(C), D->impls->list[i])) { C->impls = add_impl(C->impls, D->impls->list[i]); } } diff --git a/src/module.c b/src/module.c index 152c949..2257a0d 100644 --- a/src/module.c +++ b/src/module.c @@ -144,6 +144,7 @@ zend_internal_arg_info *psi_internal_arginfo(impl *impl) zend_internal_arg_info *ai = &aip[impl->func->args->count]; ai->name = vararg->var->name; + ai->allow_null = 1; ai->type_hint = psi_internal_type(vararg->type); if (vararg->var->reference) { ai->pass_by_reference = 1; @@ -160,9 +161,9 @@ zend_internal_arg_info *psi_internal_arginfo(impl *impl) if (iarg->var->reference) { ai->pass_by_reference = 1; } - if (iarg->var->reference || (iarg->def && iarg->def->type == PSI_T_NULL)) { + //if (iarg->var->reference || (iarg->def && iarg->def->type == PSI_T_NULL)) { ai->allow_null = 1; - } + //} } return aip; @@ -636,7 +637,7 @@ static inline ZEND_RESULT_CODE psi_let_val(token_t let_func, impl_arg *iarg, imp case PSI_T_STRVAL: if (iarg->type->type == PSI_T_STRING) { if (iarg->val.zend.str) { - arg_val->ptr = estrdup(iarg->val.zend.str->val); + arg_val->ptr = estrndup(iarg->val.zend.str->val, iarg->val.zend.str->len); *to_free = arg_val->ptr; } else { arg_val->ptr = ""; @@ -767,6 +768,22 @@ static inline void psi_do_free(free_stmt *fre) } } +static inline void psi_clean_array_struct(decl_arg *darg) { + if (darg->let + && darg->let->val->kind == PSI_LET_FUNC + && darg->let->val->data.func->type == PSI_T_ARRVAL) { + decl_type *type = real_decl_type(darg->type); + + if (type->type == PSI_T_STRUCT) { + void **ptr = (void **) ((char *) darg->mem + type->strct->size); + + while (*ptr) { + efree(*ptr++); + } + } + } +} + static inline void psi_do_clean(impl *impl) { size_t i; @@ -787,15 +804,7 @@ static inline void psi_do_clean(impl *impl) decl_arg *darg = impl->decl->args->args[i]; if (darg->mem) { - decl_type *type = real_decl_type(darg->type); - - if (type->type == PSI_T_STRUCT) { - void **ptr = (void **) ((char *) darg->mem + type->strct->size); - - while (*ptr) { - efree(*ptr++); - } - } + psi_clean_array_struct(darg); efree(darg->mem); darg->mem = NULL; } diff --git a/tests/netdb/gai001.phpt b/tests/netdb/gai001.phpt new file mode 100644 index 0000000..42e83fc --- /dev/null +++ b/tests/netdb/gai001.phpt @@ -0,0 +1,38 @@ +--TEST-- +getaddrinfo +--INI-- +psi.directory={PWD}:{PWD}/../../psi.d +--SKIPIF-- + +--FILE-- +===TEST=== + +===DONE=== +--EXPECT-- +===TEST=== +int(0) +string(12) "78.46.223.30" +string(1) "0" +int(0) +string(12) "78.46.223.30" +string(1) "0" +int(0) +string(12) "78.46.223.30" +string(1) "0" +===DONE=== \ No newline at end of file