/config.cache
*~
*.swp
+php_psi_consts.h
+php_psi_decls.h
+php_psi_macros.h
+php_psi_redirs.h
+php_psi_stdinc.h
+php_psi_structs.h
+php_psi_types.h
+php_psi_va_decls.h
* check out jit-dynamic
* fix arginfo with nullable types
* pemalloc
+* unions
+* callbacks and function pointers
PHP_ARG_ENABLE(psi, whether to enable PHP System Interface support,
[ --enable-psi Enable PHP System Interface support])
+PHP_ARG_WITH(psi-libjit, where to find libjit,
+[ --with-psi-libjit=DIR PSI: path to libjit], [ ], [ ])
+
+PHP_ARG_WITH(psi-libffi, where to find libffi,
+[ --with-psi-libffi=DIR PSI: path to libffi], [ ], [ ])
+
PHP_PSI_SRCDIR=PHP_EXT_SRCDIR(psi)
PHP_PSI_BUILDDIR=PHP_EXT_BUILDDIR(psi)
[psi_struct.m4],
[errno.m4],
[glob.m4],
+ [locale.m4],
[stddef.m4],
[stdio.m4],
[stdint.m4],
[sys_uio.m4],
[sys_utsname.m4],
[netdb.m4],
+ [netinet_in.m4],
+ [netinet_tcp.m4],
+ [poll.m4],
[syslog.m4],
[time.m4],
- [wchar.m4]], [
+ [wchar.m4],
+ [wctype.m4]], [
dnl pecl build
sinclude([m4/]incfile)
dnl php-src build
PSI_CHECK_SYS_TYPES
PSI_CHECK_ERRNO
PSI_CHECK_GLOB
+ PSI_CHECK_LOCALE
PSI_CHECK_STDIO
PSI_CHECK_STDLIB
PSI_CHECK_TIME
PSI_CHECK_SYS_UIO
PSI_CHECK_SYS_UTSNAME
PSI_CHECK_NETDB
+ PSI_CHECK_NETINET_IN
+ PSI_CHECK_NETINET_TCP
+ PSI_CHECK_POLL
PSI_CHECK_SYSLOG
PSI_CHECK_WCHAR
+ PSI_CHECK_WCTYPE
PSI_CONFIG_DONE
PHP_SUBST(PSI_SHARED_LIBADD)
AC_DEFINE_UNQUOTED(PHP_PSI_SHLIB_SUFFIX, ["$SHLIB_SUFFIX_NAME"], DL suffix)
+ AC_DEFINE_UNQUOTED([PSI_STDINC], [$PSI_STDINC], [Standard includes])
AC_DEFINE_UNQUOTED([PSI_TYPES], [$PSI_TYPES], [Predefined types])
AC_DEFINE_UNQUOTED([PSI_STRUCTS], [$PSI_STRUCTS], [Predefined structs])
AC_DEFINE_UNQUOTED([PSI_CONSTS], [$PSI_CONSTS], [Predefined constants])
--- /dev/null
+PSI_CHECK_LOCALE() {
+ AC_CHECK_HEADERS(locale.h xlocale.h)
+
+ PSI_STRUCT(struct lconv, [
+ char *currency_symbol,
+ char *decimal_point,
+ char frac_digits,
+ char *grouping,
+ char *int_curr_symbol,
+ char int_frac_digits,
+ char int_n_cs_precedes,
+ char int_n_sep_by_space,
+ char int_n_sign_posn,
+ char int_p_cs_precedes,
+ char int_p_sep_by_space,
+ char int_p_sign_posn,
+ char *mon_decimal_point,
+ char *mon_grouping,
+ char *mon_thousands_sep,
+ char *negative_sign,
+ char n_cs_precedes,
+ char n_sep_by_space,
+ char n_sign_posn,
+ char *positive_sign,
+ char p_cs_precedes,
+ char p_sep_by_space,
+ char p_sign_posn,
+ char *thousands_sep])
+
+ PSI_CONST(LC_ALL, int)
+ PSI_CONST(LC_COLLATE, int)
+ PSI_CONST(LC_CTYPE, int)
+ PSI_CONST(LC_MESSAGES, int)
+ PSI_CONST(LC_MONETARY, int)
+ PSI_CONST(LC_NUMERIC, int)
+ PSI_CONST(LC_TIME, int)
+
+ PSI_CONST(LC_COLLATE_MASK, int)
+ PSI_CONST(LC_CTYPE_MASK, int)
+ PSI_CONST(LC_MESSAGES_MASK, int)
+ PSI_CONST(LC_MONETARY_MASK, int)
+ PSI_CONST(LC_NUMERIC_MASK, int)
+ PSI_CONST(LC_TIME_MASK, int)
+ PSI_CONST(LC_ALL_MASK, int)
+
+ PSI_MACRO(locale_t LC_GLOBAL_LOCALE)
+
+ PSI_OPAQUE_TYPE(locale_t)
+
+ PSI_DECL(locale_t duplocale, [(locale_t loc)])
+ PSI_DECL(void freelocale, [(locale_t loc)])
+ PSI_DECL(struct lconv *localeconv, [(void)])
+ PSI_DECL(locale_t newlocale, [(int mask, const char *locale, locale_t base)])
+ PSI_DECL(char *setlocale, [(int category, const char *locale)])
+ PSI_DECL(locale_t uselocale, [(locale_t loc)])
+}
--- /dev/null
+PSI_CHECK_NETINET_IN() {
+ AC_CHECK_HEADERS(netinet/in.h)
+
+ PSI_TYPE(in_port_t, uint)
+ PSI_TYPE(in_addr_t, uint)
+
+ PSI_STRUCT(struct in_addr, [
+ in_addr_t s_addr]
+ )
+
+ PSI_STRUCT(struct sockaddr_in, [
+ sa_family_t sin_family,
+ in_port_t sin_port,
+ struct in_addr sin_addr]
+ )
+
+ PSI_STRUCT(struct in6_addr, [
+ uint8_t s6_addr@<:@16@:>@]
+ )
+ PSI_STRUCT(struct sockaddr_in6, [
+ sa_family_t sin6_family,
+ in_port_t sin6_port,
+ uint32_t sin6_flowinfo,
+ struct in6_addr sin6_addr,
+ uint32_t sin6_scope_id]
+ )
+
+ PSI_STRUCT(struct ipv6_mreq, [
+ struct in6_addr ipv6mr_multiaddr,
+ unsigned ipv6mr_interface]
+ )
+
+ PSI_CONST(IPPROTO_IP, int)
+ PSI_CONST(IPPROTO_IPV6, int)
+ PSI_CONST(IPPROTO_ICMP, int)
+ PSI_CONST(IPPROTO_RAW, int)
+ PSI_CONST(IPPROTO_TCP, int)
+ PSI_CONST(IPPROTO_UDP, int)
+
+ PSI_CONST(INADDR_ANY, int)
+ PSI_CONST(INADDR_BROADCAST, int)
+ PSI_CONST(INET6_ADDRSTRLEN, int)
+
+ PSI_CONST(IPV6_JOIN_GROUP, int)
+ PSI_CONST(IPV6_LEAVE_GROUP, int)
+ PSI_CONST(IPV6_MULTICAST_HOPS, int)
+ PSI_CONST(IPV6_MULTICAST_IF, int)
+ PSI_CONST(IPV6_MULTICAST_LOOP, int)
+ PSI_CONST(IPV6_UNICAST_HOPS, int)
+ PSI_CONST(IPV6_V6ONLY, int)
+
+ PSI_MACRO(int IN6_IS_ADDR_UNSPECIFIED, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_LOOPBACK, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_MULTICAST, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_LINKLOCAL, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_SITELOCAL, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_V4MAPPED, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_V4COMPAT, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_MC_NODELOCAL, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_MC_LINKLOCAL, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_MC_SITELOCAL, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_MC_ORGLOCAL, [(const struct in6_addr *a)])
+ PSI_MACRO(int IN6_IS_ADDR_MC_GLOBAL, [(const struct in6_addr *a)])
+
+ PSI_EXTVAR(struct in6_addr in6addr_loopback)
+}
--- /dev/null
+PSI_CHECK_NETINET_TCP() {
+ AC_CHECK_HEADERS(netinet/tcp.h)
+
+ PSI_CONST(TCP_NODELAY, int)
+}
--- /dev/null
+PSI_CHECK_POLL() {
+ AC_CHECK_HEADERS(poll.h)
+
+ PSI_STRUCT(struct pollfd, [
+ int fd,
+ short events,
+ short revents]
+ )
+
+ PSI_TYPE(nfds_t, uint)
+
+ PSI_CONST(POLLIN, int)
+ PSI_CONST(POLLRDNORM, int)
+ PSI_CONST(POLLRDBAND, int)
+ PSI_CONST(POLLPRI, int)
+ PSI_CONST(POLLOUT, int)
+ PSI_CONST(POLLWRNORM, int)
+ PSI_CONST(POLLRWBAND, int)
+ PSI_CONST(POLLERR, int)
+ PSI_CONST(POLLHUP, int)
+ PSI_CONST(POLLNVAL, int)
+
+ PSI_DECL(int poll, [(struct pollfd *fds, nfds_t nfds, int timeout)])
+}
+dnl Generated headers with pre-defined types, structs, consts and decls.
+PSI_STDINC=$PHP_PSI_SRCDIR/php_psi_stdinc.h
PSI_TYPES=$PHP_PSI_SRCDIR/php_psi_types.h
PSI_STRUCTS=$PHP_PSI_SRCDIR/php_psi_structs.h
PSI_CONSTS=$PHP_PSI_SRCDIR/php_psi_consts.h
PSI_DECLS=$PHP_PSI_SRCDIR/php_psi_decls.h
PSI_VA_DECLS=$PHP_PSI_SRCDIR/php_psi_va_decls.h
+dnl PSI_CONFIG_INIT()
+dnl Creates stubs of the headers with pre-defined types etc.
+dnl These headers are included by src/context.c.
+dnl This macro must be called prior any checks for a type, struct, decl etc.
AC_DEFUN(PSI_CONFIG_INIT, [
cat >$PSI_TYPES <<EOF
static struct psi_predef_type {
EOF
])
+dnl PSI_CONFIG_DONE()
+dnl Finish the headers with the pre-defined types etc.
AC_DEFUN(PSI_CONFIG_DONE, [
+ cat >$PSI_STDINC <<EOF
+PSI_INCLUDES
+EOF
for i in $PSI_TYPES $PSI_STRUCTS $PSI_CONSTS $PSI_REDIRS $PSI_DECLS $PSI_VA_DECLS; do
cat >>$i <<EOF
{0}
done
])
-psi_includes() {
- local have_
- have_=`AS_ECHO($ac_header) | $as_tr_cpp`
- cat <<EOF
-#ifdef HAVE_$have_
-# include <$ac_header>
-#endif
-EOF
-}
-
+dnl PSI_INCLUDES()
+dnl Expands to a complete list of include statements including
+dnl AC_INCLUDES_DEFAULT().
AC_DEFUN(PSI_INCLUDES, [AC_INCLUDES_DEFAULT()
-`psi_includes`])
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#endif
+#ifdef HAVE_GLOB_H
+# include <glob.h>
+#endif
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+#ifdef HAVE_XLOCALE_H
+# include <xlocale.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+# include <netinet/tcp.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+# include <arpa/nameser.h>
+#endif
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+#ifdef HAVE_POLL_H
+# include <poll.h>
+#endif
+#ifdef HAVE_RESOLV_H
+# include <resolv.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_TIMES_H
+# include <sys/times.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+# include <sys/uio.h>
+#endif
+#ifdef HAVE_SYS_UTSNAME_H
+# include <sys/utsname.h>
+#endif
+#ifdef HAVE_TIME_H
+# include <time.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+# include <syslog.h>
+#endif
+#ifdef HAVE_WCHAR_H
+# include <wchar.h>
+#endif
+#ifdef HAVE_WCTYPE_H
+# include <wctype.h>
+#endif
+])
+dnl PSI_LEMON()
+dnl Declare $LEMON precious, and check for a `lemon` in $PATH.
AC_DEFUN(PSI_LEMON, [
AC_ARG_VAR(LEMON, The lemon parser generator of the SQLite project)
AC_PATH_PROG(LEMON, lemon, ./lemon)
PHP_SUBST(LEMON)
])
+dnl PSI_PKG_CONFIG()
+dnl Check for `pkg-config` and add possible libjit and libffi directories to
+dnl $PKG_CONFIG_PATH, because those libs often ship with headers etc. in
+dnl arch-dependent locations.
AC_DEFUN([PSI_PKG_CONFIG], [
if test -z "$PKG_CONFIG"
then
export PKG_CONFIG_PATH="$PHP_PSI_LIBFFI/lib/pkgconfig:$PHP_PSI_LIBJIT/lib/pkgconfig:$PKG_CONFIG_PATH"
])
+dnl PSI_SH_TEST_SIZEOF(type)
+dnl `if` condition to test if $ac_cv_sizeof_$1 is greater than 0.
+AC_DEFUN([PSI_SH_TEST_SIZEOF], [test -n "$AS_TR_SH([ac_cv_sizeof_]$1)" && test "$AS_TR_SH([ac_cv_sizeof_]$1)" -gt 0])
+
+dnl PSI_CHECK_SIZEOF(type, special-includes)
+dnl AC_CHECK_SIZEOF wrapper with PSI_INCLUDES
+dnl Defines psi\\SIZEOF_<TYPE> pre-defined constant in $PSI_CONSTS.
AC_DEFUN(PSI_CHECK_SIZEOF, [
- AC_CHECK_SIZEOF($1, [], $2)
- if test "$AS_TR_SH([ac_cv_sizeof_]$1)"; then
- add_int_const "AS_TR_CPP([SIZEOF_]$1)" "$AS_TR_SH([ac_cv_sizeof_]$1)"
+ AC_CHECK_SIZEOF($1, [], PSI_INCLUDES
+ $2)
+ if PSI_SH_TEST_SIZEOF($1); then
+ psi_add_int_const "AS_TR_CPP([SIZEOF_]$1)" "$AS_TR_SH([ac_cv_sizeof_]$1)"
fi
])
+dnl PSI_CHECK_OFFSETOF(struct, element)
+dnl Check the offset of a struct element, implemented in the similar manner
+dnl like AC_CHECK_SIZEOF.
+dnl AC_DEFINEs OFFSETOF_<STRUCT>_<ELEMENT>.
AC_DEFUN(PSI_CHECK_OFFSETOF, [
_AC_CACHE_CHECK_INT(
[offset of $2 in $1],
)
])
+dnl PSI_COMPUTE_STR(variable, string or expression)
+dnl Compute a string constant value in a similar manner like AC_COMPUTE_INT.
+AC_DEFUN(PSI_COMPUTE_STR, [
+ AC_TRY_RUN(
+ PSI_INCLUDES
+ [int main() {
+ return EOF == fputs($2, fopen("conftest.out", "w"));
+ }
+ ], [
+ eval $1=\\\"`cat conftest.out`\\\"
+ ])
+])
+
+dnl PSI_CHECK_LIBJIT()
+dnl Check for libjit in $PHP_PSI_LIBJIT or standard locations
+dnl AC_DEFINEs HAVE_LIBJIT.
AC_DEFUN(PSI_CHECK_LIBJIT, [
- PHP_ARG_WITH(psi-libjit, where to find libjit,
- [ --with-psi-libjit=DIR PSI: path to libjit], [ ], [ ])
AC_CACHE_CHECK(for libjit, psi_cv_libjit_dir, [
for psi_cv_libjit_dir in $PHP_PSI_LIBJIT {/usr{,/local},/opt}{,/libjit}
do
fi
])
-PHP_ARG_WITH(psi-libffi, where to find libffi,
-[ --with-psi-libffi=DIR PSI: path to libffi], [ ], [ ])
+dnl PSI_CHECK_LIBFFI()
+dnl Check for libffi with `pkg-config`. If that fails, `configure` looks into
+dnl $PHP_PSI_LIBFFI or standard locations to find libjit deps.
+dnl Checks for availability of recent closure API:
+dnl \ffi_closure_alloc and \ffi_prep_closure.
+dnl Checks for availability of recent vararg API:
+dnl \ffi_prep_cif_var.
+dnl AC_DEFINEs HAVE_LIBFFI, PSI_HAVE_FFI_CLOSURE_ALLOC,
+dnl PSI_HAVE_FFI_PREP_CLOSURE and PSI_HAVE_FFO_PREP_VIF_VAR.
AC_DEFUN(PSI_CHECK_LIBFFI, [
AC_REQUIRE([PSI_PKG_CONFIG])dnl
else
psi_cv_libffi=false
fi])
+
if $psi_cv_libffi
then
AC_MSG_CHECKING(for libffi)
], [
], -L$psi_cv_libffi_dir/$PHP_LIBDIR)
])
-
-dnl PSI_COMPUTE_STR(variable, string or expression)
-AC_DEFUN(PSI_COMPUTE_STR, [
- AC_TRY_RUN(
- PSI_INCLUDES
- [int main() {
- return EOF == fputs($2, fopen("conftest.out", "w"));
- }
- ], [
- eval $1=\\\"`cat conftest.out`\\\"
- ])
-])
-# add_str_const(name, value)
-add_str_const() {
+# 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}, "
}
-# add_int_const(name, value)
-add_int_const() {
+
+# 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}, "
}
+
dnl PSI_CONST(const name, type)
+dnl Check the value of a str/int constant and add it to the list of pre-defined
+dnl constants.
AC_DEFUN(PSI_CONST, [
AC_CACHE_CHECK(value of $1, psi_cv_const_$1, [
psi_const_val=
then
case $2 in
str*)
- add_str_const "$1" "$psi_cv_const_$1"
+ psi_add_str_const "$1" "$psi_cv_const_$1"
;;
int)
- add_int_const "$1" "$psi_cv_const_$1"
+ psi_add_int_const "$1" "$psi_cv_const_$1"
;;
esac
fi
-AC_DEFUN(PSI_REDIR, [psi_symbol=ifelse([$2],[],[$1],[$2])
- cat >>$PSI_REDIRS <<<" {\"$1\", (void(*)(void))$psi_symbol}, "])
+# psi_add_redir(name, symbol)
+# Add a function redirection to $PSI_REDIRS.
+psi_add_redir() {
+ cat >>$PSI_REDIRS <<<" {\"$1\", (void(*)(void))$2}, "
+}
+# psi_add_decl(decl, options)
+# Add a pre-defined decl to $PSI_VA_DECLS/$PSI_DECLS.
+psi_add_decl() {
+ case "$2" in
+ *vararg*)
+ cat >>$PSI_VA_DECLS <<<" $1, {0}, "
+ ;;
+ *)
+ cat >>$PSI_DECLS <<<" $1, {0}, "
+ ;;
+ esac
+}
+
+dnl PSI_REDIR(name, custom symbol)
+dnl Create a function redirection to an optional custom symbol.
+AC_DEFUN(PSI_REDIR, [
+ psi_add_redir $1 ifelse([$2],[],[$1],[$2])
+])
+
+dnl PSI_FUNC_LIBC_MAIN()
+dnl Check for the platforms default stub in executables.
AC_DEFUN(PSI_FUNC_LIBC_MAIN, [
AC_REQUIRE([AC_PROG_NM])
AC_REQUIRE([AC_PROG_AWK])
])
dnl PSI_FUNC(fn, action-if-yes, action-if-no)
+dnl Check for a possible function redirection.
AC_DEFUN(PSI_FUNC, [
AC_REQUIRE([PSI_FUNC_LIBC_MAIN])
psi_symbol=$1
esac
])
+dnl PSI_DECL_ARG(decl arg)
+dnl INTERNAL: build psi_decl_args
AC_DEFUN(PSI_DECL_ARG, [
m4_define([member_name], PSI_VAR_NAME($1))
m4_define([member_type], PSI_VAR_TYPE($1))
])
dnl PSI_DECL(type func, args, flags)
+dnl Check for a function or macro declaration.
+dnl Adds a pre-defined (vararg) decl to $PSI_VA_DECLS/$PSI_DECLS.
+dnl Calls PSI_MACRO if PSI_FUNC fails.
AC_DEFUN(PSI_DECL, [
psi_decl_args=
PSI_DECL_ARG($1)
[()], [],
[m4_map_args_sep([PSI_DECL_ARG(m4_normalize(], [))], [], m4_bregexp([$2], [(\(.*\))], [\1]))])
PSI_FUNC(PSI_VAR_NAME($1), [
- ifelse([$3], vararg, [
- cat >>$PSI_VA_DECLS <<<" $psi_decl_args, {0}, "
- ], [
- cat >>$PSI_DECLS <<<" $psi_decl_args, {0}, "
- ])
+ psi_add_decl "$psi_decl_args" $3
], [
PSI_MACRO($1, $2, [
- ifelse([$3], vararg, AC_MSG_ERROR(varargs macro support is not implemented),[])
- cat >>$PSI_DECLS <<<" $psi_decl_args, {0}, "
+ ifelse([$3], vararg, [
+ AC_MSG_ERROR(varargs macro support is not implemented)
+ ],[
+ psi_add_decl "$psi_decl_args"
+ ])
])
])
])
+# psi_add_macro(macro)
+# Add a pre-defined macro function to $PSI_MACROS.
+psi_add_macro() {
+ cat >>$PSI_MACROS <<<"$1"
+}
+
dnl PSI_MACRO(macro, decl args, action-if-true)
AC_DEFUN(PSI_MACRO, [
AC_CHECK_DECL(PSI_VAR_NAME($1)$2, [
], [
macro_body="return $macro_name$macro_call;"
])
- psi_macro="$macro_type psi_macro_$macro_name$macro_decl { $macro_body }"
- cat >>$PSI_MACROS <<<"$psi_macro"
+ psi_add_macro "$macro_type psi_macro_$macro_name$macro_decl { $macro_body }"
PSI_REDIR($macro_name, psi_macro_$macro_name)
], [], PSI_INCLUDES)
])
+# psi_add_struct(struct members)
+# Add a pre-defined struct to $PSI_STRUCTS.
+psi_add_struct() {
+ cat >>$PSI_STRUCTS <<<" $1, {0}, "
+}
+
+dnl PSI_STRUCT_MEMBER(struct name, decl member)
+dnl INTERNAL: build $psi_struct_members
AC_DEFUN(PSI_STRUCT_MEMBER, [
m4_define([member_name], PSI_VAR_NAME($2))
m4_define([member_type], PSI_VAR_TYPE($2))
- PSI_CHECK_SIZEOF(AS_TR_SH($1)[_]member_name, PSI_INCLUDES
+ PSI_CHECK_SIZEOF(AS_TR_SH($1)[_]member_name,
[#define ]AS_TR_SH($1)[_]member_name (($1 *)0)->member_name
)
- if test -n "$AS_TR_SH([ac_cv_sizeof_$1][_]member_name)" \
- && test "$AS_TR_SH([ac_cv_sizeof_$1][_]member_name)" -gt 0; then
+ if PSI_SH_TEST_SIZEOF($1 member_name); then
PSI_CHECK_OFFSETOF($1, member_name)
PSI_TYPE_INDIRECTION($2, [$AS_TR_SH([ac_cv_sizeof_]$1[_]member_name)], pl, as)
psi_struct_members="[$psi_struct_members, {]PSI_TYPE_PAIR(member_type)[, \"]member_name[\", $]AS_TR_SH([ac_cv_offsetof_]$1[_]member_name)[, $]AS_TR_SH([ac_cv_sizeof_]$1[_]member_name), $pl, $as[}]"
fi
])
+dnl PSI_STRUCT(struct name, struct members)
+dnl Check a struct and its members and add a pre-defined struct and possibly a
+dnl pre-defined type for this struct.
+dnl Calls PSI_CHECK_SIZEOF for the struct and each member.
+dnl Calls PSI_CHECK_OFFSETOF and PSI_TYPE_INDIRECTON for each member.
AC_DEFUN(PSI_STRUCT, [
- PSI_CHECK_SIZEOF($1, PSI_INCLUDES)
+ PSI_CHECK_SIZEOF($1)
psi_struct_name=m4_bregexp([$1], [^\(struct \)?\(\w+\)], [\2])
psi_struct_members="{PSI_T_STRUCT, \"struct\", \"$psi_struct_name\", 0, $AS_TR_SH([ac_cv_sizeof_]$1), 0, 0}"
ifelse([$2],,,[m4_map_args_sep([PSI_STRUCT_MEMBER($1, m4_normalize(], [))], [], $2)])
- cat >>$PSI_STRUCTS <<<" $psi_struct_members, {0}, "
+ psi_add_struct "$psi_struct_members"
if test "$1" = "$psi_struct_name"; then
- cat >>$PSI_TYPES <<<" {PSI_T_STRUCT, \"$1\", \"$1\"}, "
+ psi_add_type "{PSI_T_STRUCT, \"$1\", \"$1\"}"
fi
])
+# psi_add_type(type triplet)
+# Add a pre-defined type to $PSI_TYPES.
+psi_add_type() {
+ cat >>$PSI_TYPES <<<" $1, "
+}
+
# psi_type_pair(type, size)
+# Output a PSI_T_<TYPE>, \"<TYPENAME>\" tuple.
+# Uses stdint types when possible.
psi_type_pair() {
local psi_type_name=`tr -cd A-Za-z0-9_ <<<$1`
local psi_type_lower=`tr A-Z a-z <<<$psi_type_name`
local psi_type_upper=`tr a-z A-Z <<<$psi_type_name`
local psi_type_bits=`expr $2 \* 8`
echo "PSI_T_${psi_type_upper}${psi_type_bits}, \"${psi_type_lower}${psi_type_bits}_t\""
- #eval AS_TR_SH([psi_standard_type_]$1)="${psi_type_lower}${psi_type_bits}_t"
;;
struct*)
echo "PSI_T_STRUCT, \"$2\""
esac
}
-dnl PSI_TYPE(type name, basic type, includes)
+dnl PSI_TYPE(type name, basic type)
+dnl Check for a specific type, optionally referring to a basic type.
+dnl Calls AC_TYPE_<TYPE> (if defined) and PSI_CHECK_SIZEOF.
+dnl If the basic type is just specified as "int" (in contrast to "sint" or
+dnl "uint"), AX_CHECK_SIGN is used to discover signedness of the 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_basic_type=$2
+ psi_basic_type=AS_TR_SH($2)
case $psi_basic_type in
int)
- AX_CHECK_SIGN($1, :, [
- psi_basic_type=uint
- ], PSI_INCLUDES)
+ AX_CHECK_SIGN($1, :, [psi_basic_type=uint], PSI_INCLUDES)
;;
sint)
psi_basic_type=int
;;
esac
- if test "$2" && test "$AS_TR_SH([ac_cv_sizeof_]$1)" -gt 0; then
+ if test "$2" && PSI_SH_TEST_SIZEOF($1); then
AS_TR_SH(psi_basic_type_$1)=$psi_basic_type
- cat >>$PSI_TYPES <<<" {`psi_type_pair $psi_basic_type $AS_TR_SH([ac_cv_sizeof_]$1)`, \"$1\"}, "
+ psi_add_type "{`psi_type_pair $psi_basic_type $AS_TR_SH([ac_cv_sizeof_]$1)`, \"$1\"}"
+ #cat >>$PSI_TYPES <<<"{`psi_type_pair $psi_basic_type $AS_TR_SH([ac_cv_sizeof_]$1)`, \"$1\"}, "
+ fi
+])
+
+dnl PSI_OPAQUE_TYPE(type name)
+dnl Checks a type for being a scalar, a struct or a pointer type.
+dnl Calls AC_TYPE_<TYPE> (if defined) and PSI_CHECK_SIZEOF.
+dnl Defines a pre-defined type in $PSI_TYPES and a pre-defined struct in
+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)
+ 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), [
+ AC_TRY_COMPILE(PSI_INCLUDES, [char test@<:@($1)1@:>@;], [
+ psi_type_class=scalar
+ ], [
+ AC_TRY_COMPILE(PSI_INCLUDES, [$1 test = 0;], [
+ AC_TRY_COMPILE(PSI_INCLUDES, [$1 test = (($1)0)+1;], [
+ psi_type_class="pointer of known type"
+ ], [
+ psi_type_class="pointer of opaque type"
+ ])
+ ], [
+ psi_type_class=struct
+ ])
+ ])
+ AS_TR_SH([psi_cv_type_class_]$1)="$psi_type_class"
+ ])
+ case "$AS_TR_SH([psi_cv_type_class_]$1)" in
+ scalar)
+ AX_CHECK_SIGN($1, [psi_basic_type=int], [psi_basic_type=uint], PSI_INCLUDES)
+ psi_add_type "{`psi_type_pair $psi_basic_type $AS_TR_SH([ac_cv_sizeof_]$1)`, \"$1\"}"
+ #cat >>$PSI_TYPES <<<" {`psi_type_pair $psi_basic_type $AS_TR_SH([ac_cv_sizeof_]$1)`, \"$1\"}, "
+ ;;
+ struct)
+ PSI_STRUCT($1)
+ ;;
+ pointer*)
+ psi_add_type "{PSI_T_POINTER, \"void\", \"$1\"}"
+ #cat >>$PSI_TYPES <<<" {PSI_T_POINTER, \"void\", \"$1\"}, "
+ ;;
+ *)
+ AC_MSG_WARN(could not detect type class of $1)
+ ;;
+ esac
fi
])
-dnl unsigned char* buf[16] -> unsigned char*
-dnl AC_DEFUN(PSI_VAR_TYPE, [m4_bregexp([$1], [\(\(struct \)?[^ ]+\)[ *]+[^ ]+$], [\1])])
+dnl PSI_VAR_TYPE(decl arg)
+dnl Extracts the type of a decl arg, e.g. dnl unsigned char* buf[16] -> unsigned char*.
AC_DEFUN(PSI_VAR_TYPE, [m4_bregexp([$1], [^\(const \)?\(.*\) \([*]*\)[^ ]+$], [\2\3])])
-dnl unsigned char* buf[16] -> buf
+
+dnl PSI_VAR_NAME(decl arg)
+dnl Extracts the var name of a decl arg, e.g. unsigned char* buf[16] -> buf.
AC_DEFUN(PSI_VAR_NAME, [m4_bregexp(m4_bregexp([$1], [\([^ ]+\)$], [\1]), [\w+], [\&])])
-dnl PSI_TYPE_SIZE(type, pointer level, array size)
-AC_DEFUN(PSI_TYPE_SIZE, [ifelse(
- [$3], 0,
- [ifelse([$2], 0, $AS_TR_SH([ac_cv_sizeof_]$1), $ac_cv_sizeof_void_p)],
- [ifelse([$2], 1, [`expr $3 \* $AS_TR_SH([ac_cv_sizeof_]$1)`], $ac_cv_sizeof_void_p)]
-)])
-dnl PSI_TYPE_BITS(type)
-AC_DEFUN(PSI_TYPE_BITS, [`expr 8 \* $AS_TR_SH([ac_cv_sizeof_]$1)`])
-dnl PSI_TYPE_INDIRECTION(type, size, pointer_level_var, array_size_var)
+dnl PSI_TYPE_INDIRECTION(decl arg, size, pointer_level_var, array_size_var)
+dnl Calculates and assigns pointer_level and array_size of a decl arg to sh vars.
AC_DEFUN(PSI_TYPE_INDIRECTION, [
- dnl AC_MSG_CHECKING(indirection of $1)
m4_define([psi_pointer_level], m4_len(m4_bpatsubst([PSI_VAR_TYPE($1)], [[^*]])))
m4_define([psi_array_size], [m4_bregexp([PSI_VAR_TYPE($1)], [@<:@\([0-9]+\)@:>@], [\1])])
$3=m4_incr(psi_pointer_level)
$4=psi_array_size
])
-
- dnl AC_MSG_RESULT([[$]$3, [$]$4])
])
+dnl PSI_TYPE_PAIR(type)
+dnl Expand to a PSI_T_<TYPE>, \\"<TYPENAME>\\" tuple.
+dnl FIXME: There is also psi_type_pair()?
AC_DEFUN(PSI_TYPE_PAIR, [m4_case(m4_bregexp([$1], [^\w+], [\&]),
[void], [PSI_T_VOID, \"void\"],
[struct], [PSI_T_STRUCT, \"m4_bregexp([$1], [^struct \(\w+\)], [\1])\"],
[PSI_T_NAME, \"m4_bregexp([$1], [^\(\w+ \)*\w+], [\&])\"])])
+dnl PSI_CHECK_STD_TYPES()
+dnl Checks for standard ANSI-C and stdint types.
AC_DEFUN(PSI_CHECK_STD_TYPES, [
AC_CHECK_HEADERS(stdint.h)
AC_CHECK_ALIGNOF(float)
PSI_TYPE(double)
AC_CHECK_ALIGNOF(double)
+ PSI_TYPE(long double)
+ AC_CHECK_ALIGNOF(long double)
PSI_TYPE(void *)
AC_CHECK_ALIGNOF(void *)
PSI_TYPE(char, int)
+ PSI_TYPE(signed char, int)
PSI_TYPE(unsigned char, uint)
PSI_TYPE(short, int)
+ PSI_TYPE(short int, int)
+ PSI_TYPE(signed short, int)
+ PSI_TYPE(signed short int, int)
PSI_TYPE(unsigned short, uint)
+ PSI_TYPE(unsigned short int, uint)
PSI_TYPE(int, int)
+ PSI_TYPE(signed int, int)
+ PSI_TYPE(signed, int)
PSI_TYPE(unsigned int, uint)
PSI_TYPE(unsigned, uint)
PSI_TYPE(long, int)
+ PSI_TYPE(long int, int)
+ PSI_TYPE(signed long int, int)
PSI_TYPE(unsigned long, uint)
+ PSI_TYPE(unsigned long int, uint)
+ PSI_TYPE(long long, int)
+ PSI_TYPE(signed long long, int)
+ PSI_TYPE(signed long long int, int)
+ PSI_TYPE(unsigned long long, uint)
+ PSI_TYPE(unsigned long long int, uint)
+ dnl this must come after the check fo "unsigned long long int"; autoconf, wth?
+ PSI_TYPE(long long int, int)
])
PSI_CHECK_STDINT() {
AC_CHECK_HEADERS(stdint.h)
- PSI_TYPE(int_least8_t, int)
- PSI_TYPE(int_least16_t, int)
- PSI_TYPE(int_least32_t, int)
- PSI_TYPE(int_least64_t, int)
+ PSI_TYPE(int_least8_t, sint)
+ PSI_TYPE(int_least16_t, sint)
+ PSI_TYPE(int_least32_t, sint)
+ PSI_TYPE(int_least64_t, sint)
PSI_TYPE(uint_least8_t, uint)
PSI_TYPE(uint_least16_t, uint)
PSI_TYPE(uint_least32_t, uint)
PSI_TYPE(uint_least64_t, uint)
- PSI_TYPE(int_fast8_t, int)
- PSI_TYPE(int_fast16_t, int)
- PSI_TYPE(int_fast32_t, int)
- PSI_TYPE(int_fast64_t, int)
+ PSI_TYPE(int_fast8_t, sint)
+ PSI_TYPE(int_fast16_t, sint)
+ PSI_TYPE(int_fast32_t, sint)
+ PSI_TYPE(int_fast64_t, sint)
PSI_TYPE(uint_fast8_t, uint)
PSI_TYPE(uint_fast16_t, uint)
PSI_TYPE(uint_fast32_t, uint)
PSI_TYPE(uint_fast64_t, uint)
- PSI_TYPE(intptr_t, int)
+ PSI_TYPE(intptr_t, sint)
PSI_TYPE(uintptr_t, uint)
- PSI_TYPE(intmax_t, int)
+ PSI_TYPE(intmax_t, sint)
PSI_TYPE(uintmax_t, uint)
PSI_CONST(INT8_MIN, int)
PSI_CONST(L_ctermid, int)
PSI_CONST(L_tmpnam, int)
+ PSI_MACRO(FILE *stderr)
+ PSI_MACRO(FILE *stdout)
+ PSI_MACRO(FILE *stdin)
+
PSI_DECL(void clearerr, [(FILE *stream)])
PSI_DECL(char *ctermid, [(char *s)])
PSI_DECL(int fclose, [(FILE *stream)])
PSI_CONST(EXIT_FAILURE, int)
PSI_CONST(EXIT_SUCCESS, int)
PSI_CONST(RAND_MAX, int)
- PSI_CONST(MB_CUR_MAX, int)
+
+ PSI_MACRO(int MB_CUR_MAX)
PSI_DECL(void _Exit, [(int status)])
PSI_DECL(void abort, [()])
PSI_CONST(FD_SETSIZE, int)
- PSI_MACRO(void FD_CLEAR, [(int fd, fd_set *s)])
- PSI_MACRO(void FD_COPY, [(fd_set *s1, fd_set *s2)])
- PSI_MACRO(void FD_CLR, [(int fd, fd_set *s)])
- PSI_MACRO(void FD_SET, [(int fd, fd_set *s)])
- PSI_MACRO(int FD_ISSET, [(int fd, fd_set *s)])
- PSI_MACRO(void FD_ZERO, [(fd_set *s)])
+ PSI_DECL(void FD_CLEAR, [(int fd, fd_set *s)])
+ PSI_DECL(void FD_COPY, [(fd_set *s1, fd_set *s2)])
+ PSI_DECL(void FD_CLR, [(int fd, fd_set *s)])
+ PSI_DECL(void FD_SET, [(int fd, fd_set *s)])
+ PSI_DECL(int FD_ISSET, [(int fd, fd_set *s)])
+ PSI_DECL(void FD_ZERO, [(fd_set *s)])
PSI_DECL(int select, [(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)])
dnl PSI_DECL(int pselect, [(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout, sigset_t *sigmask)])
PSI_CONST(S_IXOTH, int)
PSI_CONST(S_ISUID, int)
PSI_CONST(S_ISGID, int)
+ PSI_CONST(S_ISVTX, int)
PSI_CONST(UTIME_NOW, int)
PSI_CONST(UTIME_OMIT, int)
PSI_DECL(int timer_gettime, [(timer_t t, struct itimerspec *ts)])
PSI_DECL(int timer_settime, [(timer_t t, int flags, struct itimerspec *value, struct itimerspec *ovalue)])
PSI_DECL(void tzset, [()])
+
+ PSI_EXTVAR(int daylight)
+ PSI_EXTVAR(long timezone)
+ PSI_EXTVAR(char **tzname)
}
AC_CHECK_HEADERS(wchar.h)
PSI_TYPE(wint_t, int)
- PSI_TYPE(wctype_t, int)
PSI_STRUCT(mbstate_t)
PSI_CONST(WINT_MIN, int)
PSI_DECL(int fwscanf, [(FILE *stream, const wchar_t *format)], vararg)
PSI_DECL(wint_t getwc, [(FILE *stream)])
PSI_DECL(wint_t getwchar, [(void)])
- PSI_DECL(int iswalnum, [(wint_t wc)])
- PSI_DECL(int iswalpha, [(wint_t wc)])
- PSI_DECL(int iswcntrl, [(wint_t wc)])
- PSI_DECL(int iswctype, [(wint_t wc, wctype_t class)])
- PSI_DECL(int iswdigit, [(wint_t wc)])
- PSI_DECL(int iswgraph, [(wint_t wc)])
- PSI_DECL(int iswlower, [(wint_t wc)])
- PSI_DECL(int iswprint, [(wint_t wc)])
- PSI_DECL(int iswpunct, [(wint_t wc)])
- PSI_DECL(int iswspace, [(wint_t wc)])
- PSI_DECL(int iswupper, [(wint_t wc)])
- PSI_DECL(int iswxdigit, [(wint_t wc)])
PSI_DECL(size_t mbrlen, [(const char *s, size_t n, mbstate_t *ps)])
PSI_DECL(size_t mbrtowc, [(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)])
PSI_DECL(int mbsinit, [(const mbstate_t *ps)])
PSI_DECL(wint_t putwchar, [(wchar_t wc)])
PSI_DECL(int swprintf, [(wchar_t *wcs, size_t maxlen, const wchar_t *format)], vararg)
PSI_DECL(int swscanf, [(const wchar_t *ws, const wchar_t *format)], vararg)
- PSI_DECL(wint_t towlower, [(wint_t wc)])
- PSI_DECL(wint_t towupper, [(wint_t wc)])
PSI_DECL(wint_t ungetwc, [(wint_t wc, FILE *stream)])
PSI_DECL(wchar_t *wcpcpy, [(wchar_t *dest, const wchar_t *src)])
PSI_DECL(wchar_t *wcpncpy, [(wchar_t *dest, const wchar_t *src, size_t n)])
PSI_DECL(size_t wcsxfrm, [(wchar_t *ws1, const wchar_t *ws2, size_t n)])
PSI_DECL(size_t wcsxfrm_l, [(wchar_t *ws1, const wchar_t *ws2, size_t n, locale_t loc)])
PSI_DECL(int wctob, [(wint_t c)])
- PSI_DECL(wctype_t wctype, [(const char *name)])
PSI_DECL(int wcwidth, [(wchar_t c)])
PSI_DECL(wchar_t *wmemchr, [(const wchar_t *s, wchar_t c, size_t n)])
PSI_DECL(int wmemcmp, [(const wchar_t *s1, const wchar_t *s2, size_t n)])
--- /dev/null
+PSI_CHECK_WCTYPE() {
+ AC_CHECK_HEADERS(wctype.h)
+
+ PSI_TYPE(wctype_t, int)
+ PSI_TYPE(wctrans_t, int)
+
+ PSI_DECL(int iswalnum, [(wint_t wc)])
+ PSI_DECL(int iswalpha, [(wint_t wc)])
+ PSI_DECL(int iswcntrl, [(wint_t wc)])
+ PSI_DECL(int iswctype, [(wint_t wc, wctype_t class)])
+ PSI_DECL(int iswdigit, [(wint_t wc)])
+ PSI_DECL(int iswgraph, [(wint_t wc)])
+ PSI_DECL(int iswlower, [(wint_t wc)])
+ PSI_DECL(int iswprint, [(wint_t wc)])
+ PSI_DECL(int iswpunct, [(wint_t wc)])
+ PSI_DECL(int iswspace, [(wint_t wc)])
+ PSI_DECL(int iswupper, [(wint_t wc)])
+ PSI_DECL(int iswxdigit, [(wint_t wc)])
+ PSI_DECL(wint_t towlower, [(wint_t wc)])
+ PSI_DECL(wint_t towupper, [(wint_t wc)])
+ PSI_DECL(wint_t towctrans, [(wint_t wc, wctrans_t desc)])
+ PSI_DECL(wctype_t wctype, [(const char *name)])
+ PSI_DECL(wctrans_t wctrans, [(const char *class)])
+
+ PSI_DECL(int iswalnum_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswalpha_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswcntrl_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswctype_l, [(wint_t wc_l, wctype_t class, locale_t loc)])
+ PSI_DECL(int iswdigit_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswgraph_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswlower_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswprint_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswpunct_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswspace_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswupper_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(int iswxdigit_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(wint_t towlower_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(wint_t towupper_l, [(wint_t wc, locale_t loc)])
+ PSI_DECL(wint_t towctrans_l, [(wint_t wc, wctrans_t desc, locale_t loc)])
+ PSI_DECL(wctype_t wctype_l, [(const char *name, locale_t loc)])
+ PSI_DECL(wctrans_t wctrans_l, [(const char *class, locale_t loc)])
+}
#include "php.h"
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
-#ifdef HAVE_GLOB_H
-# include <glob.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_RESOLV_H
-# include <resolv.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_TIMES_H
-# include <sys/times.h>
-#endif
-#ifdef HAVE_SYS_UIO_H
-# include <sys/uio.h>
-#endif
-#ifdef HAVE_SYS_UTSNAME_H
-# include <sys/utsname.h>
-#endif
-#ifdef HAVE_TIME_H
-# include <time.h>
-#endif
-#ifdef HAVE_SYSLOG_H
-# include <syslog.h>
-#endif
-#ifdef HAVE_WCHAR_H
-# include <wchar.h>
-#endif
+#include "php_psi_stdinc.h"
#ifdef HAVE_DIRENT_H
# include <dirent.h>
} psi_std_types[] = {
{PSI_T_FLOAT, "float"},
{PSI_T_DOUBLE, "double"},
+#ifdef HAVE_LONG_DOUBLE
+ {PSI_T_LONG_DOUBLE, "long double"},
+#endif
{PSI_T_INT8, "int8_t"},
{PSI_T_INT16, "int16_t"},
{PSI_T_INT32, "int32_t"},
#include "php_psi_va_decls.h"
#include "php_psi_structs.h"
-/*
-static struct psi_predef_type {
- token_t type_tag;
- const char *type_name;
- const char *alias;
-} psi_predef_types[] = {
- PSI_TYPES
- {0}
-};
-
-static struct psi_predef_const {
- token_t type_tag;
- const char *type_name;
- const char *var_name;
- const char *val_text;
- token_t val_type_tag;
-} psi_predef_consts[] = {
- PSI_CONSTS
- {0}
-};
-
-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) {
- size_t offs = flags & GLOB_DOOFFS ? pglob->gl_offs : 0;
- int rv = glob(pattern, flags, errfunc, pglob);
- if (pglob->gl_pathv) {
- while (offs--) {
- pglob->gl_pathv[offs] = NULL;
- }
- }
- return rv;
-}
-
-static struct psi_func_redir {
- const char *name;
- void (*func)(void);
-} psi_func_redirs[] = {
- {"glob", (void (*)(void)) psi_glob},
- {"uname2", (void (*)(void)) uname2},
- PSI_REDIRS
- {0}
-};
-
-static struct psi_predef_decl {
- token_t type_tag;
- const char *type_name;
- const char *var_name;
- size_t pointer_level;
- size_t array_size;
-} psi_predef_decls[] = {
- PSI_DECLS
- {0}
-};
-static struct psi_predef_decl psi_predef_vararg_decls[] = {
- PSI_VA_DECLS
- {0}
-};
-
-static struct psi_predef_struct {
- token_t type_tag;
- const char *type_name;
- const char *var_name;
- size_t offset;
- size_t size;
- size_t pointer_level;
- size_t array_size;
-} psi_predef_structs[] = {
- PSI_STRUCTS
- {0}
-};
-*/
static int validate_lib(PSI_Data *data, void **dlopened) {
char lib[MAXPATHLEN];
const char *ptr = data->psi.file.ln;
static inline int validate_decl_type(PSI_Data *data, decl_type *type) {
switch (type->type) {
+ case PSI_T_CHAR:
+ case PSI_T_SHORT:
+ case PSI_T_INT:
+ case PSI_T_LONG:
case PSI_T_NAME:
if (!data->defs || !locate_decl_type_alias(data->defs, type)) {
return 0;
dprintf(fd, "typedef ");
dump_decl_type(fd, tdef->type);
- dprintf(fd, " %s;\n", tdef->alias);
+ dprintf(fd, " %s%s;\n", tdef->type->type == PSI_T_POINTER ? "*":"",
+ tdef->alias);
}
dprintf(fd, "\n");
}
return &ffi_type_float;
case PSI_T_DOUBLE:
return &ffi_type_double;
+ case PSI_T_POINTER:
+ return &ffi_type_pointer;
}
}
static inline ffi_type *psi_ffi_impl_type(token_t impl_type) {
#define BSIZE 256
#define PSI_T_POINTER PSI_T_ASTERISK
+#define PSI_T_LONG_DOUBLE (PSI_T_DOUBLE << 16)
+
typedef int token_t;
/* in php_psi.h */
return t;
}
+static inline decl_type *init_decl_type_ex(token_t type, int argc, ...) {
+ va_list argv;
+ char *ptr, *arg;
+ unsigned i;
+ size_t len, pos = 0, all = 0;
+ decl_type *t = calloc(1, sizeof(*t));
+
+ va_start(argv, argc);
+ for (i = 0; i < argc; ++i) {
+ arg = va_arg(argv, char *);
+ len = va_arg(argv, size_t);
+
+ if (len) {
+ if (all) {
+ pos = all;
+ ptr = realloc(ptr, 1 + (all += len));
+ } else {
+ ptr = malloc(1 + (all = len));
+ }
+ memcpy(ptr + pos, arg, len);
+ }
+ }
+ va_end(argv);
+
+ if (!all) {
+ ptr = calloc(1, 1);
+ } else {
+ ptr[all] = 0;
+ }
+ t->type = type;
+ t->name = ptr;
+ return t;
+}
+
static inline decl_type *real_decl_type(decl_type *type) {
while (type->real) {
type = type->real;
char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
} PSI_Parser;
+static inline size_t PSI_TokenAllocSize(size_t token_len, size_t fname_len) {
+ return sizeof(PSI_Token) + token_len + fname_len + sizeof(unsigned) + 2;
+}
+
static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
PSI_Token *T;
size_t token_len, fname_len;
token_len = P->cur - P->tok;
fname_len = strlen(P->psi.file.fn);
- T = calloc(1, sizeof(*T) + token_len + fname_len + sizeof(unsigned) + 2);
+ T = calloc(1, PSI_TokenAllocSize(token_len, fname_len));
T->type = token_typ;
T->size = token_len;
T->text = &T->buf[0];
}
static inline PSI_Token *PSI_TokenCopy(PSI_Token *src) {
- size_t fname_len = strlen(src->file);
- size_t strct_len = sizeof(*src) + src->size + fname_len + sizeof(unsigned) + 2;
+ size_t strct_len = PSI_TokenAllocSize(src->size, strlen(src->file));
PSI_Token *ptr = malloc(strct_len);
memcpy(ptr, src, strct_len);
return ptr;
}
+static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) {
+ va_list argv;
+ unsigned i;
+ PSI_Token *T = NULL;
+
+ va_start(argv, argc);
+ for (i = 0; i < argc; ++i) {
+ PSI_Token *arg = va_arg(argv, PSI_Token *);
+
+ if (T) {
+ size_t fname_len = strlen(T->file);
+
+ T = realloc(T, PSI_TokenAllocSize(T->size + arg->size, fname_len));
+ memmove(&T->buf[T->size + 1], T->file, fname_len + 1);
+ memcpy(T->file - 1, arg->text, arg->size + 1);
+ T->file = &T->buf[T->size + 1];
+ } else {
+ T = PSI_TokenCopy(arg);
+ T->type = PSI_T_NAME;
+ }
+ }
+ va_end(argv);
+
+ return T;
+}
+
static inline const char *PSI_TokenLocation(PSI_Token *t) {
return t ? t->file : "<builtin>:0:0";
}
'MIXED' {RETURN(PSI_T_MIXED);}
'VOID' {RETURN(PSI_T_VOID);}
'BOOL' {RETURN(PSI_T_BOOL);}
+ 'CHAR' {RETURN(PSI_T_CHAR);}
+ 'SHORT' {RETURN(PSI_T_SHORT);}
'INT' {RETURN(PSI_T_INT);}
+ 'LONG' {RETURN(PSI_T_LONG);}
'FLOAT' {RETURN(PSI_T_FLOAT);}
'DOUBLE' {RETURN(PSI_T_DOUBLE);}
'INT8_T' {RETURN(PSI_T_INT8);}
'INT64_T' {RETURN(PSI_T_INT64);}
'UINT64_T' {RETURN(PSI_T_UINT64);}
'UNSIGNED' {RETURN(PSI_T_UNSIGNED);}
+ 'SIGNED' {RETURN(PSI_T_SIGNED);}
'STRING' {RETURN(PSI_T_STRING);}
'ARRAY' {RETURN(PSI_T_ARRAY);}
'OBJECT' {RETURN(PSI_T_OBJECT);}
#define PSI_T_LET 9
#define PSI_T_RETURN 10
#define PSI_T_LIB 11
-#define PSI_T_INT 12
-#define PSI_T_UNSIGNED 13
-#define PSI_T_EOF 14
-#define PSI_T_QUOTED_STRING 15
-#define PSI_T_EOS 16
-#define PSI_T_STRUCT 17
-#define PSI_T_LBRACE 18
-#define PSI_T_RBRACE 19
-#define PSI_T_COLON 20
-#define PSI_T_LPAREN 21
-#define PSI_T_NUMBER 22
-#define PSI_T_RPAREN 23
-#define PSI_T_BOOL 24
-#define PSI_T_FLOAT 25
-#define PSI_T_STRING 26
-#define PSI_T_CONST 27
-#define PSI_T_NSNAME 28
-#define PSI_T_EQUALS 29
-#define PSI_T_TYPEDEF 30
-#define PSI_T_VOID 31
-#define PSI_T_LBRACKET 32
-#define PSI_T_RBRACKET 33
-#define PSI_T_COMMA 34
-#define PSI_T_ELLIPSIS 35
-#define PSI_T_DOUBLE 36
-#define PSI_T_INT8 37
-#define PSI_T_UINT8 38
-#define PSI_T_INT16 39
-#define PSI_T_UINT16 40
-#define PSI_T_INT32 41
-#define PSI_T_UINT32 42
-#define PSI_T_INT64 43
-#define PSI_T_UINT64 44
-#define PSI_T_FUNCTION 45
-#define PSI_T_NULL 46
-#define PSI_T_TRUE 47
-#define PSI_T_FALSE 48
-#define PSI_T_DOLLAR 49
-#define PSI_T_CALLOC 50
-#define PSI_T_OBJVAL 51
-#define PSI_T_ARRVAL 52
-#define PSI_T_PATHVAL 53
-#define PSI_T_STRLEN 54
-#define PSI_T_STRVAL 55
-#define PSI_T_FLOATVAL 56
-#define PSI_T_INTVAL 57
-#define PSI_T_BOOLVAL 58
-#define PSI_T_TO_OBJECT 59
-#define PSI_T_TO_ARRAY 60
-#define PSI_T_TO_STRING 61
-#define PSI_T_TO_INT 62
-#define PSI_T_TO_FLOAT 63
-#define PSI_T_TO_BOOL 64
-#define PSI_T_MIXED 65
-#define PSI_T_ARRAY 66
-#define PSI_T_OBJECT 67
-#define PSI_T_AMPERSAND 68
+#define PSI_T_CHAR 12
+#define PSI_T_SHORT 13
+#define PSI_T_INT 14
+#define PSI_T_LONG 15
+#define PSI_T_SIGNED 16
+#define PSI_T_UNSIGNED 17
+#define PSI_T_EOF 18
+#define PSI_T_QUOTED_STRING 19
+#define PSI_T_EOS 20
+#define PSI_T_STRUCT 21
+#define PSI_T_LBRACE 22
+#define PSI_T_RBRACE 23
+#define PSI_T_COLON 24
+#define PSI_T_LPAREN 25
+#define PSI_T_NUMBER 26
+#define PSI_T_RPAREN 27
+#define PSI_T_BOOL 28
+#define PSI_T_FLOAT 29
+#define PSI_T_STRING 30
+#define PSI_T_CONST 31
+#define PSI_T_NSNAME 32
+#define PSI_T_EQUALS 33
+#define PSI_T_TYPEDEF 34
+#define PSI_T_VOID 35
+#define PSI_T_LBRACKET 36
+#define PSI_T_RBRACKET 37
+#define PSI_T_COMMA 38
+#define PSI_T_ELLIPSIS 39
+#define PSI_T_DOUBLE 40
+#define PSI_T_INT8 41
+#define PSI_T_UINT8 42
+#define PSI_T_INT16 43
+#define PSI_T_UINT16 44
+#define PSI_T_INT32 45
+#define PSI_T_UINT32 46
+#define PSI_T_INT64 47
+#define PSI_T_UINT64 48
+#define PSI_T_FUNCTION 49
+#define PSI_T_NULL 50
+#define PSI_T_TRUE 51
+#define PSI_T_FALSE 52
+#define PSI_T_DOLLAR 53
+#define PSI_T_CALLOC 54
+#define PSI_T_OBJVAL 55
+#define PSI_T_ARRVAL 56
+#define PSI_T_PATHVAL 57
+#define PSI_T_STRLEN 58
+#define PSI_T_STRVAL 59
+#define PSI_T_FLOATVAL 60
+#define PSI_T_INTVAL 61
+#define PSI_T_BOOLVAL 62
+#define PSI_T_TO_OBJECT 63
+#define PSI_T_TO_ARRAY 64
+#define PSI_T_TO_STRING 65
+#define PSI_T_TO_INT 66
+#define PSI_T_TO_FLOAT 67
+#define PSI_T_TO_BOOL 68
+#define PSI_T_MIXED 69
+#define PSI_T_ARRAY 70
+#define PSI_T_OBJECT 71
+#define PSI_T_AMPERSAND 72
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include "parser.h"
%nonassoc NAME.
%left PLUS MINUS.
%left SLASH ASTERISK.
-%fallback NAME TEMP FREE SET LET RETURN LIB INT UNSIGNED.
+%fallback NAME TEMP FREE SET LET RETURN LIB CHAR SHORT INT LONG SIGNED UNSIGNED.
file ::= blocks.
def->token = ALIAS;
}
/* support opaque types */
-decl_typedef(def) ::= TYPEDEF VOID(V) NAME(ALIAS) EOS. {
- def = init_decl_typedef(ALIAS->text, init_decl_type(V->type, V->text));
+decl_typedef(def) ::= TYPEDEF VOID(V) indirection(i) NAME(ALIAS) EOS. {
+ def = init_decl_typedef(ALIAS->text, init_decl_type(i?PSI_T_POINTER:V->type, V->text));
def->token = ALIAS;
def->type->token = V;
}
free(SIZ);
}
-%token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME.
-%type decl_type {decl_type*}
-%destructor decl_type {free_decl_type($$);}
-decl_type(type_) ::= decl_type_token(T). {
+/* un/signed, urgh */
+decl_scalar_type(type_) ::= CHAR(C). {
+ type_ = C;
+}
+decl_scalar_type(type_) ::= SHORT(S) INT(I). {
+ type_ = PSI_TokenCat(2, S, I);
+ free(S);
+ free(I);
+}
+decl_scalar_type(type_) ::= SHORT(S). {
+ type_ = S;
+}
+decl_scalar_type(type_) ::= LONG(L) INT(I). {
+ type_ = PSI_TokenCat(2, L, I);
+ free(L);
+ free(I);
+}
+decl_scalar_type(type_) ::= LONG(L1) LONG(L2) INT(I). {
+ type_ = PSI_TokenCat(3, L1, L2, I);
+ free(L1);
+ free(L2);
+ free(I);
+}
+decl_scalar_type(type_) ::= LONG(L1) LONG(L2). {
+ type_ = PSI_TokenCat(2, L1, L2);
+ free(L1);
+ free(L2);
+}
+decl_type(type_) ::= UNSIGNED(U) decl_scalar_type(N). {
+ PSI_Token *T = PSI_TokenCat(2, U, N);
type_ = init_decl_type(T->type, T->text);
type_->token = T;
+ free(U);
+ free(N);
}
-/* unsigned, urgh */
-decl_type(type_) ::= UNSIGNED NAME(T). {
+decl_type(type_) ::= SIGNED(S) decl_scalar_type(N). {
+ PSI_Token *T = PSI_TokenCat(2, S, N);
type_ = init_decl_type(T->type, T->text);
type_->token = T;
- type_->name = realloc(type_->name, T->size + sizeof("unsigned"));
- memmove(type_->name + sizeof("unsigned"), type_->name, T->size);
- memcpy(type_->name, "unsigned", sizeof("unsigned")-1);
- type_->name[sizeof("unsigned")] = ' ';
- type_->name[T->size + sizeof("unsigned")] = 0;
-}
-/* we have to support plain int here because we have it in our lexer rules */
-decl_type(type_) ::= INT(T). {
- type_ = init_decl_type(PSI_T_NAME, T->text);
- type_->token = T;
+ free(S);
+ free(N);
}
/* structs ! */
decl_type(type_) ::= STRUCT(S) NAME(T). {
type_->token = T;
free(S);
}
+decl_type(type_) ::= LONG(L) DOUBLE(D). {
+ PSI_Token *T = PSI_TokenCat(2, L, D);
+ type_ = init_decl_type(T->type, T->text);
+ type_->token = T;
+ free(L);
+ free(D);
+}
+%token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME.
+%type decl_type {decl_type*}
+%destructor decl_type {free_decl_type($$);}
+decl_type(type_) ::= decl_type_token(T). {
+ type_ = init_decl_type(T->type, T->text);
+ type_->token = T;
+}
+
%type const_decl_type {decl_type*}
%destructor const_decl_type {free_decl_type($$);}