flush
authorMichael Wallner <mike@php.net>
Mon, 18 Jan 2016 11:14:33 +0000 (12:14 +0100)
committerMichael Wallner <mike@php.net>
Mon, 18 Jan 2016 12:32:34 +0000 (13:32 +0100)
16 files changed:
TODO
config.m4
m4/psi.m4
m4/psi_const.m4
m4/psi_decl.m4
m4/psi_macro.m4
m4/psi_struct.m4
m4/psi_type.m4
m4/stdint.m4
m4/wchar.m4
m4/wctype.m4
src/context.c
src/parser.h
src/parser.re
src/parser_proc.h
src/parser_proc.y

diff --git a/TODO b/TODO
index d658c42..ee63abe 100644 (file)
--- a/TODO
+++ b/TODO
@@ -4,3 +4,5 @@
 * check out jit-dynamic
 * fix arginfo with nullable types
 * pemalloc
+* unions
+* callbacks and function pointers
index 817887d..9cd22a3 100644 (file)
--- a/config.m4
+++ b/config.m4
@@ -1,6 +1,12 @@
 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)
 
index 4729740..ae6c81a 100644 (file)
--- a/m4/psi.m4
+++ b/m4/psi.m4
@@ -1,3 +1,4 @@
+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
@@ -7,6 +8,10 @@ PSI_MACROS=$PHP_PSI_SRCDIR/php_psi_macros.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 {
@@ -56,6 +61,8 @@ static struct psi_predef_decl psi_predef_vararg_decls@<:@@:>@ = {
 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
@@ -68,16 +75,9 @@ EOF
        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()
 #ifdef HAVE_ERRNO_H
 # include <errno.h>
@@ -141,12 +141,18 @@ AC_DEFUN(PSI_INCLUDES, [AC_INCLUDES_DEFAULT()
 #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
@@ -155,13 +161,25 @@ AC_DEFUN([PSI_PKG_CONFIG], [
        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],
@@ -177,9 +195,23 @@ AC_DEFUN(PSI_CHECK_OFFSETOF, [
        )
 ])
 
+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
@@ -200,8 +232,15 @@ AC_DEFUN(PSI_CHECK_LIBJIT, [
        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
 
@@ -212,6 +251,7 @@ AC_DEFUN(PSI_CHECK_LIBFFI, [
        else
                psi_cv_libffi=false
        fi])
+       
        if $psi_cv_libffi
        then
                AC_MSG_CHECKING(for libffi)
@@ -257,15 +297,3 @@ AC_DEFUN(PSI_CHECK_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`\\\"
-       ])
-])
index 79373d3..71adb03 100644 (file)
@@ -1,12 +1,18 @@
-# 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=
@@ -29,10 +35,10 @@ AC_DEFUN(PSI_CONST, [
        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
index c331bbe..92da292 100644 (file)
@@ -1,6 +1,30 @@
-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])
@@ -14,6 +38,7 @@ AC_DEFUN(PSI_FUNC_LIBC_MAIN, [
 ])
 
 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
@@ -40,6 +65,8 @@ AC_DEFUN(PSI_FUNC, [
        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))
@@ -52,6 +79,9 @@ AC_DEFUN(PSI_DECL_ARG, [
 ])
 
 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)
@@ -60,15 +90,14 @@ AC_DEFUN(PSI_DECL, [
                [()], [],
                [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"
+                       ])
                ])
        ])
 ])
index 0bae220..337a7e5 100644 (file)
@@ -1,3 +1,9 @@
+# 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, [
@@ -27,8 +33,7 @@ AC_DEFUN(PSI_MACRO, [
                ], [
                        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)
 ])
index ce04f3d..fcee59c 100644 (file)
@@ -1,24 +1,36 @@
+# 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
 ])
index 85750d9..dad3b67 100644 (file)
@@ -1,4 +1,12 @@
+# 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`
@@ -7,7 +15,6 @@ psi_type_pair() {
                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\""
@@ -22,30 +29,39 @@ psi_type_pair() {
 }
 
 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=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 test "$AS_TR_SH([ac_cv_sizeof_]$1)" -gt 0; then
+       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@:>@;], [
@@ -65,13 +81,16 @@ AC_DEFUN(PSI_OPAQUE_TYPE, [
                ])
                case "$AS_TR_SH([psi_cv_type_class_]$1)" in
                scalar)
-                       PSI_TYPE($1, int)
+                       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*)
-                       cat >>$PSI_TYPES <<<"   {PSI_T_POINTER, \"void\", \"$1\"}, "
+                       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)
@@ -80,23 +99,17 @@ AC_DEFUN(PSI_OPAQUE_TYPE, [
        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])])
 
@@ -120,15 +133,18 @@ AC_DEFUN(PSI_TYPE_INDIRECTION, [
                $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)
 
@@ -186,9 +202,10 @@ AC_DEFUN(PSI_CHECK_STD_TYPES, [
        PSI_TYPE(unsigned long, uint)
        PSI_TYPE(unsigned long int, uint)
        PSI_TYPE(long long, int)
-       PSI_TYPE(long long int, 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)
 ])
index 045279d..c21c129 100644 (file)
@@ -1,25 +1,25 @@
 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)
index 6c5430b..2d0a1ae 100644 (file)
@@ -2,7 +2,6 @@ PSI_CHECK_WCHAR() {
        AC_CHECK_HEADERS(wchar.h)
 
        PSI_TYPE(wint_t, int)
-       PSI_TYPE(wctype_t, int)
        PSI_STRUCT(mbstate_t)
 
        PSI_CONST(WINT_MIN, int)
index 319c2fc..627b919 100644 (file)
@@ -1,6 +1,7 @@
 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)])
index d2293fe..3f94d42 100644 (file)
@@ -40,6 +40,9 @@ static struct psi_std_type {
 } 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"},
@@ -124,6 +127,10 @@ static inline int locate_decl_type_struct(decl_structs *structs, decl_type *type
 
 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;
@@ -1272,7 +1279,8 @@ void PSI_ContextDump(PSI_Context *C, int fd)
 
                        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");
        }
index 8c25e88..b27fdaf 100644 (file)
@@ -13,6 +13,8 @@
 #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 */
@@ -82,7 +84,7 @@ static inline decl_type *init_decl_type_ex(token_t type, int argc, ...) {
                                pos = all;
                                ptr = realloc(ptr, 1 + (all += len));
                        } else {
-                               ptr = malloc(ptr, 1 + (all = len));
+                               ptr = malloc(1 + (all = len));
                        }
                        memcpy(ptr + pos, arg, len);
                }
@@ -1303,7 +1305,7 @@ static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
        token_len = P->cur - P->tok;
        fname_len = strlen(P->psi.file.fn);
 
-       T = calloc(1, PSI_TokenAllocSize(token_len, fname_len);
+       T = calloc(1, PSI_TokenAllocSize(token_len, fname_len));
        T->type = token_typ;
        T->size = token_len;
        T->text = &T->buf[0];
@@ -1343,7 +1345,7 @@ static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) {
 
                        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)
+                       memcpy(T->file - 1, arg->text, arg->size + 1);
                        T->file = &T->buf[T->size + 1];
                } else {
                        T = PSI_TokenCopy(arg);
index 3375a0b..70ab698 100644 (file)
@@ -263,7 +263,10 @@ token_t PSI_ParserScan(PSI_Parser *P)
                '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);}
@@ -275,6 +278,7 @@ token_t PSI_ParserScan(PSI_Parser *P)
                '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);}
index 30ad543..7fe90fd 100644 (file)
@@ -9,60 +9,64 @@
 #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
index d82a90f..b4150ae 100644 (file)
@@ -28,7 +28,7 @@ void psi_error(int, const char *, int, const char *, ...);
 %nonassoc NAME.
 %left PLUS MINUS.
 %left SLASH ASTERISK.
-%fallback NAME TEMP FREE SET LET RETURN LIB INT LONG SIGNED UNSIGNED.
+%fallback NAME TEMP FREE SET LET RETURN LIB CHAR SHORT INT LONG SIGNED UNSIGNED.
 
 file ::= blocks.
 
@@ -104,8 +104,8 @@ decl_typedef(def) ::= TYPEDEF decl_type(type) NAME(ALIAS) EOS. {
        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;
 }
@@ -237,38 +237,47 @@ struct_layout(layout) ::= COLON COLON LPAREN NUMBER(POS) COMMA NUMBER(SIZ) RPARE
        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). {
-       type_ = init_decl_type(T->type, T->text);
-       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);
 }
-/* unsigned, urgh */
-decl_type(type_) ::= UNSIGNED(U) NAME(N). {
+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);
 }
-decl_type(type_) ::= SIGNED 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("signed"));
-       memmove(type_->name + sizeof("signed"), type_->name, T->size);
-       memcpy(type_->name, "signed", sizeof("signed")-1);
-       type_->name[sizeof("signed")] = ' ';
-       type_->name[T->size + sizeof("signed")] = 0;
-}
-/* we have to support plain int, long 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;
-}
-decl_type(type_) ::= LONG 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). {
@@ -276,6 +285,21 @@ 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($$);}