From: Michael Wallner Date: Fri, 6 Nov 2015 09:41:47 +0000 (+0100) Subject: flush X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=commitdiff_plain;h=7474b3e23338ea03bcd65551959e2582cc455f9f flush --- diff --git a/php_psi.h b/php_psi.h index 2982402..f9e89b7 100644 --- a/php_psi.h +++ b/php_psi.h @@ -37,7 +37,7 @@ void psi_to_double(zval *return_value, token_t t, impl_val *ret_val, decl_var *v void psi_to_string(zval *return_value, token_t t, impl_val *ret_val, decl_var *var); ZEND_RESULT_CODE psi_parse_args(zend_execute_data *execute_data, impl *impl); -impl_val *psi_do_let(decl_arg *darg); +void *psi_do_let(decl_arg *darg); void psi_do_set(zval *return_value, set_func *func, decl_vars *vars); void psi_do_return(impl *impl, impl_val *ret_val, zval *return_value); void psi_do_free(free_stmt *fre); diff --git a/src/libffi.c b/src/libffi.c index 897affb..b0100f6 100644 --- a/src/libffi.c +++ b/src/libffi.c @@ -48,7 +48,7 @@ static void psi_ffi_closure_free(void *c) #endif } -static void handler(ffi_cif *signature, void *_result, void **_args, void *_data); +static void psi_ffi_handler(ffi_cif *signature, void *_result, void **_args, void *_data); static inline ffi_abi psi_ffi_abi(const char *convention) { return FFI_DEFAULT_ABI; @@ -149,12 +149,12 @@ static inline PSI_LibffiData *PSI_LibffiDataAlloc(PSI_LibffiContext *context, im rc = ffi_prep_closure_loc( data->closure, &context->signature, - handler, + psi_ffi_handler, data, data->code); ZEND_ASSERT(FFI_OK == rc); #elif PSI_HAVE_FFI_PREP_CLOSURE - rc = ffi_prep_closure(data->code, &context->signature, handler, data); + rc = ffi_prep_closure(data->code, &context->signature, psi_ffi_handler, data); ZEND_ASSERT(FFI_OK == rc); #else # error "Neither ffi_prep_closure() nor ffi_prep_closure_loc() available" @@ -207,11 +207,11 @@ static inline void PSI_LibffiContextFree(PSI_LibffiContext **L) { } } -static void handler(ffi_cif *_sig, void *_result, void **_args, void *_data) +static void psi_ffi_handler(ffi_cif *_sig, void *_result, void **_args, void *_data) { PSI_LibffiData *data = _data; size_t i; - void **arg_ptr = NULL, **arg_prm = NULL; + void **arg_prm = NULL; impl_val ret_val; if (SUCCESS != psi_parse_args(*(zend_execute_data **)_args[0], data->impl)) { @@ -219,17 +219,12 @@ static void handler(ffi_cif *_sig, void *_result, void **_args, void *_data) } if (data->impl->decl->args) { - arg_ptr = malloc(data->impl->decl->args->count * sizeof(*arg_ptr)); arg_prm = malloc(data->impl->decl->args->count * sizeof(*arg_prm)); for (i = 0; i < data->impl->decl->args->count; ++i) { decl_arg *darg = data->impl->decl->args->args[i]; - arg_ptr[i] = psi_do_let(darg); - arg_prm[i] = (darg->let->val && darg->let->val->is_reference) - ? &arg_ptr[i] : arg_ptr[i]; - - darg->let->ptr = arg_ptr[i]; + arg_prm[i] = psi_do_let(darg); } } @@ -253,25 +248,22 @@ static void handler(ffi_cif *_sig, void *_result, void **_args, void *_data) psi_do_clean(data->impl); - if (arg_ptr) { - free(arg_ptr); - } if (arg_prm) { free(arg_prm); } } -static void init(PSI_Context *C) +static void psi_ffi_init(PSI_Context *C) { C->context = PSI_LibffiContextInit(NULL); } -static void dtor(PSI_Context *C) +static void psi_ffi_dtor(PSI_Context *C) { PSI_LibffiContextFree((void *) &C->context); } -static zend_function_entry *compile(PSI_Context *C, PSI_Data *D) +static zend_function_entry *psi_ffi_compile(PSI_Context *C, PSI_Data *D) { size_t i, j = 0; zend_function_entry *zfe = calloc(D->impls->count + 1, sizeof(*zfe)); @@ -297,9 +289,9 @@ static zend_function_entry *compile(PSI_Context *C, PSI_Data *D) } static PSI_ContextOps ops = { - init, - dtor, - compile, + psi_ffi_init, + psi_ffi_dtor, + psi_ffi_compile, }; PSI_ContextOps *PSI_Libffi(void) diff --git a/src/libjit.c b/src/libjit.c index 9e43fd2..fd68c50 100644 --- a/src/libjit.c +++ b/src/libjit.c @@ -4,7 +4,7 @@ #include -static void handler(jit_type_t _sig, void *result, void **_args, void *_data); +static void psi_jit_handler(jit_type_t _sig, void *result, void **_args, void *_data); static inline jit_abi_t psi_jit_abi(const char *convention) { return jit_abi_cdecl; @@ -94,7 +94,7 @@ static inline PSI_LibjitData *PSI_LibjitDataAlloc(PSI_LibjitContext *context, im data->params, data->impl->decl->args->count, 1); - data->closure = jit_closure_create(context->jit, context->signature, &handler, data); + data->closure = jit_closure_create(context->jit, context->signature, &psi_jit_handler, data); context->data.list = realloc(context->data.list, ++context->data.count * sizeof(*context->data.list)); context->data.list[context->data.count-1] = data; @@ -146,11 +146,11 @@ static inline void PSI_LibjitContextFree(PSI_LibjitContext **L) { } } -static void handler(jit_type_t _sig, void *result, void **_args, void *_data) +static void psi_jit_handler(jit_type_t _sig, void *result, void **_args, void *_data) { PSI_LibjitData *data = _data; size_t i; - void **arg_ptr = NULL, **arg_prm = NULL; + void **arg_prm = NULL; impl_val ret_val; if (SUCCESS != psi_parse_args(*(zend_execute_data **)_args[0], data->impl)) { @@ -158,16 +158,12 @@ static void handler(jit_type_t _sig, void *result, void **_args, void *_data) } if (data->impl->decl->args->count) { - arg_ptr = malloc(data->impl->decl->args->count * sizeof(*arg_ptr)); arg_prm = malloc(data->impl->decl->args->count * sizeof(*arg_prm)); for (i = 0; i < data->impl->decl->args->count; ++i) { decl_arg *darg = data->impl->decl->args->args[i]; - arg_ptr[i] = psi_do_let(darg); - arg_prm[i] = darg->let->val->is_reference ? &arg_ptr[i] : arg_ptr[i]; - - darg->let->ptr = arg_ptr[i]; + arg_prm[i] = psi_do_let(darg); } } @@ -191,25 +187,22 @@ static void handler(jit_type_t _sig, void *result, void **_args, void *_data) psi_do_clean(data->impl); - if (arg_ptr) { - free(arg_ptr); - } if (arg_prm) { free(arg_prm); } } -static void init(PSI_Context *C) +static void psi_jit_init(PSI_Context *C) { C->context = PSI_LibjitContextInit(NULL); } -static void dtor(PSI_Context *C) +static void psi_jit_dtor(PSI_Context *C) { PSI_LibjitContextFree((void *) &C->context); } -static zend_function_entry *compile(PSI_Context *C, PSI_Data *D) +static zend_function_entry *psi_jit_compile(PSI_Context *C, PSI_Data *D) { size_t i, j = 0; zend_function_entry *zfe = calloc(D->impls->count + 1, sizeof(*zfe)); @@ -239,9 +232,9 @@ static zend_function_entry *compile(PSI_Context *C, PSI_Data *D) } static PSI_ContextOps ops = { - init, - dtor, - compile, + psi_jit_init, + psi_jit_dtor, + psi_jit_compile, }; PSI_ContextOps *PSI_Libjit(void) diff --git a/src/module.c b/src/module.c index 2705df1..03d9d83 100644 --- a/src/module.c +++ b/src/module.c @@ -316,6 +316,7 @@ void psi_from_zval(impl_val *mem, decl_arg *spec, zval *zv, void **tmp) zend_string_release(zs); break; } + /* no break */ default: mem->zend.lval = zval_get_long(zv); break; @@ -327,7 +328,7 @@ void *psi_array_to_struct(decl_struct *s, HashTable *arr) size_t i, j = 0, size = decl_struct_size(s); char *mem = ecalloc(1, size + s->args->count * sizeof(void *)); - for (i = 0; i < s->args->count; ++i) { + if (arr) for (i = 0; i < s->args->count; ++i) { decl_struct_layout *layout = &s->layout[i]; decl_arg *darg = s->args->args[i]; zval *entry = zend_hash_str_find_ind(arr, darg->var->name, strlen(darg->var->name)); @@ -365,7 +366,7 @@ void psi_to_array(zval *return_value, token_t t, impl_val *ret_val, decl_var *va decl_struct_layout layout = s->layout[i]; impl_val tmp; zval ztmp; - char *ptr = (char *) ret_val + layout.pos; + char *ptr = (char *) ret_val->ptr + layout.pos; memset(&tmp, 0, sizeof(tmp)); memcpy(&tmp, ptr, layout.len); @@ -375,7 +376,7 @@ void psi_to_array(zval *return_value, token_t t, impl_val *ret_val, decl_var *va psi_to_string(&ztmp, real_decl_type(darg->type)->type, &tmp, darg->var); break; } - /* nobreak */ + /* no break */ case PSI_T_INT: case PSI_T_LONG: psi_to_int(&ztmp, real_decl_type(darg->type)->type, &tmp, darg->var); @@ -481,10 +482,13 @@ void *psi_do_calloc(let_calloc *alloc) return ecalloc(alloc->n, size); } -impl_val *psi_do_let(decl_arg *darg) +void *psi_do_let(decl_arg *darg) { - impl_val *arg_val = &darg->let->out; impl_arg *iarg = darg->let->arg; + impl_val *arg_val; + + darg->let->ptr = &darg->let->out; + arg_val = darg->let->ptr; if (!iarg) { /* let foo = calloc(1, long); @@ -500,62 +504,66 @@ impl_val *psi_do_let(decl_arg *darg) } else { memset(arg_val, 0, sizeof(*arg_val)); } - return arg_val; - } - - switch (darg->let->val->func->type) { - case PSI_T_BOOLVAL: - if (iarg->type->type == PSI_T_BOOL) { - arg_val->cval = iarg->val.zend.bval; - } else { - arg_val->cval = zend_is_true(iarg->_zv); - } - break; - case PSI_T_INTVAL: - if (iarg->type->type == PSI_T_INT || iarg->type->type == PSI_T_LONG) { - arg_val->lval = iarg->val.zend.lval; - } else { - arg_val->lval = zval_get_long(iarg->_zv); - } - break; - case PSI_T_STRVAL: - if (iarg->type->type == PSI_T_STRING) { - arg_val->ptr = estrdup(iarg->val.zend.str->val); - darg->let->mem = arg_val->ptr; - zend_string_release(iarg->val.zend.str); - } else { - zend_string *zs = zval_get_string(iarg->_zv); - arg_val->ptr = estrdup(zs->val); - darg->let->mem = arg_val->ptr; - zend_string_release(zs); - } - break; - case PSI_T_STRLEN: - if (iarg->type->type == PSI_T_STRING) { - arg_val->lval = iarg->val.zend.str->len; - zend_string_release(iarg->val.zend.str); - } else { - zend_string *zs = zval_get_string(iarg->_zv); - arg_val->lval = zs->len; - zend_string_release(zs); - } - break; - case PSI_T_ARRVAL: - if (iarg->type->type == PSI_T_ARRAY) { - decl_type *type = real_decl_type(darg->type); + } else { - switch (type->type) { - case PSI_T_STRUCT: - arg_val->ptr = psi_array_to_struct(type->strct, HASH_OF(iarg->_zv)); + switch (darg->let->val->func->type) { + case PSI_T_BOOLVAL: + if (iarg->type->type == PSI_T_BOOL) { + arg_val->cval = iarg->val.zend.bval; + } else { + arg_val->cval = zend_is_true(iarg->_zv); + } + break; + case PSI_T_INTVAL: + if (iarg->type->type == PSI_T_INT || iarg->type->type == PSI_T_LONG) { + arg_val->lval = iarg->val.zend.lval; + } else { + arg_val->lval = zval_get_long(iarg->_zv); + } + break; + case PSI_T_STRVAL: + if (iarg->type->type == PSI_T_STRING) { + arg_val->ptr = estrdup(iarg->val.zend.str->val); darg->let->mem = arg_val->ptr; - break; + zend_string_release(iarg->val.zend.str); + } else { + zend_string *zs = zval_get_string(iarg->_zv); + arg_val->ptr = estrdup(zs->val); + darg->let->mem = arg_val->ptr; + zend_string_release(zs); + } + break; + case PSI_T_STRLEN: + if (iarg->type->type == PSI_T_STRING) { + arg_val->lval = iarg->val.zend.str->len; + zend_string_release(iarg->val.zend.str); + } else { + zend_string *zs = zval_get_string(iarg->_zv); + arg_val->lval = zs->len; + zend_string_release(zs); + } + break; + case PSI_T_ARRVAL: + if (iarg->type->type == PSI_T_ARRAY) { + decl_type *type = real_decl_type(darg->type); + + switch (type->type) { + case PSI_T_STRUCT: + arg_val->ptr = psi_array_to_struct(type->strct, HASH_OF(iarg->_zv)); + darg->let->mem = arg_val->ptr; + break; + } } + break; + EMPTY_SWITCH_DEFAULT_CASE(); } - break; - EMPTY_SWITCH_DEFAULT_CASE(); } - return arg_val; + if (darg->let->val && darg->let->val->is_reference) { + return &darg->let->ptr; + } else { + return darg->let->ptr; + } } void psi_do_set(zval *return_value, set_func *func, decl_vars *vars) diff --git a/src/parser.h b/src/parser.h index 7424414..cd1e0d4 100644 --- a/src/parser.h +++ b/src/parser.h @@ -950,3 +950,4 @@ void PSI_ParserDtor(PSI_Parser *P); void PSI_ParserFree(PSI_Parser **P); #endif + diff --git a/src/parser_proc.h b/src/parser_proc.h index 3d86e2b..5940f92 100644 --- a/src/parser_proc.h +++ b/src/parser_proc.h @@ -1,9 +1,9 @@ -#define PSI_T_COMMENT 1 -#define PSI_T_LIB 2 -#define PSI_T_QUOTED_STRING 3 -#define PSI_T_EOS 4 -#define PSI_T_STRUCT 5 -#define PSI_T_NAME 6 +#define PSI_T_NAME 1 +#define PSI_T_COMMENT 2 +#define PSI_T_LIB 3 +#define PSI_T_QUOTED_STRING 4 +#define PSI_T_EOS 5 +#define PSI_T_STRUCT 6 #define PSI_T_LBRACE 7 #define PSI_T_RBRACE 8 #define PSI_T_BOOL 9 diff --git a/src/parser_proc.y b/src/parser_proc.y index efffcf7..62e8011 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -17,6 +17,9 @@ %syntax_error { PSI_ParserSyntaxError(P, P->fn, P->line, "Unexpected token '%s'", TOKEN->text); } + +%nonassoc NAME. + file ::= blocks. blocks ::= block. @@ -240,6 +243,11 @@ decl_type(type_) ::= NAME(T). { type_ = init_decl_type(T->type, T->text); free(T); } +decl_type(type_) ::= STRUCT(S) NAME(T). { + type_ = init_decl_type(S->type, T->text); + free(S); + free(T); +} %type impl {impl*} %destructor impl {free_impl($$);} diff --git a/src/validator.c b/src/validator.c index 510bba1..128b2ac 100644 --- a/src/validator.c +++ b/src/validator.c @@ -215,8 +215,15 @@ static inline int validate_struct(PSI_Validator *V, decl_struct *s) { s->layout = calloc(s->args->count, sizeof(*s->layout)); for (i = 0; i < s->args->count; ++i) { decl_arg *darg = s->args->args[i]; - decl_type *type = real_decl_type(darg->type); - token_t t = darg->var->pointer_level ? PSI_T_POINTER : type->type; + token_t t; + + if (!validate_decl_arg(V, darg)) { + return 0; + } + + t = darg->var->pointer_level + ? PSI_T_POINTER + : real_decl_type(darg->type)->type; if (i) { decl_struct_layout *l = &s->layout[i-1]; @@ -278,50 +285,38 @@ static inline decl *locate_impl_decl(decls *decls, return_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 - * - we can have multiple let stmts; every arg of the ret stmts var (the function to call) must have one - * - we can have any count of set stmts; processing out vars - * - we can have any count of free stmts; freeing any out vars - */ - size_t i, j, k; - return_stmt *ret; - decl *decl; - - if (!stmts) { - V->error(PSI_WARNING, "Missing body for implementation %s!", - impl->func->name); - return 0; - } - if (stmts->ret.count != 1) { - if (stmts->ret.count > 1) { - V->error(PSI_WARNING, "Too many `ret` statements for implmentation %s;" +static inline int validate_impl_ret_stmt(PSI_Validator *V, impl *impl) { + /* we must have exactly one ret stmt delcaring the native func to call */ + /* and which type cast to apply */ + if (impl->stmts->ret.count != 1) { + if (impl->stmts->ret.count > 1) { + V->error(PSI_WARNING, "Too many `return` statements for implmentation %s;" " found %zu, exactly one is needed", - impl->func->name, stmts->ret.count); + impl->func->name, impl->stmts->ret.count); } else { - V->error(PSI_WARNING, "Missing `ret` statement for implementation %s", + V->error(PSI_WARNING, "Missing `return` statement for implementation %s", impl->func->name); } return 0; } - - ret = stmts->ret.list[0]; - decl = locate_impl_decl(V->decls, ret); - if (!decl) { + if (!(impl->decl = locate_impl_decl(V->decls, impl->stmts->ret.list[0]))) { V->error(PSI_WARNING, "Missing declaration for implementation %s", impl->func->name); return 0; } + return 1; +} +static inline int validate_impl_let_stmts(PSI_Validator *V, impl *impl) { + size_t i, j; + /* we can have multiple let stmts */ /* check that we have a let stmt for every decl arg */ - if (decl->args) for (i = 0; i < decl->args->count; ++i) { - decl_arg *darg = decl->args->args[i]; + if (impl->decl->args) for (i = 0; i < impl->decl->args->count; ++i) { + decl_arg *darg = impl->decl->args->args[i]; int check = 0; - for (j = 0; j < stmts->let.count; ++j) { - let_stmt *let = stmts->let.list[j]; + for (j = 0; j < impl->stmts->let.count; ++j) { + let_stmt *let = impl->stmts->let.list[j]; if (!strcmp(let->var->name, darg->var->name)) { darg->let = let; @@ -333,13 +328,13 @@ static inline int validate_impl_stmts(PSI_Validator *V, impl *impl, impl_stmts * 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); + darg->var->name, impl->decl->func->var->name, impl->func->name); return 0; } } /* 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]; + for (i = 0; i < impl->stmts->let.count; ++i) { + let_stmt *let = impl->stmts->let.list[i]; int check = 0; if (let->val && let->val->func && let->val->func->alloc) { @@ -367,9 +362,14 @@ static inline int validate_impl_stmts(PSI_Validator *V, impl *impl, impl_stmts * } } } + return 1; +} +static inline int validate_impl_set_stmts(PSI_Validator *V, impl *impl) { + size_t i, j, k; + /* we can have any count of set stmts; processing out vars */ /* check that set stmts reference known variables */ - for (i = 0; i < stmts->set.count; ++i) { - set_stmt *set = stmts->set.list[i]; + for (i = 0; i < impl->stmts->set.count; ++i) { + set_stmt *set = impl->stmts->set.list[i]; int check = 0; if (impl->func->args) for (j = 0; j < impl->func->args->count; ++j) { @@ -392,8 +392,8 @@ static inline int validate_impl_stmts(PSI_Validator *V, impl *impl, impl_stmts * decl_var *set_var = set->val->vars->vars[j]; check = 0; - if (decl->args) for (k = 0; k < decl->args->count; ++k) { - decl_arg *set_arg = decl->args->args[k]; + if (impl->decl->args) for (k = 0; k < impl->decl->args->count; ++k) { + decl_arg *set_arg = impl->decl->args->args[k]; if (!strcmp(set_var->name, set_arg->var->name)) { check = 1; @@ -410,19 +410,23 @@ static inline int validate_impl_stmts(PSI_Validator *V, impl *impl, impl_stmts * } } } - /* check free stmts */ - for (i = 0; i < stmts->fre.count; ++i) { - free_stmt *fre = stmts->fre.list[i]; + return 1; +} +static inline int validate_impl_free_stmts(PSI_Validator *V, impl *impl) { + size_t i, j, k; + /* we can have any count of free stmts; freeing any out vars */ + for (i = 0; i < impl->stmts->fre.count; ++i) { + free_stmt *fre = impl->stmts->fre.list[i]; for (j = 0; j < fre->vars->count; ++j) { decl_var *free_var = fre->vars->vars[j]; int check = 0; - if (!strcmp(free_var->name, decl->func->var->name)) { + if (!strcmp(free_var->name, impl->decl->func->var->name)) { continue; } - if (decl->args) for (k = 0; k < decl->args->count; ++k) { - decl_arg *free_arg = decl->args->args[k]; + if (impl->decl->args) for (k = 0; k < impl->decl->args->count; ++k) { + decl_arg *free_arg = impl->decl->args->args[k]; if (!strcmp(free_var->name, free_arg->var->name)) { check = 1; @@ -439,8 +443,28 @@ static inline int validate_impl_stmts(PSI_Validator *V, impl *impl, impl_stmts * } } } + return 1; +} +static inline int validate_impl_stmts(PSI_Validator *V, impl *impl) { + if (!impl->stmts) { + V->error(PSI_WARNING, "Missing body for implementation %s!", + impl->func->name); + return 0; + } - impl->decl = decl; + if (!validate_impl_ret_stmt(V, impl)) { + return 0; + } + + if (!validate_impl_let_stmts(V, impl)) { + return 0; + } + if (!validate_impl_set_stmts(V, impl)) { + return 0; + } + if (!validate_impl_free_stmts(V, impl)) { + return 0; + } return 1; } @@ -449,7 +473,7 @@ static inline int validate_impl(PSI_Validator *V, impl *impl) { if (!validate_impl_func(V, impl, impl->func)) { return 0; } - if (!validate_impl_stmts(V, impl, impl->stmts)) { + if (!validate_impl_stmts(V, impl)) { return 0; } return 1; diff --git a/tests/time/time.psi b/tests/time/time.psi new file mode 100644 index 0000000..5a9b2b0 --- /dev/null +++ b/tests/time/time.psi @@ -0,0 +1,61 @@ +typedef long time_t; +typedef int suseconds_t; + +struct timespec { + time_t tv_sec; + long tv_nsec; +} + +struct timeval { + time_t tv_sec; + suseconds_t tv_usec; +} + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +} + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long tm_gmtoff; + char *tm_zone; +} + +extern int gettimeofday(struct timeval *tv, struct timezone *tz); +function psi\gettimeofday(array &$tv = NULL, array &$tz = NULL) : int { + let tv = calloc(1, struct timeval); + let tz = calloc(1, struct timezone); + return to_int(gettimeofday); + set $tv = to_array(*tv); + set $tz = to_array(*tz); +} + +extern char *asctime(struct tm *tm); +function psi\asctime(array $tm = NULL) : string { + let tm = arrval($tm); + return to_string(asctime); +} + + +extern struct tm *gmtime(time_t tp); +function psi\gmtime(int $ts) : array { + let tp = &intval($ts); + return to_array(gmtime); +} + +extern int nanosleep(struct timespec *rqtp, struct timespec *rmtp); +function psi\nanosleep(array $rq = NULL, array &$rm = NULL) : int { + let rqtp = arrval($rq); + let rmtp = calloc(1, struct timespec); + return to_int(nanosleep); + set $rm = to_array(*rmtp); +} diff --git a/tests/time/time001.phpt b/tests/time/time001.phpt new file mode 100644 index 0000000..8c35eb9 --- /dev/null +++ b/tests/time/time001.phpt @@ -0,0 +1,57 @@ +--TEST-- +gettimeofday +--INI-- +psi.directory = {PWD} +--SKIPIF-- + +--FILE-- +===TEST=== + +===DONE=== +--EXPECTF-- +===TEST=== +array(4) { + ["sec"]=> + int(1%d) + ["usec"]=> + int(%d) + ["minuteswest"]=> + int(%d) + ["dsttime"]=> + int(%d) +} +int(0) +int(0) +array(2) { + ["tv_sec"]=> + int(1%d) + ["tv_usec"]=> + int(%d) +} +int(0) +array(2) { + ["tv_sec"]=> + int(1%d) + ["tv_usec"]=> + int(%d) +} +array(2) { + ["tz_minuteswest"]=> + int(%d) + ["tz_dsttime"]=> + int(%d) +} +bool(true) +===DONE=== + \ No newline at end of file diff --git a/tests/time/time002.phpt b/tests/time/time002.phpt new file mode 100644 index 0000000..6e091e0 --- /dev/null +++ b/tests/time/time002.phpt @@ -0,0 +1,24 @@ +--TEST-- +asctime/gmtime +--SKIPIF-- + +--ENV-- +TZ=UTC +--INI-- +psi.directory = {PWD} +--FILE-- +===TEST=== + +===DONE=== +--EXPECT-- +===TEST=== +string(25) "Sun Jan 0 00:00:00 1900 +" +string(25) "Fri Feb 13 23:31:30 2009 +" +===DONE=== diff --git a/tests/time/time003.phpt b/tests/time/time003.phpt new file mode 100644 index 0000000..1fe5073 --- /dev/null +++ b/tests/time/time003.phpt @@ -0,0 +1,44 @@ +--TEST-- +nanosleep +--SKIPIF-- + +--ENV-- +TZ=UTC +--INI-- +psi.directory = {PWD} +--FILE-- +===TEST=== + 10000000], $rm), $rm); +var_dump(psi\gettimeofday($tv2), $tv2); +var_dump($tv2["tv_usec"]-$tv1["tv_usec"]); +?> +===DONE=== +--EXPECTF-- +===TEST=== +int(0) +array(2) { + ["tv_sec"]=> + int(1%d) + ["tv_usec"]=> + int(%d) +} +int(0) +array(2) { + ["tv_sec"]=> + int(0) + ["tv_nsec"]=> + int(0) +} +int(0) +array(2) { + ["tv_sec"]=> + int(%d) + ["tv_usec"]=> + int(%d) +} +int(10%r\d\d\d%r) +===DONE===