)
PSI_CONST(AF_INET, int)
+ PSI_CONST(AF_INET6, int)
PSI_CONST(AF_UNIX, int)
PSI_CONST(AF_UNSPEC, int)
PSI_CONST(MSG_CTRUNC, int)
to_int(gl_pathc),
to_int(gl_offs),
to_int(gl_flags),
- to_array(**gl_pathv, gl_pathc + gl_offs, to_string(*gl_pathv))
+ to_array(gl_pathv, gl_pathc + gl_offs, to_string(gl_pathv))
);
free globfree(buf);
}
return void(endservent);
}
+function psi\sethostent(bool $stayopen) : void {
+ let stayopen = intval($stayopen);
+ return void(sethostent);
+}
+function psi\setnetset(bool $stayopen) : void {
+ let stayopen = intval($stayopen);
+ return void(setnetent);
+}
+function psi\setprotoent(bool $stayopen) : void {
+ let stayopen = intval($stayopen);
+ return void(setprotoent);
+}
+function psi\setservent(bool $stayopen) : void {
+ let stayopen = intval($stayopen);
+ return void(setservent);
+}
+
+function psi\gethostent() : array {
+ return to_array(gethostent,
+ to_string(h_name),
+ to_array(h_aliases, to_string(h_aliases)),
+ to_int(h_addrtype),
+ to_int(h_length),
+ to_array(h_addr_list, to_string(h_addr_list, h_length))
+ );
+}
+
function psi\gai_strerror(int $errcode) : string {
let errcode = intval($errcode);
return to_string(gai_strerror);
}
+// 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);
let hints = arrval($hints);
let res = &NULL;
return to_int(getaddrinfo);
- set $res = to_array(*res,
+ set $res = to_array(**res,
to_int(ai_flags),
to_int(ai_family),
to_int(ai_socktype),
to_int(ai_addrlen),
to_string(ai_addr, ai_addrlen),
to_string(ai_canonname),
- to_array(ai_next, ...)
+ to_array(*ai_next, ...)
);
free freeaddrinfo(res);
}
\ No newline at end of file
function psi\fopen(string $path, string $mode) : object {
let path = pathval($path);
let mode = strval($mode);
- return to_object(*fopen);
+ return to_object(fopen);
}
// extern int fclose(FILE *stream);
function psi\times(array &$tms = NULL) : int {
let buf = calloc(1, psi\SIZEOF_STRUCT_TMS);
return to_int(times);
- set $tms = to_array(*buf,
+ set $tms = to_array(buf,
to_int(tms_utime),
to_int(tms_stime),
to_int(tms_cutime),
to_string(version),
to_string(machine),
to_string(domainname));
-}
\ No newline at end of file
+}
PSI_MACROS
+struct utsname *uname2() {
+ struct utsname *u = calloc(1, sizeof(*u));
+ uname(u);
+ return u;
+}
+
int psi_glob(const char *pattern, int flags,
int (*errfunc) (const char *epath, int eerrno),
glob_t *pglob) {
void (*func)(void);
} psi_func_redirs[] = {
{"glob", (void (*)(void)) psi_glob},
+ {"uname2", (void (*)(void)) uname2},
PSI_REDIRS
{0}
};
case PSI_T_ELLIPSIS:
if (set->outer.set && set->outer.set->func->type == PSI_T_TO_ARRAY) {
set->func->handler = psi_to_recursive;
+ set->inner = set->outer.set->inner;
+ set->count = set->outer.set->count;
break;
}
/* no break */
if (ref_type->type == PSI_T_STRUCT) {
/* to_array(struct, to_...) */
- for (i = 0; i < set->count; ++i) {
- decl_var *sub_var = set->inner[i]->vars->vars[0];
- decl_arg *sub_ref = locate_struct_member(ref_type->strct, sub_var);
-
- if (sub_ref) {
- if (!validate_set_value_ex(data, set->inner[i], sub_ref, ref_type->strct->args)) {
- return 0;
+ if (!set->outer.set || set->outer.set->inner != set->inner) {
+ for (i = 0; i < set->count; ++i) {
+ decl_var *sub_var = set->inner[i]->vars->vars[0];
+ decl_arg *sub_ref = locate_struct_member(ref_type->strct, sub_var);
+
+ if (sub_ref) {
+ if (!validate_set_value_ex(data, set->inner[i], sub_ref, ref_type->strct->args)) {
+ return 0;
+ }
}
}
}
free_call->func, impl->func->name);
return 0;
}
- if (!impl->decl->args) {
- data->error(free_call->token, PSI_WARNING,
- "Declaration '%s' of implementation '%s'"
- " does not have any arguments to free",
- impl->decl->func->var->name, impl->func->name);
- }
+
+
/* now check for known vars */
for (l = 0; l < free_call->vars->count; ++l) {
int check = 0;
decl_var *free_var = free_call->vars->vars[l];
- for (k = 0; k < impl->decl->args->count; ++k) {
- decl_arg *free_arg = impl->decl->args->args[k];
+ if (!strcmp(free_var->name, impl->decl->func->var->name)) {
+ check = 1;
+ free_var->arg = impl->decl->func;
+ } else 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;
- free_var->arg = free_arg;
- break;
+ if (!strcmp(free_var->name, free_arg->var->name)) {
+ check = 1;
+ free_var->arg = free_arg;
+ break;
+ }
}
}
}
static inline void dump_impl_set_value(int fd, set_value *set, unsigned level) {
- size_t i, j;
+ size_t i;
if (level > 1) {
/* only if not directly after `set ...` */
void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val)
{
+ char *str;
decl_var *var = set->vars->vars[0];
token_t t = real_decl_type(var->arg->type)->type;
RETVAL_DOUBLE(deref_impl_val(ret_val, var)->dval);
break;
default:
- case PSI_T_VOID:
- case PSI_T_INT8:
- case PSI_T_UINT8:
if (!var->arg->var->pointer_level) {
RETVAL_STRINGL(&ret_val->cval, 1);
} else {
ret_val = deref_impl_val(ret_val, var);
- if (ret_val && ret_val->ptr) {
+ if (var->arg->var->array_size) {
+ str = (char *) ret_val;
+ } else {
+ str = ret_val->ptr;
+ }
+ if (str) {
if (set->num) {
- RETVAL_STRINGL(ret_val->ptr, psi_long_num_exp(set->num, set->outer.val));
+ zend_long n = psi_long_num_exp(set->num, set->outer.val);
+ RETVAL_STRINGL(str, n);
} else {
- RETVAL_STRING(ret_val->ptr);
+ RETVAL_STRING(str);
}
} else {
RETVAL_EMPTY_STRING();
}
}
return;
- psi_to_int(return_value, set, ret_val);
- break;
}
convert_to_string(return_value);
}
static impl_val *iterate(impl_val *val, size_t size, unsigned i, impl_val *tmp)
{
memset(tmp, 0, sizeof(*tmp));
- memcpy(tmp, ((void*) val->ptr) + size * i, size);
+ memcpy(tmp, ((void*) val) + size * i, size);
return tmp;
}
void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val)
{
- set->outer.set->func->handler(return_value, set->outer.set, r_val->ptr);
+ set->outer.set->func->handler(return_value, set, r_val);
}
void psi_to_array(zval *return_value, set_value *set, impl_val *r_val)
token_t t = real_decl_type(var->arg->type)->type;
impl_val tmp, *ret_val = deref_impl_val(r_val, var);
- if ((intptr_t) ret_val->ptr <= (intptr_t) 0) {
+ if ((intptr_t) ret_val <= (intptr_t) 0) {
RETURN_NULL();
}
set_value *sub_set = set->inner[i];
decl_var *sub_var = sub_set->vars->vars[0];
- sub_set->outer.val = r_val;
+ sub_set->outer.val = ret_val;
if (sub_var->arg) {
impl_val *tmp = NULL, *val;
zval ztmp;
- val = deref_impl_val(struct_member_ref(sub_var->arg, ret_val, &tmp), sub_var);
+ val = struct_member_ref(sub_var->arg, ret_val, &tmp);
sub_set->func->handler(&ztmp, sub_set, val);
add_assoc_zval(return_value, sub_var->name, &ztmp);
}
return;
} else if (set->num) {
- /* to_array(arr_var, num_expr, to_int(*arr_var))
- */
+ /* to_array(arr_var, num_expr, to_int(*arr_var)) */
zval ele;
+ char *ptr;
zend_long i, n = psi_long_num_exp(set->num, set->outer.val);
+ size_t size = psi_t_size(var->arg->var->pointer_level ? PSI_T_POINTER : t);
+ set_value *sub_set = set->inner[0];
+ sub_set->outer.val = set->outer.val;
for (i = 0; i < n; ++i) {
- size_t size = psi_t_size(var->arg->var->pointer_level ? PSI_T_POINTER : t);
- impl_val *ptr = iterate(ret_val, size, i, &tmp);
-
- set->inner[0]->func->handler(&ele, set->inner[0], ptr);
+ ptr = (char *) ret_val->ptr + i * size;
+ sub_set->func->handler(&ele, sub_set, (void *) ptr);
add_next_index_zval(return_value, &ele);
}
} else {
- ZEND_ASSERT(0);
+ /* to_array(arr_var, to_int(*arr_var)) */
+ zval ele;
+ char *ptr = ret_val->ptr;
+ size_t size = psi_t_size(var->arg->var->pointer_level ? PSI_T_POINTER : t);
+ set_value *sub_set = set->inner[0];
+
+ sub_set->outer.val = set->outer.val;
+ while (*(void **) ptr) {
+ sub_set->func->handler(&ele, sub_set, (void *) ptr);
+ add_next_index_zval(return_value, &ele);
+ ptr += size;
+ }
}
}
zend_long n = psi_long_num_exp(alloc->nmemb, NULL), s = psi_long_num_exp(alloc->size, NULL);
void *mem = safe_emalloc(n, s, sizeof(void *));
memset(mem, 0, n * s + sizeof(void *));
+#if 0
+ fprintf(stderr, "calloc: %p\n", mem);
+#endif
return mem;
}
switch (let->val ? let->val->kind : PSI_LET_NULL) {
case PSI_LET_TMP:
- arg_val->ptr = deref_impl_val(let->val->data.var->arg->val.ptr, let->var);
+ memcpy(arg_val, deref_impl_val(let->val->data.var->arg->let->ptr, let->val->data.var), sizeof(*arg_val));
+#if 0
+ fprintf(stderr, "LET TMP: %p -> %p\n",
+ let->val->data.var->arg->let->ptr,
+ arg_val->ptr);
+#endif
break;
case PSI_LET_NULL:
if (darg->var->array_size) {
static inline void psi_do_set(zval *return_value, set_value *set)
{
+ decl_arg *set_arg = set->vars->vars[0]->arg;
+
zval_dtor(return_value);
- set->func->handler(return_value, set, set->vars->vars[0]->arg->ptr);
+ set->func->handler(return_value, set, set_arg->let ? set_arg->let->ptr : set_arg->ptr);
}
static inline void psi_do_return(zval *return_value, return_stmt *ret)
case PSI_T_NAME:
if (strct) {
ref = struct_member_ref(exp->u.dvar->arg, strct, &tmp);
+ } else if (exp->u.dvar->arg->let) {
+ ref = exp->u.dvar->arg->let->ptr;
} else {
ref = exp->u.dvar->arg->ptr;
}
if (val->vars) {
free_decl_vars(val->vars);
}
- if (val->inner) {
+ if (val->inner && (!val->outer.set || val->outer.set->inner != val->inner)) {
size_t i;
for (i = 0; i < val->count; ++i) {
free_set_value(val->inner[i]);
static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) {
unsigned i;
- if (var->arg->var != var) for (i = 1; i < var->pointer_level; ++i) {
+ ZEND_ASSERT(var->arg->var != var);
+#if 0
+ fprintf(stderr, "deref: %s pl=%u:%u as=%u:%u %p\n",
+ var->name, var->pointer_level, var->arg->var->pointer_level,
+ var->array_size, var->arg->var->array_size, ret_val);
+#endif
+ for (i = 0; i < var->pointer_level; ++i) {
+#if 0
+ fprintf(stderr, "-- %p %p %p\n", ret_val, *(void**)ret_val, ret_val->ptr);
+#endif
ret_val = *(void **) ret_val;
}
return ret_val;
impl_val *val, *val_ptr;
unsigned i;
+ ZEND_ASSERT(var->arg->var == var);
+#if 0
+ fprintf(stderr, "enref: %s pl=%u:%u as=%u:%u\n",
+ var->name, var->pointer_level, var->arg->var->pointer_level,
+ var->array_size, var->arg->var->array_size);
+#endif
if (!var->pointer_level && real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
return ptr;
}
+
val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *));
- for (i = 1; i < var->pointer_level; ++i) {
+ for (i = !var->arg->var->array_size; i < var->pointer_level; ++i) {
+#if 0
+ fprintf(stderr, "++\n");
+#endif
val_ptr->ptr = (void **) val_ptr + 1;
val_ptr = val_ptr->ptr;
}
}
static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) {
- void *ptr = (char *) struct_ptr->ptr + set_arg->layout->pos;
- impl_val *val = enref_impl_val(ptr, set_arg->var);
-
- if (val != ptr) {
- *to_free = val;
- }
-
- return val;
+ void *ptr = (char *) struct_ptr + set_arg->layout->pos;
+#if 0
+ fprintf(stderr, "struct member %s: %p\n", set_arg->var->name, ptr);
+#endif
+ return ptr;
}
+
#define PSI_ERROR 16
#define PSI_WARNING 32
typedef void (*psi_error_cb)(PSI_Token *token, int type, const char *msg, ...);
$cd = psi\iconv_open("latin1", "utf8");
$in = "ß";
$rc = psi\iconv($cd, $in, $tr);
-var_dump($tr === "\xdf");
-var_dump($in === "");
+if ($tr !== "\xdf") var_dump($tr);
+if ($in !== "") var_dump($in);
var_dump(psi\iconv_close($cd));
?>
===DONE===
--EXPECT--
===TEST===
-bool(true)
-bool(true)
int(0)
===DONE===