[sys_types.m4],
[sys_uio.m4],
[sys_utsname.m4],
+ [ndbm.m4],
[netdb.m4],
[netinet_in.m4],
[netinet_tcp.m4],
PSI_CHECK_SYS_STAT
PSI_CHECK_SYS_UIO
PSI_CHECK_SYS_UTSNAME
+ PSI_CHECK_NDBM
PSI_CHECK_NETDB
PSI_CHECK_NETINET_IN
PSI_CHECK_NETINET_TCP
#ifdef HAVE_ARPA_NAMESER_H
# include <arpa/nameser.h>
#endif
+#ifdef HAVE_NDBM_H
+# include <ndbm.h>
+#endif
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif
# psi_add_str_const(name, value)
# Add a pre-defined string constant to $PSI_CONSTS
psi_add_str_const() {
- cat >>$PSI_CONSTS <<<" {PSI_T_STRING, \"string\", \"psi\\\\$1\", $2, PSI_T_QUOTED_STRING}, "
+ grep -q "\"psi\\\\\\\\$1\"" $PSI_CONSTS || cat >>$PSI_CONSTS <<<" {PSI_T_STRING, \"string\", \"psi\\\\$1\", $2, PSI_T_QUOTED_STRING}, "
}
# psi_add_int_const(name, value)
# Add a pre-defined int constant to $PSI_CONSTS
psi_add_int_const() {
- cat >>$PSI_CONSTS <<<" {PSI_T_INT, \"int\", \"psi\\\\$1\", \"$2\", PSI_T_NUMBER}, "
+ grep -q "\"psi\\\\\\\\$1\"" $PSI_CONSTS || cat >>$PSI_CONSTS <<<" {PSI_T_INT, \"int\", \"psi\\\\$1\", \"$2\", PSI_T_NUMBER}, "
}
dnl PSI_CONST(const name, type)
dnl Defines a pre-defined type in $PSI_TYPES.
AC_DEFUN(PSI_TYPE, [
ifdef(AS_TR_CPP(AC_TYPE_$1), AS_TR_CPP(AC_TYPE_$1))
- PSI_CHECK_SIZEOF($1, PSI_INCLUDES)
+ PSI_CHECK_SIZEOF($1)
psi_basic_type=AS_TR_SH($2)
case $psi_basic_type in
int)
dnl $PSI_STRUCTS if the type is a struct.
AC_DEFUN(PSI_OPAQUE_TYPE, [
ifdef(AS_TR_CPP(AC_TYPE_$1), AS_TR_CPP(AC_TYPE_$1))
- PSI_CHECK_SIZEOF($1, PSI_INCLUDES)
+ PSI_CHECK_SIZEOF($1)
if PSI_SH_TEST_SIZEOF($1); then
psi_type_class=
AC_CACHE_CHECK(type class of $1, AS_TR_SH([psi_cv_type_class_]$1), [
let path = strval($pattern);
let flags = intval($flags);
let err = NULL;
- let buf = arrval($glob);
+ let buf = &arrval($glob);
return to_int(glob);
set $glob = to_array(*buf,
to_int(gl_matchc),
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 hints = &arrval($hints);
let res = &NULL;
return to_int(getaddrinfo);
set $res = to_array(**res,
to_string(ai_canonname),
to_array(*ai_next, ...)
);
- free freeaddrinfo(res);
+ free freeaddrinfo(*res);
}
// extern int getnameinfo(struct sockaddr *sa, socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)
// extern char *asctime(struct tm *tm);
function psi\asctime(array $tm = NULL) : string {
- let tm = arrval($tm);
+ let tm = &arrval($tm);
return to_string(asctime);
}
// extern char *asctime_r(struct tm *tm, char *buf);
function psi\asctime_r(array $tm = NULL) : string {
- let tm = arrval($tm);
+ let tm = &arrval($tm);
let buf = calloc(32, psi\SIZEOF_CHAR);
return to_string(asctime_r);
}
// extern int nanosleep(struct timespec *rqts, struct timespec *rmts);
function psi\nanosleep(array $rq = NULL, array &$rm = NULL) : int {
- let rqts = arrval($rq);
+ let rqts = &arrval($rq);
let rmts = calloc(1, psi\SIZEOF_STRUCT_TIMESPEC);
return to_int(nanosleep);
set $rm = to_array(*rmts,
ZEND_ASSERT(nels + 1 < argc);
els[nels++] = type;
-
+//fprintf(stderr, "%s o:%d, a:%d, p:%d l:%d\n", darg->var->name, offset, align, padding, darg->layout->len);
offset += MAX(align, padding) + darg->layout->len;
}
-
+//fprintf(stderr, "%s s:%d o=%d\n", strct->name, strct->size, offset);
ZEND_ASSERT(offset <= strct->size);
if (offset < strct->size) {
padding = strct->size - offset;
ffi_type *strct = calloc(1, sizeof(ffi_type));
strct->type = FFI_TYPE_STRUCT;
- strct->size = real->strct->size;
+ strct->size = 0;//real->strct->size;
strct->elements = psi_ffi_struct_type_elements(real->strct);
real->strct->engine.type = strct;
# define PSI_ENGINE "ffi"
#endif
+#include <ndbm.h>
+
ZEND_DECLARE_MODULE_GLOBALS(psi);
PHP_INI_BEGIN()
case PSI_T_DOUBLE:
mem->dval = zval_get_double(zv);
break;
+ case PSI_T_VOID:
case PSI_T_INT8:
case PSI_T_UINT8:
if (spec->var->pointer_level) {
return mem;
}
-static inline ZEND_RESULT_CODE psi_let_val(token_t let_func, impl_arg *iarg, impl_val *arg_val, decl_struct *strct, void **to_free)
+static inline impl_val *psi_let_val(token_t let_func, impl_arg *iarg, impl_val *arg_val, decl_struct *strct, void **to_free)
{
switch (let_func) {
case PSI_T_BOOLVAL:
if (PSI_T_PATHVAL == let_func) {
if (SUCCESS != php_check_open_basedir(arg_val->ptr)) {
efree(arg_val->ptr);
- return FAILURE;
+ return NULL;
}
}
break;
break;
case PSI_T_ARRVAL:
if (iarg->type->type == PSI_T_ARRAY) {
- arg_val->ptr = psi_array_to_struct(strct, HASH_OF(iarg->_zv));
- *to_free = arg_val->ptr;
+ arg_val = psi_array_to_struct(strct, HASH_OF(iarg->_zv));
+ *to_free = arg_val;
}
break;
case PSI_T_OBJVAL:
psi_object *obj;
if (!instanceof_function(Z_OBJCE_P(iarg->_zv), psi_class_entry)) {
- return FAILURE;
+ return NULL;
}
obj = PSI_OBJ(iarg->_zv, NULL);
break;
EMPTY_SWITCH_DEFAULT_CASE();
}
- return SUCCESS;
+ return arg_val;
}
static inline void *psi_do_let(let_stmt *let)
case PSI_LET_FUNC:
iarg = let->val->data.func->arg;
- if (SUCCESS != psi_let_val(let->val->data.func->type, iarg, darg->ptr, real_decl_type(darg->type)->strct, &darg->mem)) {
+ if (!(darg->ptr = psi_let_val(let->val->data.func->type, iarg, darg->ptr, real_decl_type(darg->type)->strct, &darg->mem))) {
return NULL;
}
}
for (j = 0; j < f->vars->count; ++j) {
decl_var *dvar = f->vars->vars[j];
decl_arg *darg = dvar->arg;
+ impl_val *fval = darg->let ? darg->let->ptr : darg->ptr;
- f->decl->call.args[j] = &darg->val;
+ f->decl->call.args[j] = deref_impl_val(fval, dvar);
}
/* FIXME: check in validate_* that free functions return scalar */
efree(darg->mem);
darg->mem = NULL;
}
+ darg->ptr = &darg->val;
}
if (impl->func->args->vararg.args) {
}
va->types[i] = vatype;
- psi_let_val(let_fn, vaarg, &va->values[i], NULL, &to_free);
+ /* FIXME: varargs with struct-by-value :) */
+ if (!psi_let_val(let_fn, vaarg, &va->values[i], NULL, &to_free)) {
+ return NULL;
+ }
if (to_free) {
if (!va->free_list) {
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) {
+ if (!var->pointer_level ){//&& real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
return ptr;
}
let flags = intval($flags);
set $result = to_string(*buffer);
return to_int(idna_to_ascii_8z);
- free free(buffer);
+ free free(*buffer);
}
default char *idna_strerror(int rc);
function idn\strerror(int $rc) : string {
--- /dev/null
+function psi\dbm_open(string $file, int $open_flags, int $file_mode) : object {
+ let file = pathval($file);
+ let open_flags = intval($open_flags);
+ let file_mode = intval($file_mode);
+ return to_object(dbm_open);
+}
+
+function psi\dbm_store(object $db, array $key, array $data, int $mode) : int {
+ let db = objval($db);
+ let key = arrval($key);
+ let content = arrval($data);
+ let store_mode = intval($mode);
+ return to_int(dbm_store);
+}
+
+function psi\dbm_fetch(object $db, array $key) : array {
+ let db = objval($db);
+ let key = arrval($key);
+ return to_array(dbm_fetch,
+ to_string(dptr, dsize),
+ to_int(dsize)
+ );
+}
+
+function psi\dbm_close(object $db) : void {
+ let db = objval($db);
+ return void(dbm_close);
+}
--- /dev/null
+--TEST--
+ndbm
+--INI--
+psi.directory={PWD}:{PWD}/../../psi.d
+--SKIPIF--
+<?php
+extension_loaded("psi") or die("skip - need ext/psi");
+function_exists("psi\\dbm_open") or die("skip - need nbdm support");
+?>
+--FILE--
+===TEST===
+<?php
+class db {
+ private $db;
+
+ function __construct($file = "ndbm001.db", $o = 0102, $m = 0640) {
+ if (!$this->db = psi\dbm_open($file, $o, $m)) {
+ throw new Exception(psi\strerror(psi\errno()));
+ }
+ }
+
+ function __destruct() {
+ psi\dbm_close($this->db);
+ }
+
+ function __set($k, $v) {
+ return psi\dbm_store($this->db, [
+ "dptr" => $k,
+ "dsize" => strlen($k)
+ ], [
+ "dptr" => $v,
+ "dsize" => strlen($v)
+ ], psi\DBM_REPLACE);
+ }
+
+ function __get($k) {
+ $val = psi\dbm_fetch($this->db, [
+ "dptr" => $k,
+ "dsize" => strlen($k)
+ ]);
+ if ($val) {
+ return $val["dptr"];
+ }
+ }
+}
+
+$db = new db();
+$db->key = "data";
+var_dump($db->key);
+?>
+===DONE===
+--CLEAN--
+<?php
+@unlink("ndbm001.db");
+?>
+--EXPECT--
+===TEST===
+string(4) "data"
+===DONE===