./lemon: lemon.c | lempar.c
$(CC) -o $@ $<
+$(PHP_PSI_SRCDIR)/src/context.c: $(PHP_PSI_SRCDIR)/config.m4
+ touch $@
$(PHP_PSI_SRCDIR)/src/%.c: $(PHP_PSI_BUILDDIR)/parser.h
touch $@
$(PHP_PSI_SRCDIR)/src/parser_proc.y: $(PHP_PSI_BUILDDIR)/parser.h
dnl PSI_STRUCT(name, members, member type cases, includes)
PSI_STRUCTS=
AC_DEFUN(PSI_STRUCT, [
+ AC_CHECK_SIZEOF(struct $1, [], PSI_INCLUDES_DEFAULT($4))
psi_struct_members=
m4_foreach(member, [$2], [
AC_CHECK_MEMBER(struct $1.member, [
fi
], [], PSI_INCLUDES_DEFAULT($4))
])
- PSI_STRUCTS="{\"$1\", {$psi_struct_members}}, $PSI_STRUCTS"
+ PSI_STRUCTS="{\"$1\", $ac_cv_sizeof_struct_$1, {$psi_struct_members}}, $PSI_STRUCTS"
])
AC_TYPE_INT8_T
PSI_CONST(ITIMER_REAL, int, sys/time.h)
PSI_CONST(ITIMER_VIRTUAL, int, sys/time.h)
PSI_CONST(ITIMER_PROF, int, sys/time.h)
+ dnl sys/times.h
+ PSI_STRUCT(tms, [
+ [tms_utime],
+ [tms_stime],
+ [tms_cutime],
+ [tms_cstime]], [
+ ], sys/times.h)
dnl sys/types.h
PSI_TYPE(blkcnt_t, int)
PSI_TYPE(blksize_t, int)
#define PSI_PREDEF_STRUCT_MEMBERS 32
typedef struct psi_predef_struct {
const char *name;
+ size_t size;
psi_predef_struct_member members[PSI_PREDEF_STRUCT_MEMBERS];
} psi_predef_struct;
static const psi_predef_struct psi_predef_structs[] = {
}
if (!(*dlopened = dlopen(ptr, RTLD_LAZY|RTLD_LOCAL))) {
data->error(PSI_WARNING, "Could not open library '%s': %s.",
- data->psi.file.fn, dlerror());
+ data->psi.file.ln, dlerror());
return 0;
}
return 1;
#endif
decl->dlptr = dlsym(dl ?: RTLD_NEXT, func->var->name);
if (!decl->dlptr) {
- data->error(PSI_WARNING, "Failed to located symbol '%s': %s",
+ data->error(PSI_WARNING, "Failed to locate symbol '%s': %s",
func->var->name, dlerror());
}
return 1;
}
dstruct = init_decl_struct(pre->name, dargs);
+ dstruct->size = pre->size;
T.structs = add_decl_struct(T.structs, dstruct);
}
ZEND_ASSERT(s);
for (i = 0; i < s->args->count; ++i) {
decl_arg *darg = s->args->args[i];
- impl_val tmp;
+ impl_val tmp, tmp_ptr;
zval ztmp;
char *ptr = (char *) ret_val->ptr + darg->layout->pos;
+ tmp_ptr.ptr = &tmp;
memset(&tmp, 0, sizeof(tmp));
memcpy(&tmp, ptr, darg->layout->len);
switch (real_decl_type(darg->type)->type) {
case PSI_T_UINT64:
psi_to_int(&ztmp, real_decl_type(darg->type)->type, &tmp, darg->var);
break;
+ case PSI_T_STRUCT:
+ psi_to_array(&ztmp, real_decl_type(darg->type)->type, &tmp_ptr, darg->var);
+ break;
default:
printf("t=%d\n", real_decl_type(darg->type)->type);
abort();
--- /dev/null
+extern int __xstat64(int ver, char *path, struct stat *buf);
+function psi\stat(string $path, array &$buf = NULL) : int {
+ let ver = NULL;
+ let path = strval($path);
+ let buf = calloc(1, struct stat);
+ return to_int(__xstat64);
+ set $buf = to_array(*buf);
+}
--- /dev/null
+--TEST--
+stat
+--INI--
+psi.directory={PWD}
+--SKIPIF--
+<?php
+extension_loaded("psi") or die("skip - need ext/psi");
+?>
+--FILE--
+===TEST===
+<?php
+var_dump(psi\stat(__FILE__, $stat), $stat);
+?>
+===DONE===
+--EXPECTF--
+===TEST===
+int(0)
+array(13) {
+ ["st_dev"]=>
+ int(%d)
+ ["st_ino"]=>
+ int(%d)
+ ["st_mode"]=>
+ int(%d)
+ ["st_nlink"]=>
+ int(1)
+ ["st_uid"]=>
+ int(%d)
+ ["st_gid"]=>
+ int(%d)
+ ["st_rdev"]=>
+ int(%d)
+ ["st_size"]=>
+ int(76)
+ ["st_atim"]=>
+ array(2) {
+ ["tv_sec"]=>
+ int(1%d)
+ ["tv_nsec"]=>
+ int(%d)
+ }
+ ["st_mtim"]=>
+ array(2) {
+ ["tv_sec"]=>
+ int(1%d)
+ ["tv_nsec"]=>
+ int(%d)
+ }
+ ["st_ctim"]=>
+ array(2) {
+ ["tv_sec"]=>
+ int(1%d)
+ ["tv_nsec"]=>
+ int(%d)
+ }
+ ["st_blksize"]=>
+ int(%d)
+ ["st_blocks"]=>
+ int(%d)
+}
+===DONE===
\ No newline at end of file
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 buf = calloc(32, char);
+ return to_string(asctime_r);
+}
-extern struct tm *gmtime(time_t tp);
+extern struct tm *gmtime(time_t *tp);
function psi\gmtime(int $ts) : array {
let tp = &intval($ts);
return to_array(gmtime);
}
+extern struct tm *gmtime_r(time_t *tp, struct tm *buf);
+function psi\gmtime_r(int $ts) : array {
+ let tp = &intval($ts);
+ let buf = calloc(1, struct tm);
+ return to_array(gmtime_r);
+}
+
extern int nanosleep(struct timespec *rqtp, struct timespec *rmtp);
function psi\nanosleep(array $rq = NULL, array &$rm = NULL) : int {
let rqtp = arrval($rq);
return to_int(nanosleep);
set $rm = to_array(*rmtp);
}
+
+extern clock_t times(struct tms *buf);
+function psi\times(array &$tms = NULL) : int {
+ let buf = calloc(1, struct tms);
+ return to_int(times);
+ set $tms = to_array(*buf);
+}
===TEST===
<?php
var_dump(psi\asctime(NULL));
+var_dump(psi\asctime_r(NULL));
var_dump(psi\asctime(psi\gmtime(1234567890)));
+var_dump(psi\asctime_r(psi\gmtime_r(1234567890)));
?>
===DONE===
--EXPECT--
===TEST===
string(25) "Sun Jan 0 00:00:00 1900
"
+string(25) "Sun Jan 0 00:00:00 1900
+"
+string(25) "Fri Feb 13 23:31:30 2009
+"
string(25) "Fri Feb 13 23:31:30 2009
"
===DONE===
["tv_usec"]=>
int(%d)
}
-int(10%r\d\d\d%r)
+int(%r\d\d\d\d\d%r)
===DONE===
--- /dev/null
+--TEST--
+times
+--INI--
+psi.directory={PWD}
+--SKIPIF--
+<?php
+extension_loaded("psi") or die("skip - need ext/psi");
+?>
+--FILE--
+===TEST===
+<?php
+var_dump(psi\times($times), $times);
+?>
+===DONE===
+--EXPECTF--
+===TEST===
+int(%d)
+array(4) {
+ ["tms_utime"]=>
+ int(%d)
+ ["tms_stime"]=>
+ int(%d)
+ ["tms_cutime"]=>
+ int(%d)
+ ["tms_cstime"]=>
+ int(%d)
+}
+===DONE===