flush
authorMichael Wallner <mike@php.net>
Mon, 1 Feb 2016 12:13:08 +0000 (13:13 +0100)
committerMichael Wallner <mike@php.net>
Mon, 1 Feb 2016 12:13:08 +0000 (13:13 +0100)
config.m4
m4/ax_check_sign.m4
m4/ax_pthread.m4 [new file with mode: 0644]
m4/psi.m4
m4/psi_struct.m4
m4/psi_type.m4
m4/signal.m4 [new file with mode: 0644]
m4/stdlib.m4
m4/unistd.m4 [new file with mode: 0644]
src/context.c
src/context_validate.c

index 74fefdb..447ffe6 100644 (file)
--- a/config.m4
+++ b/config.m4
@@ -3,6 +3,7 @@ PHP_PSI_BUILDDIR=PHP_EXT_BUILDDIR(psi)
 
 m4_foreach(incfile, [
        [ax_check_sign.m4],
+       [ax_pthread.m4],
        [psi.m4],
        [psi_type.m4],
        [psi_const.m4],
@@ -30,8 +31,10 @@ m4_foreach(incfile, [
        [netinet_in.m4],
        [netinet_tcp.m4],
        [poll.m4],
+       [signal.m4],
        [syslog.m4],
        [time.m4],
+       [unistd.m4],
        [wchar.m4],
        [wctype.m4]], [
        dnl pecl build
@@ -54,6 +57,8 @@ PHP_ARG_WITH(psi-libffi, where to find libffi,
 
 if test "$PHP_PSI" != no; then
        PHP_CONFIGURE_PART(Configuring PSI)
+       
+       ifdef([AC_USE_SYSTEM_EXTENSIONS],AC_USE_SYSTEM_EXTENSIONS)
 
        PSI_LEMON
        PSI_CHECK_LIBJIT
@@ -73,6 +78,7 @@ if test "$PHP_PSI" != no; then
        PSI_CHECK_LOCALE
        PSI_CHECK_STDIO
        PSI_CHECK_STDLIB
+       PSI_CHECK_UNISTD
        PSI_CHECK_TIME
        PSI_CHECK_SYS_SELECT
        PSI_CHECK_SYS_SOCKET
@@ -86,6 +92,7 @@ if test "$PHP_PSI" != no; then
        PSI_CHECK_NETINET_IN
        PSI_CHECK_NETINET_TCP
        PSI_CHECK_POLL
+       PSI_CHECK_SIGNAL
        PSI_CHECK_SYSLOG
        PSI_CHECK_WCHAR
        PSI_CHECK_WCTYPE
@@ -98,6 +105,7 @@ if test "$PHP_PSI" != no; then
        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_UNIONS], [$PSI_UNIONS], [Predefined structs])
        AC_DEFINE_UNQUOTED([PSI_CONSTS], [$PSI_CONSTS], [Predefined constants])
        AC_DEFINE_UNQUOTED([PSI_MACROS], [$PSI_MACROS], [Redirected Macros])
        AC_DEFINE_UNQUOTED([PSI_REDIRS], [$PSI_REDIRS], [Redirected functions])
index 244865f..5c925c2 100644 (file)
@@ -1,3 +1,42 @@
+# ===========================================================================
+#       http://www.gnu.org/software/autoconf-archive/ax_check_sign.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_SIGN (TYPE, [ACTION-IF-SIGNED], [ACTION-IF-UNSIGNED], [INCLUDES])
+#
+# DESCRIPTION
+#
+#   Checks whether TYPE is signed or not. If no INCLUDES are specified, the
+#   default includes are used. If ACTION-IF-SIGNED is given, it is
+#   additional shell code to execute when the type is signed. If
+#   ACTION-IF-UNSIGNED is given, it is executed when the type is unsigned.
+#
+#   This macro assumes that the type exists. Therefore the existence of the
+#   type should be checked before calling this macro. For example:
+#
+#     AC_CHECK_HEADERS([wchar.h])
+#     AC_CHECK_TYPE([wchar_t],,[ AC_MSG_ERROR([Type wchar_t not found.]) ])
+#     AX_CHECK_SIGN([wchar_t],
+#       [ AC_DEFINE(WCHAR_T_SIGNED, 1, [Define if wchar_t is signed]) ],
+#       [ AC_DEFINE(WCHAR_T_UNSIGNED, 1, [Define if wchar_t is unsigned]) ], [
+#     #ifdef HAVE_WCHAR_H
+#     #include <wchar.h>
+#     #endif
+#     ])
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Ville Laurikari <vl@iki.fi>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 6
+
 AC_DEFUN([AX_CHECK_SIGN], [
        typename=`echo $1 | sed "s/@<:@^a-zA-Z0-9_@:>@/_/g"`
        AC_CACHE_CHECK([whether $1 is signed], ax_cv_decl_${typename}_signed, [
diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4
new file mode 100644 (file)
index 0000000..d383ad5
--- /dev/null
@@ -0,0 +1,332 @@
+# ===========================================================================
+#        http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC to any special C compiler that is needed for
+#   multi-threaded programs (defaults to the value of CC otherwise). (This
+#   is necessary on AIX to use the special cc_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also link it with them as well. e.g. you should link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threads programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#     LIBS="$PTHREAD_LIBS $LIBS"
+#     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#     CC="$PTHREAD_CC"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+#   PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+#   PTHREAD_CFLAGS.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+#   Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+#   Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 21
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
+        AC_MSG_RESULT([$ax_pthread_ok])
+        if test x"$ax_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case ${host_os} in
+        solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+        ;;
+
+        darwin*)
+        ax_pthread_flags="-pthread $ax_pthread_flags"
+        ;;
+esac
+
+# Clang doesn't consider unrecognized options an error unless we specify
+# -Werror. We throw in some extra Clang-specific options to ensure that
+# this doesn't happen for GCC, which also accepts -Werror.
+
+AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
+save_CFLAGS="$CFLAGS"
+ax_pthread_extra_flags="-Werror"
+CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
+                  [AC_MSG_RESULT([yes])],
+                  [ax_pthread_extra_flags=
+                   AC_MSG_RESULT([no])])
+CFLAGS="$save_CFLAGS"
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+                pthread-config)
+                AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+                if test x"$ax_pthread_config" = xno; then continue; fi
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+                        static void routine(void *a) { a = 0; }
+                        static void *start_routine(void *a) { return a; }],
+                       [pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */])],
+                [ax_pthread_ok=yes],
+                [])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT([$ax_pthread_ok])
+        if test "x$ax_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        AC_MSG_CHECKING([for joinable pthread attribute])
+        attr_name=unknown
+        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+            AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+                           [int attr = $attr; return attr /* ; */])],
+                [attr_name=$attr; break],
+                [])
+        done
+        AC_MSG_RESULT([$attr_name])
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case ${host_os} in
+            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
+            osf* | hpux*) flag="-D_REENTRANT";;
+            solaris*)
+            if test "$GCC" = "yes"; then
+                flag="-D_REENTRANT"
+            else
+                # TODO: What about Clang on Solaris?
+                flag="-mt -D_REENTRANT"
+            fi
+            ;;
+        esac
+        AC_MSG_RESULT([$flag])
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+            [ax_cv_PTHREAD_PRIO_INHERIT], [
+                AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+                                                [[int i = PTHREAD_PRIO_INHERIT;]])],
+                    [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+                    [ax_cv_PTHREAD_PRIO_INHERIT=no])
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+            [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != xyes; then
+            case $host_os in
+                aix*)
+                AS_CASE(["x/$CC"],
+                  [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+                  [#handle absolute path differently from PATH based program lookup
+                   AS_CASE(["x$CC"],
+                     [x/*],
+                     [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+                     [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+                ;;
+            esac
+        fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+        ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
+        :
+else
+        ax_pthread_ok=no
+        $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
index e8d8069..63407be 100644 (file)
--- a/m4/psi.m4
+++ b/m4/psi.m4
@@ -3,6 +3,7 @@ PSI_STDINC=$PHP_PSI_SRCDIR/php_psi_stdinc.h
 PSI_STDTYPES=$PHP_PSI_SRCDIR/php_psi_stdtypes.h
 PSI_TYPES=$PHP_PSI_SRCDIR/php_psi_types.h
 PSI_STRUCTS=$PHP_PSI_SRCDIR/php_psi_structs.h
+PSI_UNIONS=$PHP_PSI_SRCDIR/php_psi_unions.h
 PSI_CONSTS=$PHP_PSI_SRCDIR/php_psi_consts.h
 PSI_REDIRS=$PHP_PSI_SRCDIR/php_psi_redirs.h
 PSI_MACROS=$PHP_PSI_SRCDIR/php_psi_macros.h
@@ -49,6 +50,18 @@ static struct psi_predef_struct {
        size_t pointer_level;
        size_t array_size;
 } psi_predef_structs@<:@@:>@ = {
+EOF
+       cat >$PSI_UNIONS <<EOF
+/* generated by configure */
+static struct psi_predef_union {
+       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_unions@<:@@:>@ = {
 EOF
        cat >$PSI_CONSTS <<EOF
 /* generated by configure */
@@ -91,7 +104,7 @@ AC_DEFUN(PSI_CONFIG_DONE, [
 /* generated by configure */
 PSI_INCLUDES
 EOF
-       for i in $PSI_STDTYPES $PSI_TYPES $PSI_STRUCTS $PSI_CONSTS $PSI_REDIRS $PSI_DECLS $PSI_VA_DECLS; do
+       for i in $PSI_STDTYPES $PSI_TYPES $PSI_STRUCTS $PSI_UNIONS $PSI_CONSTS $PSI_REDIRS $PSI_DECLS $PSI_VA_DECLS; do
                cat >>$i <<EOF
        {0}
 };
@@ -99,13 +112,59 @@ EOF
        done
 ])
 
-dnl PSI_CONFIG_POSIX(section, headers)
-AC_DEFUN(PSI_CONFIG_POSIX, [
+dnl PSI_SH_CONFIG_POSIX_ENABLED(section)
+dnl Expand to $psi_config_posix_<section>
+AC_DEFUN(PSI_SH_CONFIG_POSIX_ENABLED, [$AS_TR_SH([psi_config_posix_]$1)])
+
+dnl PSI_CONFIG_POSIX_ENABLED(section, action-if-yes, action-if-not)
+dnl Internal. Used to check if --enable-psi-posix=section was given.
+AC_DEFUN(PSI_CONFIG_POSIX_ENABLED, [
+       AS_TR_SH([psi_config_posix_]$1)=false
        case "$PHP_PSI_POSIX" in
-       yes|all) ;;
-       *) expr "$PHP_PSI_POSIX" : '\b$1\b' >/dev/null || return 0 ;;
+       yes|all)
+               AS_TR_SH([psi_config_posix_]$1)=true 
+               ;;
+       *)
+               if expr "$PHP_PSI_POSIX" : '\b$1\b' >/dev/null; then
+                       AS_TR_SH([psi_config_posix_]$1)=true
+               fi
+               ;;
        esac
-       ifelse($2,,,AC_CHECK_HEADERS($2))
+       if $AS_TR_SH([psi_config_posix_]$1); then
+               ifelse([$2],,:,[$2])
+       else
+               ifelse([$3],,:,[$3])
+       fi
+])
+
+dnl PSI_TEST_POSIX_ENABLED(section, action-if-yes, action-if-not)
+dnl Shell-if test if PSI POSIX section was configured.
+AC_DEFUN(PSI_SH_TEST_POSIX_ENABLED, [
+       if test "PSI_SH_CONFIG_POSIX_ENABLED([$1])" && $PSI_SH_CONFIG_POSIX_ENABLED([$1]); then
+               ifelse([$2],,:,[$2])
+       else
+               ifelse([$3],,:,[$3])
+       fi
+])
+
+dnl PSI_CONFIG_POSIX(section, headers)
+AC_DEFUN(PSI_CONFIG_POSIX, [
+       PSI_CONFIG_POSIX_ENABLED($1, [
+               PHP_CONFIGURE_PART(Configuring PSI POSIX: $1)
+               ifelse([$2],,,AC_CHECK_HEADERS($2))
+       ], [
+               return 0
+       ])
+])
+
+AC_DEFUN(PSI_PTHREAD_ONCE, [
+       AX_PTHREAD([
+               LIBS="$PTHREAD_LIBS $LIBS"
+               CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+       ])
+])
+AC_DEFUN(PSI_PTHREAD, [
+       AC_REQUIRE([PSI_PTHREAD_ONCE])
 ])
 
 dnl PSI_INCLUDES()
@@ -169,6 +228,9 @@ AC_DEFUN(PSI_INCLUDES, [AC_INCLUDES_DEFAULT()
 #ifdef HAVE_TIME_H
 # include <time.h>
 #endif
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
 #ifdef HAVE_SYSLOG_H
 # include <syslog.h>
 #endif
@@ -204,10 +266,22 @@ dnl PSI_SH_SIZEOF(type)
 dnl expand to shell variable $ac_cv_sizeof_<TYPE>
 AC_DEFUN([PSI_SH_SIZEOF], [$AS_TR_SH([ac_cv_sizeof_]$1)])
 
+dnl PSI_SH_OFFSETOF(type)
+dnl Expand to shell variable $ac_cv_offsetof_<TYPE>
+AC_DEFUN([PSI_SH_OFFSETOF], [$AS_TR_SH([ac_cv_offsetof_]$1)])
+
+dnl PSI_SH_ALIGNOF(type)
+dnl Expand to shell variable $ac_cv_offsetof_<TYPE>
+AC_DEFUN([PSI_SH_ALIGNOF], [$AS_TR_SH([ac_cv_alignof_]$1)])
+
 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_SH_TEST_ALIGNOF(type)
+dnl `if` condition to test if $ac_cv_alignof_$1 is greater than 0.
+AC_DEFUN([PSI_SH_TEST_ALIGNOF], [test -n "$AS_TR_SH([ac_cv_alignof_]$1)" && test "$AS_TR_SH([ac_cv_alignof_]$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.
@@ -219,6 +293,17 @@ AC_DEFUN(PSI_CHECK_SIZEOF, [
        fi
 ])
 
+dnl PSI_CHECK_ALIGNOF(type, special-includes)
+dnl AC_CHECK_ALIGNOF wrapper with PSI_INCLUDES
+dnl Defines psi\\ALIGNOF_<TYPE> pre-defined constant in $PSI_CONSTS.
+AC_DEFUN(PSI_CHECK_ALIGNOF, [
+       AC_CHECK_ALIGNOF($1, PSI_INCLUDES
+               $2)
+       if PSI_SH_TEST_ALIGNOF($1); then
+               psi_add_int_const "AS_TR_CPP([ALIGNOF_]$1)" "$AS_TR_SH([ac_cv_alignof_]$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.
@@ -238,10 +323,6 @@ AC_DEFUN(PSI_CHECK_OFFSETOF, [
        )
 ])
 
-dnl PSI_SH_OFFSETOF(type)
-dnl Expand to shell variable $ac_cv_offsetof_<TYPE>
-AC_DEFUN([PSI_SH_OFFSETOF], [$AS_TR_SH([ac_cv_offsetof_]$1)])
-
 
 dnl PSI_COMPUTE_STR(variable, string or expression)
 dnl Compute a string constant value in a similar manner like AC_COMPUTE_INT.
index 5a03dd5..c577430 100644 (file)
@@ -4,6 +4,12 @@ psi_add_struct() {
        cat >>$PSI_STRUCTS <<<" $1, {0}, "
 }
 
+# psi_add_union(union/struct members)
+# Add a pre-defined union to $PSI_UNIONS.
+psi_add_union() {
+       cat >>$PSI_UNIONS <<<"  $1, {0}, "
+}
+
 dnl PSI_STRUCT_MEMBER(struct name, decl member)
 dnl INTERNAL: build $psi_struct_members
 AC_DEFUN(PSI_STRUCT_MEMBER, [
@@ -40,15 +46,33 @@ AC_DEFUN(PSI_STRUCT_MEMBER, [
 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.
+dnl Calls PSI_CHECK_SIZEOF and PSI_CHECK_ALIGNOF for the struct.
+dnl Calls PSI_CHECK_SIZEOF, PSI_CHECK_OFFSETOF and PSI_TYPE_INDIRECTON for each member.
 AC_DEFUN(PSI_STRUCT, [
        PSI_CHECK_SIZEOF($1)
+       PSI_CHECK_ALIGNOF($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}"
+       psi_struct_members="{PSI_T_STRUCT, \"struct\", \"$psi_struct_name\", PSI_SH_ALIGNOF($1), PSI_SH_SIZEOF($1), 0, 0}"
        ifelse([$2],,,[m4_map_args_sep([PSI_STRUCT_MEMBER($1, m4_normalize(], [))], [], $2)])
        psi_add_struct "$psi_struct_members"
        if test "$1" = "$psi_struct_name"; then
                psi_add_type "{PSI_T_STRUCT, \"$1\", \"$1\"}"
        fi
 ])
+
+dnl PSI_UNION(union name, union/struct members)
+dnl Check a union and its members and add a pre-defined union and possibly a
+dnl pre-defined type for this union.
+dnl Calls PSI_CHECK_SIZEOF for the union and each member.
+dnl Calls PSI_CHECK_OFFSETOF and PSI_TYPE_INDIRECTON for each member.
+AC_DEFUN(PSI_UNION, [
+       PSI_CHECK_SIZEOF($1)
+       PSI_CHECK_ALIGNOF($1)
+       psi_struct_name=m4_bregexp([$1], [^\(union \)?\(\w+\)], [\2])
+       psi_struct_members="{PSI_T_UNION, \"union\", \"$psi_struct_name\", PSI_SH_ALIGNOF($1), PSI_SH_SIZEOF($1), 0, 0}"
+       ifelse([$2],,,[m4_map_args_sep([PSI_STRUCT_MEMBER($1, m4_normalize(], [))], [], $2)])
+       psi_add_union "$psi_struct_members"
+       if test "$1" = "$psi_struct_name"; then
+               psi_add_type "{PSI_T_UNION, \"$1\", \"$1\"}"
+       fi
+])
index 050f805..b635e17 100644 (file)
@@ -23,6 +23,9 @@ psi_type_pair() {
        struct*)
                echo "PSI_T_STRUCT, \"$2\""
                ;;
+       union*)
+               echo "PSI_T_UNION, \"$2\""
+               ;;
        void)
                echo "PSI_T_VOID, \"void\""
                ;;
@@ -86,7 +89,7 @@ AC_DEFUN(PSI_OPAQUE_TYPE, [
        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), [
+               AC_CACHE_CHECK(kind of $1, AS_TR_SH([psi_cv_type_class_]$1), [
                        AC_TRY_COMPILE(PSI_INCLUDES, [char test@<:@($1)1@:>@;], [
                                psi_type_class=scalar
                        ], [
@@ -114,7 +117,7 @@ AC_DEFUN(PSI_OPAQUE_TYPE, [
                        psi_add_type "{PSI_T_POINTER, \"void\", \"$1\"}"
                        ;;
                *)
-                       AC_MSG_WARN(could not detect type class of $1)
+                       AC_MSG_WARN(could not detect kind of $1)
                        ;;
                esac
        fi
@@ -162,6 +165,7 @@ 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])\"],
+       [union], [PSI_T_UNION, \"m4_bregexp([$1], [^union \(\w+\)], [\1])\"],
        [PSI_T_NAME, \"m4_bregexp([$1], [^\(\w+ \)*\w+], [\&])\"])])
 
 dnl PSI_CHECK_STD_TYPES()
diff --git a/m4/signal.m4 b/m4/signal.m4
new file mode 100644 (file)
index 0000000..8a0f141
--- /dev/null
@@ -0,0 +1,184 @@
+PSI_CHECK_SIGNAL() {
+       PSI_CONFIG_POSIX(signal, signal.h)
+       
+       PSI_PTHREAD
+       
+       PSI_CONST(SIG_DFL, int)
+       PSI_CONST(SIG_ERR, int)
+       PSI_CONST(SIG_HOLD, int)
+       PSI_CONST(SIG_IGN, int)
+       
+       PSI_CONST(SIGEV_NONE, int)
+       PSI_CONST(SIGEV_SIGNAL, int)
+       PSI_CONST(SIGEV_THREAD, int)
+       
+       PSI_MACRO(int SIGRTMIN)
+       PSI_MACRO(int SIGRTMAX)
+       PSI_MACRO(int RTSIG_MAX)
+       
+       PSI_CONST(SIGABRT, int)
+       PSI_CONST(SIGALRM, int)
+       PSI_CONST(SIGBUS, int)
+       PSI_CONST(SIGCHLD, int)
+       PSI_CONST(SIGCONT, int)
+       PSI_CONST(SIGFPE, int)
+       PSI_CONST(SIGHUP, int)
+       PSI_CONST(SIGILL, int)
+       PSI_CONST(SIGINT, int)
+       PSI_CONST(SIGKILL, int)
+       PSI_CONST(SIGPIPE, int)
+       PSI_CONST(SIGQUIT, int)
+       PSI_CONST(SIGSEGV, int)
+       PSI_CONST(SIGSTOP, int)
+       PSI_CONST(SIGTERM, int)
+       PSI_CONST(SIGTSTP, int)
+       PSI_CONST(SIGTTIN, int)
+       PSI_CONST(SIGTTOU, int)
+       PSI_CONST(SIGUSR1, int)
+       PSI_CONST(SIGUSR2, int)
+       PSI_CONST(SIGPOLL, int)
+       PSI_CONST(SIGPROF, int)
+       PSI_CONST(SIGSYS, int)
+       PSI_CONST(SIGTRAP, int)
+       PSI_CONST(SIGURG, int)
+       PSI_CONST(SIGVTALRM, int)
+       PSI_CONST(SIGXCPU, int)
+       PSI_CONST(SIGXFSZ, int)
+
+       PSI_MACRO(int SIG_BLOCK)
+       PSI_MACRO(int SIG_UNBLOCK)
+       PSI_MACRO(int SIG_SETMASK)
+       
+       PSI_CONST(SA_NOCLDSTOP, int)
+       PSI_CONST(SA_ONSTACK, int)
+       PSI_CONST(SA_RESETHAND, int)
+       PSI_CONST(SA_RESTART, int)
+       PSI_CONST(SA_SIGINFO, int)
+       PSI_CONST(SA_NOCLDWAIT, int)
+       PSI_CONST(SA_NODEFER, int)
+       PSI_CONST(SS_ONSTACK, int)
+       PSI_CONST(SS_DISABLE, int)
+       PSI_CONST(MINSIGSTKSZ, int)
+       PSI_CONST(SIGSTKSZ, int)
+
+       PSI_CONST(ILL_ILLOPC, int)
+       PSI_CONST(ILL_ILLOPN, int)
+       PSI_CONST(ILL_ILLADR, int)
+       PSI_CONST(ILL_ILLTRP, int)
+       PSI_CONST(ILL_PRVOPC, int)
+       PSI_CONST(ILL_PRVREG, int)
+       PSI_CONST(ILL_COPROC, int)
+       PSI_CONST(ILL_BADSTK, int)
+       PSI_CONST(FPE_INTDIV, int)
+       PSI_CONST(FPE_INTOVF, int)
+       PSI_CONST(FPE_FLTDIV, int)
+       PSI_CONST(FPE_FLTOVF, int)
+       PSI_CONST(FPE_FLTUND, int)
+       PSI_CONST(FPE_FLTRES, int)
+       PSI_CONST(FPE_FLTINV, int)
+       PSI_CONST(FPE_FLTSUB, int)
+       PSI_CONST(SEGV_MAPERR, int)
+       PSI_CONST(SEGV_ACCERR, int)
+       PSI_CONST(BUS_ADRALN, int)
+       PSI_CONST(BUS_ADRERR, int)
+       PSI_CONST(BUS_OBJERR, int)
+       PSI_CONST(TRAP_BRKPT, int)
+       PSI_CONST(TRAP_TRACE, int)
+       PSI_CONST(CLD_EXITED, int)
+       PSI_CONST(CLD_KILLED, int)
+       PSI_CONST(CLD_DUMPED, int)
+       PSI_CONST(CLD_TRAPPED, int)
+       PSI_CONST(CLD_STOPPED, int)
+       PSI_CONST(CLD_CONTINUED, int)
+       PSI_CONST(POLL_IN, int)
+       PSI_CONST(POLL_OUT, int)
+       PSI_CONST(POLL_MSG, int)
+       PSI_CONST(POLL_ERR, int)
+       PSI_CONST(POLL_PRI, int)
+       PSI_CONST(POLL_HUP, int)
+       PSI_CONST(SI_USER, int)
+       PSI_CONST(SI_QUEUE, int)
+       PSI_CONST(SI_TIMER, int)
+       PSI_CONST(SI_ASYNCIO, int)
+       PSI_CONST(SI_MESGQ, int)
+
+       PSI_TYPE(sig_atomic_t, int)
+       PSI_OPAQUE_TYPE(sigset_t)
+       PSI_OPAQUE_TYPE(mcontext_t)
+       
+       PSI_UNION(union sigval, [
+               int sival_int,
+               void *sival_ptr]
+       )
+       
+       PSI_STRUCT(struct sigevent, [
+               int sigev_notify,
+               int sigev_signo,
+               union sigval sigev_value]
+       )
+       
+       PSI_STRUCT(stack_t, [
+               void *ss_sp,
+               size_t ss_size,
+               int ss_flags]
+       )
+       
+       PSI_STRUCT(struct sigaction, [
+               void *sa_handler,
+               sigset_t sa_mask,
+               int sa_flags,
+               void *sa_sigaction]
+       )
+       
+       PSI_STRUCT(ucontext_t, [
+               ucontext_t *uc_link,
+               sigset_t uc_sigmask,
+               stack_t uc_stack,
+               mcontext_t uc_mcontext]
+       )
+       
+       PSI_STRUCT(siginfo_t, [
+               int si_signo,
+               int si_code,
+               int si_errno,
+               pid_t si_pid,
+               uid_t si_uid,
+               void *si_addr,
+               int si_status,
+               long si_band,
+               union sigval si_value]
+       )
+       
+       PSI_DECL(int kill, [(pid_t pid, int sig)])
+       PSI_DECL(int killpg, [(pid_t pgrp, int sig)])
+       PSI_DECL(void psiginfo, [(const siginfo_t *pinfo, const char *s)])
+       PSI_DECL(void psignal, [(int sig, const char *s)])
+       
+       PSI_SH_TEST_POSIX_ENABLED(pthread, [
+               PSI_DECL(int pthread_kill, [(pthread_t thread, int sig)])
+               PSI_DECL(int pthread_sigmask, [(int how, const sigset_t *set, sigset_t *oldset)])
+       ])
+       
+       PSI_DECL(int raise, [(int sig)])
+       PSI_DECL(int sigaction, [(int sig, const struct sigaction *act, struct sigaction *oact)])
+       PSI_DECL(int sigaddset, [(sigset_t * set, int signum)])
+       PSI_DECL(int sigaltstack, [(const stack_t *ss, stack_t *oss)])
+       PSI_DECL(int sigdelset, [(sigset_t *set, int signum)])
+       PSI_DECL(int sigemptyset, [(sigset_t *set)])
+       PSI_DECL(int sigfillset, [(sigset_t *set)])
+       PSI_DECL(int sighold, [(int sig)])
+       PSI_DECL(int sigignore, [(int sig)])
+       PSI_DECL(int siginterrupt, [(int sig, int flag)])
+       PSI_DECL(int sigismember, [(const sigset_t *set, int signum)])
+       PSI_DECL(void *signal, [(int sig, void *func)])
+       PSI_DECL(int sigpause, [(int sig)])
+       PSI_DECL(int sigpending, [(sigset_t *set)])
+       PSI_DECL(int sigprocmask, [(int how, const sigset_t *set, sigset_t *oset)])
+       PSI_DECL(int sigqueue, [(pid_t pid, int sig, const union sigval value)])
+       PSI_DECL(int sigrelse, [(int sig)])
+       PSI_DECL(void *sigset, [(int sig, void *disp)])
+       PSI_DECL(int sigsuspend, [(const sigset_t *sigmask)])
+       PSI_DECL(int sigtimedwait, [(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)])
+       PSI_DECL(int sigwait, [(const sigset_t *set, int *sig)])
+       PSI_DECL(int sigwaitinfo, [(const sigset_t *set, siginfo_t *info)])
+}
\ No newline at end of file
index 99ca54e..4f2f739 100644 (file)
@@ -57,7 +57,11 @@ PSI_CHECK_STDLIB() {
        PSI_DECL(char *realpath, [(char *path, char *resolved)])
        PSI_DECL(unsigned short *seed48, [(unsigned short seed16v@<:@3@:>@)])
        PSI_DECL(int setenv, [(char *var)])
-       PSI_DECL(void setkey, [(char *key)])
+       
+       AC_SEARCH_LIBS(setkey, crypt, [
+               PSI_DECL(void setkey, [(char *key)])
+       ])
+       
        PSI_DECL(char *setstate, [(char *state)])
        PSI_DECL(void srand, [(unsigned seed)])
        PSI_DECL(void srand48, [(long seed)])
diff --git a/m4/unistd.m4 b/m4/unistd.m4
new file mode 100644 (file)
index 0000000..a5a4ff6
--- /dev/null
@@ -0,0 +1,378 @@
+PSI_CHECK_UNISTD() {
+       PSI_CONFIG_POSIX(unistd, unistd.h)
+       
+       PSI_CONST(F_LOCK, int)
+       PSI_CONST(F_TEST, int)
+       PSI_CONST(F_TLOCK, int)
+       PSI_CONST(F_ULOCK, int)
+       PSI_CONST(F_OK, int)
+       PSI_CONST(R_OK, int)
+       PSI_CONST(W_OK, int)
+       PSI_CONST(X_OK, int)
+       PSI_CONST(STDERR_FILENO, int)
+       PSI_CONST(STDIN_FILENO, int)
+       PSI_CONST(STDOUT_FILENO, int)
+       PSI_CONST(_CS_PATH, int)
+       PSI_CONST(_CS_POSIX_V6_ILP32_OFF32_CFLAGS, int)
+       PSI_CONST(_CS_POSIX_V6_ILP32_OFF32_LDFLAGS, int)
+       PSI_CONST(_CS_POSIX_V6_ILP32_OFF32_LIBS, int)
+       PSI_CONST(_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS, int)
+       PSI_CONST(_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS, int)
+       PSI_CONST(_CS_POSIX_V6_ILP32_OFFBIG_LIBS, int)
+       PSI_CONST(_CS_POSIX_V6_LP64_OFF64_CFLAGS, int)
+       PSI_CONST(_CS_POSIX_V6_LP64_OFF64_LDFLAGS, int)
+       PSI_CONST(_CS_POSIX_V6_LP64_OFF64_LIBS, int)
+       PSI_CONST(_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS, int)
+       PSI_CONST(_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS, int)
+       PSI_CONST(_CS_POSIX_V6_LPBIG_OFFBIG_LIBS, int)
+       PSI_CONST(_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS, int)
+       PSI_CONST(_CS_POSIX_V7_ILP32_OFF32_CFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_ILP32_OFF32_LDFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_ILP32_OFF32_LIBS, int)
+       PSI_CONST(_CS_POSIX_V7_ILP32_OFFBIG_CFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_ILP32_OFFBIG_LIBS, int)
+       PSI_CONST(_CS_POSIX_V7_LP64_OFF64_CFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_LP64_OFF64_LDFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_LP64_OFF64_LIBS, int)
+       PSI_CONST(_CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_LPBIG_OFFBIG_LIBS, int)
+       PSI_CONST(_CS_POSIX_V7_THREADS_CFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_THREADS_LDFLAGS, int)
+       PSI_CONST(_CS_POSIX_V7_WIDTH_RESTRICTED_ENVS, int)
+       PSI_CONST(_CS_V6_ENV, int)
+       PSI_CONST(_CS_V7_ENV, int)
+       PSI_CONST(_PC_2_SYMLINKS, int)
+       PSI_CONST(_PC_ALLOC_SIZE_MIN, int)
+       PSI_CONST(_PC_ASYNC_IO, int)
+       PSI_CONST(_PC_CHOWN_RESTRICTED, int)
+       PSI_CONST(_PC_FILESIZEBITS, int)
+       PSI_CONST(_PC_LINK_MAX, int)
+       PSI_CONST(_PC_MAX_CANON, int)
+       PSI_CONST(_PC_MAX_INPUT, int)
+       PSI_CONST(_PC_NAME_MAX, int)
+       PSI_CONST(_PC_NO_TRUNC, int)
+       PSI_CONST(_PC_PATH_MAX, int)
+       PSI_CONST(_PC_PIPE_BUF, int)
+       PSI_CONST(_PC_PRIO_IO, int)
+       PSI_CONST(_PC_REC_INCR_XFER_SIZE, int)
+       PSI_CONST(_PC_REC_MAX_XFER_SIZE, int)
+       PSI_CONST(_PC_REC_MIN_XFER_SIZE, int)
+       PSI_CONST(_PC_REC_XFER_ALIGN, int)
+       PSI_CONST(_PC_SYMLINK_MAX, int)
+       PSI_CONST(_PC_SYNC_IO, int)
+       PSI_CONST(_PC_TIMESTAMP_RESOLUTION, int)
+       PSI_CONST(_PC_VDISABLE, int)
+       PSI_CONST(_POSIX2_CHAR_TERM, int)
+       PSI_CONST(_POSIX2_C_BIND, int)
+       PSI_CONST(_POSIX2_C_DEV, int)
+       PSI_CONST(_POSIX2_FORT_DEV, int)
+       PSI_CONST(_POSIX2_FORT_RUN, int)
+       PSI_CONST(_POSIX2_LOCALEDEF, int)
+       PSI_CONST(_POSIX2_PBS, int)
+       PSI_CONST(_POSIX2_PBS_ACCOUNTING, int)
+       PSI_CONST(_POSIX2_PBS_CHECKPOINT, int)
+       PSI_CONST(_POSIX2_PBS_LOCATE, int)
+       PSI_CONST(_POSIX2_PBS_MESSAGE, int)
+       PSI_CONST(_POSIX2_PBS_TRACK, int)
+       PSI_CONST(_POSIX2_SW_DEV, int)
+       PSI_CONST(_POSIX2_SYMLINKS, int)
+       PSI_CONST(_POSIX2_UPE, int)
+       PSI_CONST(_POSIX2_VERSION, int)
+       PSI_CONST(_POSIX_ADVISORY_INFO, int)
+       PSI_CONST(_POSIX_ASYNCHRONOUS_IO, int)
+       PSI_CONST(_POSIX_ASYNC_IO, int)
+       PSI_CONST(_POSIX_BARRIERS, int)
+       PSI_CONST(_POSIX_CHOWN_RESTRICTED, int)
+       PSI_CONST(_POSIX_CLOCK_SELECTION, int)
+       PSI_CONST(_POSIX_CPUTIME, int)
+       PSI_CONST(_POSIX_FSYNC, int)
+       PSI_CONST(_POSIX_IPV6, int)
+       PSI_CONST(_POSIX_JOB_CONTROL, int)
+       PSI_CONST(_POSIX_MAPPED_FILES, int)
+       PSI_CONST(_POSIX_MEMLOCK, int)
+       PSI_CONST(_POSIX_MEMLOCK_RANGE, int)
+       PSI_CONST(_POSIX_MEMORY_PROTECTION, int)
+       PSI_CONST(_POSIX_MESSAGE_PASSING, int)
+       PSI_CONST(_POSIX_MONOTONIC_CLOCK, int)
+       PSI_CONST(_POSIX_NO_TRUNC, int)
+       PSI_CONST(_POSIX_PRIORITIZED_IO, int)
+       PSI_CONST(_POSIX_PRIORITY_SCHEDULING, int)
+       PSI_CONST(_POSIX_PRIO_IO, int)
+       PSI_CONST(_POSIX_RAW_SOCKETS, int)
+       PSI_CONST(_POSIX_READER_WRITER_LOCKS, int)
+       PSI_CONST(_POSIX_REALTIME_SIGNALS, int)
+       PSI_CONST(_POSIX_REGEXP, int)
+       PSI_CONST(_POSIX_SAVED_IDS, int)
+       PSI_CONST(_POSIX_SEMAPHORES, int)
+       PSI_CONST(_POSIX_SHARED_MEMORY_OBJECTS, int)
+       PSI_CONST(_POSIX_SHELL, int)
+       PSI_CONST(_POSIX_SPAWN, int)
+       PSI_CONST(_POSIX_SPIN_LOCKS, int)
+       PSI_CONST(_POSIX_SPORADIC_SERVER, int)
+       PSI_CONST(_POSIX_SYNCHRONIZED_IO, int)
+       PSI_CONST(_POSIX_SYNC_IO, int)
+       PSI_CONST(_POSIX_THREADS, int)
+       PSI_CONST(_POSIX_THREAD_ATTR_STACKADDR, int)
+       PSI_CONST(_POSIX_THREAD_ATTR_STACKSIZE, int)
+       PSI_CONST(_POSIX_THREAD_CPUTIME, int)
+       PSI_CONST(_POSIX_THREAD_PRIORITY_SCHEDULING, int)
+       PSI_CONST(_POSIX_THREAD_PRIO_INHERIT, int)
+       PSI_CONST(_POSIX_THREAD_PRIO_PROTECT, int)
+       PSI_CONST(_POSIX_THREAD_PROCESS_SHARED, int)
+       PSI_CONST(_POSIX_THREAD_ROBUST_PRIO_INHERIT, int)
+       PSI_CONST(_POSIX_THREAD_ROBUST_PRIO_PROTECT, int)
+       PSI_CONST(_POSIX_THREAD_SAFE_FUNCTIONS, int)
+       PSI_CONST(_POSIX_THREAD_SPORADIC_SERVER, int)
+       PSI_CONST(_POSIX_TIMEOUTS, int)
+       PSI_CONST(_POSIX_TIMERS, int)
+       PSI_CONST(_POSIX_TIMESTAMP_RESOLUTION, int)
+       PSI_CONST(_POSIX_TRACE, int)
+       PSI_CONST(_POSIX_TRACE_EVENT_FILTER, int)
+       PSI_CONST(_POSIX_TRACE_INHERIT, int)
+       PSI_CONST(_POSIX_TRACE_LOG, int)
+       PSI_CONST(_POSIX_TYPED_MEMORY_OBJECTS, int)
+       PSI_CONST(_POSIX_V6_ILP32_OFF32, int)
+       PSI_CONST(_POSIX_V6_ILP32_OFFBIG, int)
+       PSI_CONST(_POSIX_V6_LP64_OFF64, int)
+       PSI_CONST(_POSIX_V6_LPBIG_OFFBIG, int)
+       PSI_CONST(_POSIX_V7_ILP32_OFF32, int)
+       PSI_CONST(_POSIX_V7_ILP32_OFFBIG, int)
+       PSI_CONST(_POSIX_V7_LP64_OFF64, int)
+       PSI_CONST(_POSIX_V7_LPBIG_OFFBIG, int)
+       PSI_CONST(_POSIX_VDISABLE, int)
+       PSI_CONST(_POSIX_VERSION, int)
+       PSI_CONST(_SC_2_CHAR_TERM, int)
+       PSI_CONST(_SC_2_C_BIND, int)
+       PSI_CONST(_SC_2_C_DEV, int)
+       PSI_CONST(_SC_2_FORT_DEV, int)
+       PSI_CONST(_SC_2_FORT_RUN, int)
+       PSI_CONST(_SC_2_LOCALEDEF, int)
+       PSI_CONST(_SC_2_PBS, int)
+       PSI_CONST(_SC_2_PBS_ACCOUNTING, int)
+       PSI_CONST(_SC_2_PBS_CHECKPOINT, int)
+       PSI_CONST(_SC_2_PBS_LOCATE, int)
+       PSI_CONST(_SC_2_PBS_MESSAGE, int)
+       PSI_CONST(_SC_2_PBS_TRACK, int)
+       PSI_CONST(_SC_2_SW_DEV, int)
+       PSI_CONST(_SC_2_UPE, int)
+       PSI_CONST(_SC_2_VERSION, int)
+       PSI_CONST(_SC_ADVISORY_INFO, int)
+       PSI_CONST(_SC_AIO_LISTIO_MAX, int)
+       PSI_CONST(_SC_AIO_MAX, int)
+       PSI_CONST(_SC_AIO_PRIO_DELTA_MAX, int)
+       PSI_CONST(_SC_ARG_MAX, int)
+       PSI_CONST(_SC_ASYNCHRONOUS_IO, int)
+       PSI_CONST(_SC_ATEXIT_MAX, int)
+       PSI_CONST(_SC_BARRIERS, int)
+       PSI_CONST(_SC_BC_BASE_MAX, int)
+       PSI_CONST(_SC_BC_DIM_MAX, int)
+       PSI_CONST(_SC_BC_SCALE_MAX, int)
+       PSI_CONST(_SC_BC_STRING_MAX, int)
+       PSI_CONST(_SC_CHILD_MAX, int)
+       PSI_CONST(_SC_CLK_TCK, int)
+       PSI_CONST(_SC_CLOCK_SELECTION, int)
+       PSI_CONST(_SC_COLL_WEIGHTS_MAX, int)
+       PSI_CONST(_SC_CPUTIME, int)
+       PSI_CONST(_SC_DELAYTIMER_MAX, int)
+       PSI_CONST(_SC_EXPR_NEST_MAX, int)
+       PSI_CONST(_SC_FSYNC, int)
+       PSI_CONST(_SC_GETGR_R_SIZE_MAX, int)
+       PSI_CONST(_SC_GETPW_R_SIZE_MAX, int)
+       PSI_CONST(_SC_HOST_NAME_MAX, int)
+       PSI_CONST(_SC_IOV_MAX, int)
+       PSI_CONST(_SC_IPV6, int)
+       PSI_CONST(_SC_JOB_CONTROL, int)
+       PSI_CONST(_SC_LINE_MAX, int)
+       PSI_CONST(_SC_LOGIN_NAME_MAX, int)
+       PSI_CONST(_SC_MAPPED_FILES, int)
+       PSI_CONST(_SC_MEMLOCK, int)
+       PSI_CONST(_SC_MEMLOCK_RANGE, int)
+       PSI_CONST(_SC_MEMORY_PROTECTION, int)
+       PSI_CONST(_SC_MESSAGE_PASSING, int)
+       PSI_CONST(_SC_MONOTONIC_CLOCK, int)
+       PSI_CONST(_SC_MQ_OPEN_MAX, int)
+       PSI_CONST(_SC_MQ_PRIO_MAX, int)
+       PSI_CONST(_SC_NGROUPS_MAX, int)
+       PSI_CONST(_SC_OPEN_MAX, int)
+       PSI_CONST(_SC_PAGESIZE, int)
+       PSI_CONST(_SC_PAGE_SIZE, int)
+       PSI_CONST(_SC_PRIORITIZED_IO, int)
+       PSI_CONST(_SC_PRIORITY_SCHEDULING, int)
+       PSI_CONST(_SC_RAW_SOCKETS, int)
+       PSI_CONST(_SC_READER_WRITER_LOCKS, int)
+       PSI_CONST(_SC_REALTIME_SIGNALS, int)
+       PSI_CONST(_SC_REGEXP, int)
+       PSI_CONST(_SC_RE_DUP_MAX, int)
+       PSI_CONST(_SC_RTSIG_MAX, int)
+       PSI_CONST(_SC_SAVED_IDS, int)
+       PSI_CONST(_SC_SEMAPHORES, int)
+       PSI_CONST(_SC_SEM_NSEMS_MAX, int)
+       PSI_CONST(_SC_SEM_VALUE_MAX, int)
+       PSI_CONST(_SC_SHARED_MEMORY_OBJECTS, int)
+       PSI_CONST(_SC_SHELL, int)
+       PSI_CONST(_SC_SIGQUEUE_MAX, int)
+       PSI_CONST(_SC_SPAWN, int)
+       PSI_CONST(_SC_SPIN_LOCKS, int)
+       PSI_CONST(_SC_SPORADIC_SERVER, int)
+       PSI_CONST(_SC_SS_REPL_MAX, int)
+       PSI_CONST(_SC_STREAM_MAX, int)
+       PSI_CONST(_SC_SYMLOOP_MAX, int)
+       PSI_CONST(_SC_SYNCHRONIZED_IO, int)
+       PSI_CONST(_SC_THREADS, int)
+       PSI_CONST(_SC_THREAD_ATTR_STACKADDR, int)
+       PSI_CONST(_SC_THREAD_ATTR_STACKSIZE, int)
+       PSI_CONST(_SC_THREAD_CPUTIME, int)
+       PSI_CONST(_SC_THREAD_DESTRUCTOR_ITERATIONS, int)
+       PSI_CONST(_SC_THREAD_KEYS_MAX, int)
+       PSI_CONST(_SC_THREAD_PRIORITY_SCHEDULING, int)
+       PSI_CONST(_SC_THREAD_PRIO_INHERIT, int)
+       PSI_CONST(_SC_THREAD_PRIO_PROTECT, int)
+       PSI_CONST(_SC_THREAD_PROCESS_SHARED, int)
+       PSI_CONST(_SC_THREAD_ROBUST_PRIO_INHERIT, int)
+       PSI_CONST(_SC_THREAD_ROBUST_PRIO_PROTECT, int)
+       PSI_CONST(_SC_THREAD_SAFE_FUNCTIONS, int)
+       PSI_CONST(_SC_THREAD_SPORADIC_SERVER, int)
+       PSI_CONST(_SC_THREAD_STACK_MIN, int)
+       PSI_CONST(_SC_THREAD_THREADS_MAX, int)
+       PSI_CONST(_SC_TIMEOUTS, int)
+       PSI_CONST(_SC_TIMERS, int)
+       PSI_CONST(_SC_TIMER_MAX, int)
+       PSI_CONST(_SC_TRACE, int)
+       PSI_CONST(_SC_TRACE_EVENT_FILTER, int)
+       PSI_CONST(_SC_TRACE_EVENT_NAME_MAX, int)
+       PSI_CONST(_SC_TRACE_INHERIT, int)
+       PSI_CONST(_SC_TRACE_LOG, int)
+       PSI_CONST(_SC_TRACE_NAME_MAX, int)
+       PSI_CONST(_SC_TRACE_SYS_MAX, int)
+       PSI_CONST(_SC_TRACE_USER_EVENT_MAX, int)
+       PSI_CONST(_SC_TTY_NAME_MAX, int)
+       PSI_CONST(_SC_TYPED_MEMORY_OBJECTS, int)
+       PSI_CONST(_SC_TZNAME_MAX, int)
+       PSI_CONST(_SC_V6_ILP32_OFF32, int)
+       PSI_CONST(_SC_V6_ILP32_OFFBIG, int)
+       PSI_CONST(_SC_V6_LP64_OFF64, int)
+       PSI_CONST(_SC_V6_LPBIG_OFFBIG, int)
+       PSI_CONST(_SC_V7_ILP32_OFF32, int)
+       PSI_CONST(_SC_V7_ILP32_OFFBIG, int)
+       PSI_CONST(_SC_V7_LP64_OFF64, int)
+       PSI_CONST(_SC_V7_LPBIG_OFFBIG, int)
+       PSI_CONST(_SC_VERSION, int)
+       PSI_CONST(_SC_XOPEN_CRYPT, int)
+       PSI_CONST(_SC_XOPEN_ENH_I18N, int)
+       PSI_CONST(_SC_XOPEN_REALTIME, int)
+       PSI_CONST(_SC_XOPEN_REALTIME_THREADS, int)
+       PSI_CONST(_SC_XOPEN_SHM, int)
+       PSI_CONST(_SC_XOPEN_STREAMS, int)
+       PSI_CONST(_SC_XOPEN_UNIX, int)
+       PSI_CONST(_SC_XOPEN_UUCP, int)
+       PSI_CONST(_SC_XOPEN_VERSION, int)
+       PSI_CONST(_XOPEN_CRYPT, int)
+       PSI_CONST(_XOPEN_ENH_I18N, int)
+       PSI_CONST(_XOPEN_REALTIME, int)
+       PSI_CONST(_XOPEN_REALTIME_THREADS, int)
+       PSI_CONST(_XOPEN_SHM, int)
+       PSI_CONST(_XOPEN_STREAMS, int)
+       PSI_CONST(_XOPEN_UNIX, int)
+       PSI_CONST(_XOPEN_UUCP, int)
+       PSI_CONST(_XOPEN_VERSION, int)
+       
+       PSI_EXTVAR(char *optarg)
+       PSI_EXTVAR(int opterr)
+       PSI_EXTVAR(int optind)
+       PSI_EXTVAR(int optopt)
+       
+       PSI_DECL(int access, [(const char *path, int amode)])
+       PSI_DECL(unsigned alarm, [(unsigned seconds)])
+       PSI_DECL(int chdir, [(const char *path)])
+       PSI_DECL(int chown, [(const char *path, uid_t owner, gid_t group)])
+       PSI_DECL(int close, [(int fildes)])
+       PSI_DECL(size_t confstr, [(int name, char *buf, size_t len)])
+       
+       AC_SEARCH_LIBS(crypt, crypt, [
+               PSI_DECL(char *crypt, [(const char *key, const char *salt)])
+       ])
+       
+       PSI_DECL(int dup, [(int fildes)])
+       PSI_DECL(int dup2, [(int fildes, int fildes2)])
+       
+       AC_SEARCH_LIBS(encrypt, crypt, [
+               PSI_DECL(void encrypt, [(char block@<:@64@:>@, int edflag)])
+       ])
+       
+       PSI_DECL(void _exit, [(int status)])
+       PSI_DECL(int execl, [(const char *path, const char *arg)], vararg)
+       PSI_DECL(int execle, [(const char *path, const char *arg)], vararg)
+       PSI_DECL(int execlp, [(const char *file, const char *arg)], vararg)
+       PSI_DECL(int execv, [(const char *path, char **argv)])
+       PSI_DECL(int execve, [(const char *path, char **argv, char **envp)])
+       PSI_DECL(int execvp, [(const char *file, char **argv)])
+       PSI_DECL(int faccessat, [(int fd, const char *path, int amode, int flag)])
+       PSI_DECL(int fchdir, [(int fildes)])
+       PSI_DECL(int fchown, [(int fildes, uid_t owner, gid_tgroup)])
+       PSI_DECL(int fchownat, [(int fd, const char *path, uid_t owner, gid_t group, int flag)])
+       PSI_DECL(int fdatasync, [(int fildes)])
+       PSI_DECL(int fexecve, [(int fd, char **argv, char **envp)])
+       PSI_DECL(pid_t fork, [(void)])
+       PSI_DECL(long fpathconf, [(int fd, int name)])
+       PSI_DECL(int fsync, [(int fildes)])
+       PSI_DECL(int ftruncate, [(int fildes, off_t length)])
+       PSI_DECL(char *getcwd, [(char *buf, size_t size)])
+       PSI_DECL(gid_t getegid, [(void)])
+       PSI_DECL(uid_t geteuid, [(void)])
+       PSI_DECL(gid_t getgid, [(void)])
+       PSI_DECL(int getgroups, [(int gidsetsize, gid_t *grouplist)])
+       PSI_DECL(long gethostid, [(void)])
+       PSI_DECL(int gethostname, [(char * name, size_t namelen)])
+       PSI_DECL(char *getlogin, [(void)])
+       PSI_DECL(int getlogin_r, [(char *buf, size_t bufsize)])
+       PSI_DECL(int getopt, [(int argc, char **argv, const char *optstring)])
+       PSI_DECL(pid_t getpgid, [(pid_t pid)])
+       PSI_DECL(pid_t getpgrp, [(void)])
+       PSI_DECL(pid_t getpid, [(void)])
+       PSI_DECL(pid_t getppid, [(void)])
+       PSI_DECL(pid_t getsid, [(pid_t pid)])
+       PSI_DECL(uid_t getuid, [(void)])
+       PSI_DECL(int isatty, [(int fd)])
+       PSI_DECL(int lchown, [(const char *path, uid_t owner, gid_t group)])
+       PSI_DECL(int link, [(const char *path1, const char *path2)])
+       PSI_DECL(int linkat, [(int fd1, const char *path1, int fd2, const char *path2, int flag)])
+       PSI_DECL(int lockf, [(int fd, int cmd, off_t len)])
+       PSI_DECL(off_t lseek, [(int fildes, off_t offset, int whence)])
+       PSI_DECL(int nice, [(int incr)])
+       PSI_DECL(long pathconf, [(const char *path, int name)])
+       PSI_DECL(int pause, [(void)])
+       PSI_DECL(int pipe, [(int fildes@<:@2:>@)])
+       PSI_DECL(ssize_t pread, [(int fildes, void *buf, size_t nbyte, off_t offset)])
+       PSI_DECL(ssize_t pwrite, [(int fildes, const void *buf, size_t nbyte, off_t offset)])
+       PSI_DECL(ssize_t read, [(int fd, void *buf, size_t count)])
+       PSI_DECL(ssize_t readlink, [(const char *path, char *buf, size_t bufsize)])
+       PSI_DECL(ssize_t readlinkat, [(int fd, const char *path, char *buf, size_t bufsize)])
+       PSI_DECL(int rmdir, [(const char *path)])
+       PSI_DECL(int setegid, [(gid_t gid)])
+       PSI_DECL(int seteuid, [(uid_t uid)])
+       PSI_DECL(int setgid, [(gid_t gid)])
+       PSI_DECL(int setpgid, [(pid_t pid, pid_t pgid)])
+       PSI_DECL(pid_t setpgrp, [(void)])
+       PSI_DECL(int setregid, [(gid_t rgid, gid_t egid)])
+       PSI_DECL(int setreuid, [(uid_t ruid, uid_t euid)])
+       PSI_DECL(pid_t setsid, [(void)])
+       PSI_DECL(int setuid, [(uid_t uid)])
+       PSI_DECL(unsigned sleep, [(unsigned seconds)])
+       PSI_DECL(void swab, [(const void *from, void *to, ssize_t n)])
+       PSI_DECL(int symlink, [(const char *path1, const char *path2)])
+       PSI_DECL(int symlinkat, [(const char *path1, int fd, const char *path2)])
+       PSI_DECL(void sync, [(void)])
+       PSI_DECL(long sysconf, [(int name)])
+       PSI_DECL(pid_t tcgetpgrp, [(int fd)])
+       PSI_DECL(int tcsetpgrp, [(int fd, pid_t pgrp)])
+       PSI_DECL(int truncate, [(const char *path, off_t length)])
+       PSI_DECL(char *ttyname, [(int fd)])
+       PSI_DECL(int ttyname_r, [(int fd, char *buf, size_t buflen)])
+       PSI_DECL(int unlink, [(const char *path)])
+       PSI_DECL(int unlinkat, [(int fd, const char *path, int flag)])
+       PSI_DECL(ssize_t write, [(int fildes, const void *buf, size_t nbyte)])
+
+
+}
\ No newline at end of file
index 8bd2dee..17699a4 100644 (file)
@@ -35,7 +35,7 @@
 #include "php_psi_decls.h"
 #include "php_psi_va_decls.h"
 #include "php_psi_structs.h"
-
+#include "php_psi_unions.h"
 
 PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error, unsigned flags)
 {
@@ -43,6 +43,7 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr
        struct psi_predef_type *predef_type;
        struct psi_predef_const *predef_const;
        struct psi_predef_struct *predef_struct;
+       struct psi_predef_union *predef_union;
        struct psi_predef_decl *predef_decl;
 
        if (!C) {
@@ -85,6 +86,7 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr
                decl_struct *dstruct = init_decl_struct(predef_struct->var_name, dargs);
 
                dstruct->size = predef_struct->size;
+               dstruct->align = predef_struct->offset;
                for (member = &predef_struct[1]; member->type_tag; ++member) {
                        decl_type *type;
                        decl_var *dvar;
@@ -100,6 +102,28 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr
                T.structs = add_decl_struct(T.structs, dstruct);
                predef_struct = member;
        }
+       for (predef_union = &psi_predef_unions[0]; predef_union->type_tag; ++predef_union) {
+               struct psi_predef_union *member;
+               decl_args *dargs = init_decl_args(NULL);
+               decl_union *dunion = init_decl_union(predef_union->var_name, dargs);
+
+               dunion->size = predef_union->size;
+               dunion->align = dunion->offset;
+               for (member = &predef_union[1]; member->type_tag; ++member) {
+                       decl_type *type;
+                       decl_var *dvar;
+                       decl_arg *darg;
+
+                       type = init_decl_type(member->type_tag, member->type_name);
+                       dvar = init_decl_var(member->var_name, member->pointer_level, member->array_size);
+                       darg = init_decl_arg(type, dvar);
+                       darg->layout = init_decl_struct_layout(member->offset, member->size);
+                       dargs = add_decl_arg(dargs, darg);
+               }
+
+               T.unions = add_decl_union(T.unions, dunion);
+               predef_union = member;
+       }
        for (predef_decl = &psi_predef_decls[0]; predef_decl->type_tag; ++predef_decl) {
                struct psi_predef_decl *farg;
                decl_type *ftype = init_decl_type(predef_decl->type_tag, predef_decl->type_name);
index 12befca..826a6b3 100644 (file)
@@ -201,23 +201,23 @@ static inline void psi_sort_struct_args(void **args, size_t count) {
                        psi_sort_struct_arg_cmp, psi_sort_struct_arg_swp);
 }
 
-static inline int validate_decl_struct_darg(PSI_Data *data, decl_arg *darg) {
+static inline int validate_decl_struct_darg(PSI_Data *data, decl_arg *darg, void *current) {
        decl_type *real = real_decl_type(darg->type);
 
        /* pre-validate any structs/unions/enums */
        switch (real->type) {
        case PSI_T_STRUCT:
-               if (!validate_decl_struct(data, real->strct)) {
+               if ((current && current == real->strct) || !validate_decl_struct(data, real->strct)) {
                        return 0;
                }
                break;
        case PSI_T_UNION:
-               if (!validate_decl_union(data, real->unn)) {
+               if ((current && current == real->unn) || !validate_decl_union(data, real->unn)) {
                        return 0;
                }
                break;
        case PSI_T_ENUM:
-               if (!validate_decl_enum(data, real->enm)) {
+               if ((current && current == real->enm) || !validate_decl_enum(data, real->enm)) {
                        return 0;
                }
                break;
@@ -253,30 +253,81 @@ static inline size_t sizeof_decl_arg(decl_arg *darg) {
                }
        }
 
+       ZEND_ASSERT(size);
+
        return size;
 }
 
-static inline size_t align_decl_arg(decl_arg *darg, size_t *pos, size_t *len) {
+static inline size_t alignof_decl_type(decl_type *t);
+static inline size_t alignof_decl_arg(decl_arg *darg);
+static inline size_t alignof_decl_union(decl_union *u);
+static inline size_t alignof_decl_struct(decl_struct *s);
+
+static inline size_t alignof_decl_args(decl_args *args) {
+       size_t i, maxalign = 0;
+
+       for (i = 0; i < args->count; ++i) {
+               decl_arg *darg = args->args[i];
+               size_t align = alignof_decl_arg(darg);
+
+               if (align > maxalign) {
+                       maxalign = align;
+               }
+       }
+
+       return maxalign;
+}
+
+static inline size_t alignof_decl_struct(decl_struct *s) {
+       if (!s->align) {
+               s->align = alignof_decl_args(s->args);
+       }
+       return s->align;
+}
+
+static inline size_t alignof_decl_union(decl_union *u) {
+       if (!u->align) {
+               u->align = alignof_decl_args(u->args);
+       }
+       return u->align;
+}
+
+static inline size_t alignof_decl_type(decl_type *t) {
+       decl_type *real = real_decl_type(t);
+       size_t align;
+
+       switch (real->type) {
+       case PSI_T_STRUCT:
+               align = alignof_decl_struct(real->strct);
+               break;
+       case PSI_T_UNION:
+               align = alignof_decl_union(real->unn);
+               break;
+       case PSI_T_ENUM:
+       default:
+               align = psi_t_alignment(real->type);
+       }
+
+       return align;
+}
+
+static inline size_t alignof_decl_arg(decl_arg *darg) {
        size_t align;
 
        if (darg->var->pointer_level && (!darg->var->array_size || darg->var->pointer_level > 2)) {
                align = psi_t_alignment(PSI_T_POINTER);
        } else {
-               decl_type *real = real_decl_type(darg->type);
-
-               switch (real->type) {
-               case PSI_T_STRUCT:
-                       align = real->strct->align;
-                       break;
-               case PSI_T_UNION:
-                       align = real->unn->align;
-                       break;
-               default:
-                       align = psi_t_alignment(real->type);
-                       break;
-               }
+               align = alignof_decl_type(darg->type);
        }
 
+       return align;
+}
+
+static inline size_t align_decl_arg(decl_arg *darg, size_t *pos, size_t *len) {
+       size_t align = alignof_decl_arg(darg);
+
+       ZEND_ASSERT(align);
+
        *len = sizeof_decl_arg(darg);
        *pos = psi_align(align, *pos);
 
@@ -303,7 +354,9 @@ static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) {
                ZEND_ASSERT(!darg->var->arg || darg->var->arg == darg);
                darg->var->arg = darg;
 
-               if (darg->layout) {
+               if (!validate_decl_struct_darg(data, darg, s)) {
+                       return 0;
+               } else if (darg->layout) {
                        pos = darg->layout->pos;
 
                        align = align_decl_arg(darg, &pos, &len);
@@ -312,20 +365,16 @@ static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) {
                                data->error(data, darg->token, PSI_WARNING,
                                                "Computed size %zu of %s.%s does not match"
                                                " pre-defined size %zu of type '%s'",
-                                               darg->layout->len, s->name, darg->var->name, len,
+                                               len, s->name, darg->var->name, darg->layout->len,
                                                darg->type->name);
-                               return 0;
                        }
                        if (darg->layout->pos != pos) {
                                data->error(data, darg->token, PSI_WARNING,
                                                "Computed offset %zu of %s.%s does not match"
                                                " pre-defined offset %zu",
-                                               darg->layout->len, s->name, darg->var->name, len);
-                               return 0;
+                                               pos, s->name, darg->var->name, darg->layout->pos);
                        }
-               } else if (!validate_decl_struct_darg(data, darg)) {
-                       return 0;
-               } else {
+               } else  {
                        if (i) {
                                pos = s->args->args[i-1]->layout->pos +
                                                s->args->args[i-1]->layout->len;
@@ -357,7 +406,7 @@ static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) {
 }
 
 static inline int validate_decl_union(PSI_Data *data, decl_union *u) {
-       size_t i, pos, len, size, align;
+       size_t i, pos, len, size = 0, align;
 
        if (!u->size && !u->args->count) {
                data->error(data, u->token, PSI_WARNING,
@@ -376,27 +425,26 @@ static inline int validate_decl_union(PSI_Data *data, decl_union *u) {
                ZEND_ASSERT(!darg->var->arg || darg->var->arg == darg);
                darg->var->arg = darg;
 
-               if (darg->layout) {
+               if (!validate_decl_struct_darg(data, darg, u)) {
+                       return 0;
+               } else if (darg->layout) {
                        pos = darg->layout->pos;
 
                        align = align_decl_arg(darg, &pos, &len);
 
                        if (darg->layout->pos != 0) {
                                data->error(data, darg->token, PSI_WARNING,
-                                               "Offset of %s.%s must be 0",
+                                               "Offset of %s.%s should be 0",
                                                u->name, darg->var->name);
-                               return 0;
+                               darg->layout->pos = 0;
                        }
                        if (darg->layout->len != len) {
                                data->error(data, darg->token, PSI_WARNING,
                                                "Computed size %zu of %s.%s does not match"
                                                " pre-defined size %zu of type '%s'",
-                                               darg->layout->len, u->name, darg->var->name, size,
+                                               len, u->name, darg->var->name, darg->layout->len,
                                                darg->type->name);
-                               return 0;
                        }
-               } else if (!validate_decl_struct_darg(data, darg)) {
-                       return 0;
                } else {
                        pos = 0;