add int64 support and package.xml file

This commit is contained in:
Wez Furlong
2004-01-11 20:58:04 +00:00
parent 50bd92e0b8
commit b63a9ce2b6
6 changed files with 359 additions and 2 deletions

View File

@@ -115,7 +115,7 @@ if test "$PHP_FFI" != "no"; then
fi
PHP_NEW_EXTENSION(ffi, php_ffi.c ffi_struct.c ffi_library.c ffi_parser_util.c ffi_parser.c $ffi_sources libffi/src/debug.c libffi/src/prep_cif.c libffi/src/types.c libffi/src/raw_api.c libffi/src/java_raw_api.c, $ext_shared,,-I@ext_srcdir@/libffi/include)
PHP_NEW_EXTENSION(ffi, php_ffi.c ffi_struct.c ffi_library.c ffi_parser_util.c ffi_parser.c ffi_int64.c $ffi_sources libffi/src/debug.c libffi/src/prep_cif.c libffi/src/types.c libffi/src/raw_api.c libffi/src/java_raw_api.c, $ext_shared,,-I@ext_srcdir@/libffi/include)
PHP_ADD_BUILD_DIR($ext_builddir/libffi/src/$TARGETDIR)
PHP_ADD_BUILD_DIR($ext_builddir/libffi)
PHP_ADD_BUILD_DIR($ext_builddir/libffi/src)

View File

@@ -4,7 +4,7 @@
ARG_WITH("ffi", "Foreign Function Interface Support", "no");
if (PHP_FFI == "yes") {
EXTENSION("ffi", "php_ffi.c ffi_struct.c ffi_library.c ffi_parser.c ffi_parser_util.c", null,
EXTENSION("ffi", "php_ffi.c ffi_struct.c ffi_library.c ffi_parser.c ffi_parser_util.c ffi_int64.c", null,
"/D PHP_LIBFFI_VERSION=\"2.00-beta\" /I\"" + configure_module_dirname + "/libffi/include\"");
ADD_SOURCES(configure_module_dirname + "/libffi/src/x86", "ffi.c win32-msvc.c", "ffi");
ADD_SOURCES(configure_module_dirname + "/libffi/src", "debug.c prep_cif.c types.c raw_api.c java_raw_api.c", "ffi");

195
ffi_int64.c Normal file
View File

@@ -0,0 +1,195 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2004 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.0 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_0.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Wez Furlong <wez@thebrainroom.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_ffi.h"
#include "php_ffi_internal.h"
SINT64 php_ffi_strto_int64(const char *nptr, char **endptr, int base, int is_unsigned)
{
int negative;
register UINT64 cutoff;
register unsigned int cutlim;
register UINT64 i;
register const char *s;
register unsigned char c;
const char *save;
int overflow;
if (base < 0 || base == 1 || base > 36)
base = 10;
s = nptr;
/* Skip white space. */
while (isspace (*s))
++s;
if (*s == '\0') {
goto noconv;
}
/* Check for a sign. */
if (*s == '-') {
negative = 1;
++s;
} else if (*s == '+') {
negative = 0;
++s;
} else {
negative = 0;
}
if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X') {
s += 2;
}
/* If BASE is zero, figure it out ourselves. */
if (base == 0) {
if (*s == '0') {
if (toupper (s[1]) == 'X') {
s += 2;
base = 16;
} else {
base = 8;
}
} else {
base = 10;
}
}
/* Save the pointer so we can check later if anything happened. */
save = s;
cutoff = UPHP_FFI_SINT64_MAX / (unsigned long int) base;
cutlim = (unsigned int) (UPHP_FFI_SINT64_MAX % (unsigned long int) base);
overflow = 0;
i = 0;
for (c = *s; c != '\0'; c = *++s) {
if (isdigit(c)) {
c -= '0';
} else if (isalpha(c)) {
c = toupper(c) - 'A' + 10;
} else {
break;
}
if (c >= base) {
break;
}
/* Check for overflow. */
if (i > cutoff || (i == cutoff && c > cutlim)) {
overflow = 1;
} else {
i *= (UINT64) base;
i += c;
}
}
/* Check if anything actually happened. */
if (s == save) {
goto noconv;
}
/* Store in ENDPTR the address of one character
past the last character we converted. */
if (endptr != NULL) {
*endptr = (char *) s;
}
if (is_unsigned) {
/* Check for a value that is within the range of
`unsigned long int', but outside the range of `long int'. */
if (negative) {
if (i > (UINT64) PHP_FFI_SINT64_MIN) {
overflow = 1;
}
} else if (i > (UINT64) PHP_FFI_SINT64_MAX) {
overflow = 1;
}
}
if (overflow) {
if (is_unsigned) {
return UPHP_FFI_SINT64_MAX;
} else {
return negative ? PHP_FFI_SINT64_MIN : PHP_FFI_SINT64_MAX;
}
}
/* Return the result of the appropriate sign. */
return (negative ? -((SINT64) i) : (SINT64) i);
noconv:
/* There was no number to convert. */
if (endptr != NULL) {
*endptr = (char *) nptr;
}
return 0L;
}
static char _dig_vec[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *php_ffi_int64_tostr(SINT64 val, char *dst, int radix)
{
char buffer[65];
register char *p;
long long_val;
if (radix < 0) {
if (val < 0) {
*dst++ = '-';
val = -val;
}
}
if (val == 0) {
*dst++='0';
*dst='\0';
return dst;
}
p = &buffer[sizeof(buffer)-1];
*p = '\0';
while ((UINT64) val > (UINT64) LONG_MAX) {
UINT64 quo=(UINT64) val/(unsigned int) 10;
uint rem= (unsigned int) (val- quo* (unsigned int) 10);
*--p = _dig_vec[rem];
val= quo;
}
long_val= (long) val;
while (long_val != 0) {
long quo= long_val/10;
*--p = _dig_vec[(unsigned char) (long_val - quo*10)];
long_val= quo;
}
while ((*dst++ = *p++) != 0)
;
return dst-1;
}

View File

@@ -421,6 +421,18 @@ int php_ffi_zval_to_native(void **mem, int *need_free, zval *val, struct php_ffi
convert_to_double(val);
*mem = &Z_DVAL_P(val);
return 1;
} else if (argtype->type == &ffi_type_sint64 || argtype->type == &ffi_type_uint64) {
if (want_alloc) {
*mem = emalloc(sizeof(SINT64));
*need_free = 1;
}
if (Z_TYPE_P(val) == IS_LONG) {
*(SINT64*)mem = Z_LVAL_P(val);
} else {
convert_to_string(val);
*(SINT64*)mem = php_ffi_strto_int64(Z_STRVAL_P(val), NULL, -1, argtype->type == &ffi_type_uint64);
}
return 1;
}
return 0;
@@ -471,6 +483,11 @@ int php_ffi_native_to_zval(void *mem, struct php_ffi_typed_arg *argtype, zval *v
} else if (argtype->type == &ffi_type_double) {
ZVAL_DOUBLE(val, *(double*)mem);
return 1;
} else if (argtype->type == &ffi_type_sint64 || argtype->type == &ffi_type_uint64) {
char intbuf[128];
php_ffi_int64_tostr(*(SINT64*)mem, intbuf, -1);
ZVAL_STRING(val, intbuf, 1);
return 1;
}
return 0;

137
package.xml Executable file
View File

@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE package SYSTEM "../pear/package.dtd">
<package>
<name>ffi</name>
<summary>Foreign Function Interface</summary>
<maintainers>
<maintainer>
<user>wez</user>
<name>Wez Furlong</name>
<email>wez@php.net</email>
<role>lead</role>
</maintainer>
</maintainers>
<description>FFI is a multi-platform extension for PHP 5 that allows you to bind to functions from arbitrary shared libraries and call them.</description>
<license>PHP</license>
<release>
<state>alpha</state>
<version>0.1</version>
<date>2004-01-11</date>
<notes>Initial release</notes>
<filelist>
<file role="src" name="config.m4"/>
<file role="src" name="config.w32"/>
<file role="src" name="CREDITS"/>
<file role="src" name="EXPERIMENTAL"/>
<file role="src" name="ffi_library.c"/>
<file role="src" name="ffi_parser.c"/>
<file role="src" name="ffi_parser.h"/>
<file role="src" name="ffi_parser_util.c"/>
<file role="src" name="ffi_parser.y"/>
<file role="src" name="ffi_struct.c"/>
<file role="src" name="ffi_int64.c"/>
<file role="src" name="Makefile.frag"/>
<file role="src" name="php_ffi.c"/>
<file role="src" name="php_ffi.h"/>
<file role="src" name="php_ffi_internal.h"/>
<file role="doc" name="README"/>
<dir name="libffi" role="src">
<file role="src" name="fficonfig.h.in"/>
<file role="src" name="LICENSE"/>
<file role="src" name="README"/>
<dir name="include" role="src">
<file role="src" name="ffi_common.h"/>
<file role="src" name="fficonfig.h"/>
<file role="src" name="ffi.h.in"/>
<file role="src" name="ffi_mips.h"/>
</dir>
<dir name="src" role="src">
<file role="src" name="debug.c"/>
<file role="src" name="ffitest.c"/>
<file role="src" name="java_raw_api.c"/>
<file role="src" name="prep_cif.c"/>
<file role="src" name="raw_api.c"/>
<file role="src" name="types.c"/>
<dir name="alpha" role="src">
<file role="src" name="ffi.c"/>
<file role="src" name="osf.S"/>
</dir>
<dir name="arm" role="src">
<file role="src" name="ffi.c"/>
<file role="src" name="sysv.S"/>
</dir>
<dir name="ia64" role="src">
<file role="src" name="ffi.c"/>
<file role="src" name="ia64_flags.h"/>
<file role="src" name="unix.S"/>
</dir>
<dir name="m68k" role="src">
<file role="src" name="ffi.c"/>
<file role="src" name="sysv.S"/>
</dir>
<dir name="mips" role="src">
<file role="src" name="ffi.c"/>
<file role="src" name="n32.S"/>
<file role="src" name="o32.S"/>
</dir>
<dir name="powerpc" role="src">
<file role="src" name="aix_closure.S"/>
<file role="src" name="aix.S"/>
<file role="src" name="asm.h"/>
<file role="src" name="darwin_closure.S"/>
<file role="src" name="darwin.S"/>
<file role="src" name="ffi.c"/>
<file role="src" name="ffi_darwin.c"/>
<file role="src" name="ppc_closure.S"/>
<file role="src" name="sysv.S"/>
</dir>
<dir name="s390" role="src">
<file role="src" name="ffi.c"/>
<file role="src" name="sysv.S"/>
</dir>
<dir name="sh" role="src">
<file role="src" name="ffi.c"/>
<file role="src" name="sysv.S"/>
</dir>
<dir name="sparc" role="src">
<file role="src" name="ffi.c"/>
<file role="src" name="v8.S"/>
<file role="src" name="v9.S"/>
</dir>
<dir name="x86" role="src">
<file role="src" name="ffi64.c"/>
<file role="src" name="ffi.c"/>
<file role="src" name="sysv.S"/>
<file role="src" name="unix64.S"/>
<file role="src" name="win32-msvc.c"/>
<file role="src" name="win32.S"/>
</dir>
</dir>
<dir name="tests" role="test">
<file name="001.phpt"/>
</dir>
</filelist>
<deps>
<dep type="php" rel="ge" version="5" />
</deps>
</release>
</package>
<!--
vim:et:ts=1:sw=1
-->

View File

@@ -162,3 +162,11 @@ php_ffi_function *php_ffi_parser_register_func(struct php_ffi_def_context *ctx,
void php_ffi_struct_dtor(void *object, zend_object_handle handle TSRMLS_DC);
void php_ffi_struct_object_clone(void *object, void **clone_ptr TSRMLS_DC);
extern zend_object_handlers php_ffi_struct_object_handlers;
SINT64 php_ffi_strto_int64(const char *nptr, char **endptr, int base, int is_unsigned);
char *php_ffi_int64_tostr(SINT64 val, char *dst, int radix);
#define UPHP_FFI_SINT64_MAX (~(UINT64)0)
#define PHP_FFI_SINT64_MIN ((SINT64)0x8000000000000000)
#define PHP_FFI_SINT64_MAX ((SINT64)0x7FFFFFFFFFFFFFFF)