* check out jit-dynamic
* fix arginfo with nullable types
* pemalloc
+* unions
+* callbacks and function pointers
PHP_ARG_ENABLE(psi, whether to enable PHP System Interface support,
[ --enable-psi Enable PHP System Interface support])
+PHP_ARG_WITH(psi-libjit, where to find libjit,
+[ --with-psi-libjit=DIR PSI: path to libjit], [ ], [ ])
+
+PHP_ARG_WITH(psi-libffi, where to find libffi,
+[ --with-psi-libffi=DIR PSI: path to libffi], [ ], [ ])
+
PHP_PSI_SRCDIR=PHP_EXT_SRCDIR(psi)
PHP_PSI_BUILDDIR=PHP_EXT_BUILDDIR(psi)
+dnl Generated headers with pre-defined types, structs, consts and decls.
PSI_STDINC=$PHP_PSI_SRCDIR/php_psi_stdinc.h
PSI_TYPES=$PHP_PSI_SRCDIR/php_psi_types.h
PSI_STRUCTS=$PHP_PSI_SRCDIR/php_psi_structs.h
PSI_DECLS=$PHP_PSI_SRCDIR/php_psi_decls.h
PSI_VA_DECLS=$PHP_PSI_SRCDIR/php_psi_va_decls.h
+dnl PSI_CONFIG_INIT()
+dnl Creates stubs of the headers with pre-defined types etc.
+dnl These headers are included by src/context.c.
+dnl This macro must be called prior any checks for a type, struct, decl etc.
AC_DEFUN(PSI_CONFIG_INIT, [
cat >$PSI_TYPES <<EOF
static struct psi_predef_type {
EOF
])
+dnl PSI_CONFIG_DONE()
+dnl Finish the headers with the pre-defined types etc.
AC_DEFUN(PSI_CONFIG_DONE, [
cat >$PSI_STDINC <<EOF
PSI_INCLUDES
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>
#endif
])
+dnl PSI_LEMON()
+dnl Declare $LEMON precious, and check for a `lemon` in $PATH.
AC_DEFUN(PSI_LEMON, [
AC_ARG_VAR(LEMON, The lemon parser generator of the SQLite project)
AC_PATH_PROG(LEMON, lemon, ./lemon)
PHP_SUBST(LEMON)
])
+dnl PSI_PKG_CONFIG()
+dnl Check for `pkg-config` and add possible libjit and libffi directories to
+dnl $PKG_CONFIG_PATH, because those libs often ship with headers etc. in
+dnl arch-dependent locations.
AC_DEFUN([PSI_PKG_CONFIG], [
if test -z "$PKG_CONFIG"
then
export PKG_CONFIG_PATH="$PHP_PSI_LIBFFI/lib/pkgconfig:$PHP_PSI_LIBJIT/lib/pkgconfig:$PKG_CONFIG_PATH"
])
+dnl PSI_SH_TEST_SIZEOF(type)
+dnl `if` condition to test if $ac_cv_sizeof_$1 is greater than 0.
+AC_DEFUN([PSI_SH_TEST_SIZEOF], [test -n "$AS_TR_SH([ac_cv_sizeof_]$1)" && test "$AS_TR_SH([ac_cv_sizeof_]$1)" -gt 0])
+
+dnl PSI_CHECK_SIZEOF(type, special-includes)
+dnl AC_CHECK_SIZEOF wrapper with PSI_INCLUDES
+dnl Defines psi\\SIZEOF_<TYPE> pre-defined constant in $PSI_CONSTS.
AC_DEFUN(PSI_CHECK_SIZEOF, [
- AC_CHECK_SIZEOF($1, [], $2)
- if test "$AS_TR_SH([ac_cv_sizeof_]$1)"; then
- add_int_const "AS_TR_CPP([SIZEOF_]$1)" "$AS_TR_SH([ac_cv_sizeof_]$1)"
+ AC_CHECK_SIZEOF($1, [], PSI_INCLUDES
+ $2)
+ if PSI_SH_TEST_SIZEOF($1); then
+ psi_add_int_const "AS_TR_CPP([SIZEOF_]$1)" "$AS_TR_SH([ac_cv_sizeof_]$1)"
fi
])
+dnl PSI_CHECK_OFFSETOF(struct, element)
+dnl Check the offset of a struct element, implemented in the similar manner
+dnl like AC_CHECK_SIZEOF.
+dnl AC_DEFINEs OFFSETOF_<STRUCT>_<ELEMENT>.
AC_DEFUN(PSI_CHECK_OFFSETOF, [
_AC_CACHE_CHECK_INT(
[offset of $2 in $1],
)
])
+dnl PSI_COMPUTE_STR(variable, string or expression)
+dnl Compute a string constant value in a similar manner like AC_COMPUTE_INT.
+AC_DEFUN(PSI_COMPUTE_STR, [
+ AC_TRY_RUN(
+ PSI_INCLUDES
+ [int main() {
+ return EOF == fputs($2, fopen("conftest.out", "w"));
+ }
+ ], [
+ eval $1=\\\"`cat conftest.out`\\\"
+ ])
+])
+
+dnl PSI_CHECK_LIBJIT()
+dnl Check for libjit in $PHP_PSI_LIBJIT or standard locations
+dnl AC_DEFINEs HAVE_LIBJIT.
AC_DEFUN(PSI_CHECK_LIBJIT, [
- PHP_ARG_WITH(psi-libjit, where to find libjit,
- [ --with-psi-libjit=DIR PSI: path to libjit], [ ], [ ])
AC_CACHE_CHECK(for libjit, psi_cv_libjit_dir, [
for psi_cv_libjit_dir in $PHP_PSI_LIBJIT {/usr{,/local},/opt}{,/libjit}
do
fi
])
-PHP_ARG_WITH(psi-libffi, where to find libffi,
-[ --with-psi-libffi=DIR PSI: path to libffi], [ ], [ ])
+dnl PSI_CHECK_LIBFFI()
+dnl Check for libffi with `pkg-config`. If that fails, `configure` looks into
+dnl $PHP_PSI_LIBFFI or standard locations to find libjit deps.
+dnl Checks for availability of recent closure API:
+dnl \ffi_closure_alloc and \ffi_prep_closure.
+dnl Checks for availability of recent vararg API:
+dnl \ffi_prep_cif_var.
+dnl AC_DEFINEs HAVE_LIBFFI, PSI_HAVE_FFI_CLOSURE_ALLOC,
+dnl PSI_HAVE_FFI_PREP_CLOSURE and PSI_HAVE_FFO_PREP_VIF_VAR.
AC_DEFUN(PSI_CHECK_LIBFFI, [
AC_REQUIRE([PSI_PKG_CONFIG])dnl
else
psi_cv_libffi=false
fi])
+
if $psi_cv_libffi
then
AC_MSG_CHECKING(for libffi)
], [
], -L$psi_cv_libffi_dir/$PHP_LIBDIR)
])
-
-dnl PSI_COMPUTE_STR(variable, string or expression)
-AC_DEFUN(PSI_COMPUTE_STR, [
- AC_TRY_RUN(
- PSI_INCLUDES
- [int main() {
- return EOF == fputs($2, fopen("conftest.out", "w"));
- }
- ], [
- eval $1=\\\"`cat conftest.out`\\\"
- ])
-])
-# add_str_const(name, value)
-add_str_const() {
+# psi_add_str_const(name, value)
+# Add a pre-defined string constant to $PSI_CONSTS
+psi_add_str_const() {
cat >>$PSI_CONSTS <<<" {PSI_T_STRING, \"string\", \"psi\\\\$1\", $2, PSI_T_QUOTED_STRING}, "
}
-# add_int_const(name, value)
-add_int_const() {
+
+# psi_add_int_const(name, value)
+# Add a pre-defined int constant to $PSI_CONSTS
+psi_add_int_const() {
cat >>$PSI_CONSTS <<<" {PSI_T_INT, \"int\", \"psi\\\\$1\", \"$2\", PSI_T_NUMBER}, "
}
+
dnl PSI_CONST(const name, type)
+dnl Check the value of a str/int constant and add it to the list of pre-defined
+dnl constants.
AC_DEFUN(PSI_CONST, [
AC_CACHE_CHECK(value of $1, psi_cv_const_$1, [
psi_const_val=
then
case $2 in
str*)
- add_str_const "$1" "$psi_cv_const_$1"
+ psi_add_str_const "$1" "$psi_cv_const_$1"
;;
int)
- add_int_const "$1" "$psi_cv_const_$1"
+ psi_add_int_const "$1" "$psi_cv_const_$1"
;;
esac
fi
-AC_DEFUN(PSI_REDIR, [psi_symbol=ifelse([$2],[],[$1],[$2])
- cat >>$PSI_REDIRS <<<" {\"$1\", (void(*)(void))$psi_symbol}, "])
+# psi_add_redir(name, symbol)
+# Add a function redirection to $PSI_REDIRS.
+psi_add_redir() {
+ cat >>$PSI_REDIRS <<<" {\"$1\", (void(*)(void))$2}, "
+}
+# psi_add_decl(decl, options)
+# Add a pre-defined decl to $PSI_VA_DECLS/$PSI_DECLS.
+psi_add_decl() {
+ case "$2" in
+ *vararg*)
+ cat >>$PSI_VA_DECLS <<<" $1, {0}, "
+ ;;
+ *)
+ cat >>$PSI_DECLS <<<" $1, {0}, "
+ ;;
+ esac
+}
+
+dnl PSI_REDIR(name, custom symbol)
+dnl Create a function redirection to an optional custom symbol.
+AC_DEFUN(PSI_REDIR, [
+ psi_add_redir $1 ifelse([$2],[],[$1],[$2])
+])
+
+dnl PSI_FUNC_LIBC_MAIN()
+dnl Check for the platforms default stub in executables.
AC_DEFUN(PSI_FUNC_LIBC_MAIN, [
AC_REQUIRE([AC_PROG_NM])
AC_REQUIRE([AC_PROG_AWK])
])
dnl PSI_FUNC(fn, action-if-yes, action-if-no)
+dnl Check for a possible function redirection.
AC_DEFUN(PSI_FUNC, [
AC_REQUIRE([PSI_FUNC_LIBC_MAIN])
psi_symbol=$1
esac
])
+dnl PSI_DECL_ARG(decl arg)
+dnl INTERNAL: build psi_decl_args
AC_DEFUN(PSI_DECL_ARG, [
m4_define([member_name], PSI_VAR_NAME($1))
m4_define([member_type], PSI_VAR_TYPE($1))
])
dnl PSI_DECL(type func, args, flags)
+dnl Check for a function or macro declaration.
+dnl Adds a pre-defined (vararg) decl to $PSI_VA_DECLS/$PSI_DECLS.
+dnl Calls PSI_MACRO if PSI_FUNC fails.
AC_DEFUN(PSI_DECL, [
psi_decl_args=
PSI_DECL_ARG($1)
[()], [],
[m4_map_args_sep([PSI_DECL_ARG(m4_normalize(], [))], [], m4_bregexp([$2], [(\(.*\))], [\1]))])
PSI_FUNC(PSI_VAR_NAME($1), [
- ifelse([$3], vararg, [
- cat >>$PSI_VA_DECLS <<<" $psi_decl_args, {0}, "
- ], [
- cat >>$PSI_DECLS <<<" $psi_decl_args, {0}, "
- ])
+ psi_add_decl "$psi_decl_args" $3
], [
PSI_MACRO($1, $2, [
- ifelse([$3], vararg, AC_MSG_ERROR(varargs macro support is not implemented),[])
- cat >>$PSI_DECLS <<<" $psi_decl_args, {0}, "
+ ifelse([$3], vararg, [
+ AC_MSG_ERROR(varargs macro support is not implemented)
+ ],[
+ psi_add_decl "$psi_decl_args"
+ ])
])
])
])
+# psi_add_macro(macro)
+# Add a pre-defined macro function to $PSI_MACROS.
+psi_add_macro() {
+ cat >>$PSI_MACROS <<<"$1"
+}
+
dnl PSI_MACRO(macro, decl args, action-if-true)
AC_DEFUN(PSI_MACRO, [
AC_CHECK_DECL(PSI_VAR_NAME($1)$2, [
], [
macro_body="return $macro_name$macro_call;"
])
- psi_macro="$macro_type psi_macro_$macro_name$macro_decl { $macro_body }"
- cat >>$PSI_MACROS <<<"$psi_macro"
+ psi_add_macro "$macro_type psi_macro_$macro_name$macro_decl { $macro_body }"
PSI_REDIR($macro_name, psi_macro_$macro_name)
], [], PSI_INCLUDES)
])
+# psi_add_struct(struct members)
+# Add a pre-defined struct to $PSI_STRUCTS.
+psi_add_struct() {
+ cat >>$PSI_STRUCTS <<<" $1, {0}, "
+}
+
+dnl PSI_STRUCT_MEMBER(struct name, decl member)
+dnl INTERNAL: build $psi_struct_members
AC_DEFUN(PSI_STRUCT_MEMBER, [
m4_define([member_name], PSI_VAR_NAME($2))
m4_define([member_type], PSI_VAR_TYPE($2))
- PSI_CHECK_SIZEOF(AS_TR_SH($1)[_]member_name, PSI_INCLUDES
+ PSI_CHECK_SIZEOF(AS_TR_SH($1)[_]member_name,
[#define ]AS_TR_SH($1)[_]member_name (($1 *)0)->member_name
)
- if test -n "$AS_TR_SH([ac_cv_sizeof_$1][_]member_name)" \
- && test "$AS_TR_SH([ac_cv_sizeof_$1][_]member_name)" -gt 0; then
+ if PSI_SH_TEST_SIZEOF($1 member_name); then
PSI_CHECK_OFFSETOF($1, member_name)
PSI_TYPE_INDIRECTION($2, [$AS_TR_SH([ac_cv_sizeof_]$1[_]member_name)], pl, as)
psi_struct_members="[$psi_struct_members, {]PSI_TYPE_PAIR(member_type)[, \"]member_name[\", $]AS_TR_SH([ac_cv_offsetof_]$1[_]member_name)[, $]AS_TR_SH([ac_cv_sizeof_]$1[_]member_name), $pl, $as[}]"
fi
])
+dnl PSI_STRUCT(struct name, struct members)
+dnl Check a struct and its members and add a pre-defined struct and possibly a
+dnl pre-defined type for this struct.
+dnl Calls PSI_CHECK_SIZEOF for the struct and each member.
+dnl Calls PSI_CHECK_OFFSETOF and PSI_TYPE_INDIRECTON for each member.
AC_DEFUN(PSI_STRUCT, [
- PSI_CHECK_SIZEOF($1, PSI_INCLUDES)
+ PSI_CHECK_SIZEOF($1)
psi_struct_name=m4_bregexp([$1], [^\(struct \)?\(\w+\)], [\2])
psi_struct_members="{PSI_T_STRUCT, \"struct\", \"$psi_struct_name\", 0, $AS_TR_SH([ac_cv_sizeof_]$1), 0, 0}"
ifelse([$2],,,[m4_map_args_sep([PSI_STRUCT_MEMBER($1, m4_normalize(], [))], [], $2)])
- cat >>$PSI_STRUCTS <<<" $psi_struct_members, {0}, "
+ psi_add_struct "$psi_struct_members"
if test "$1" = "$psi_struct_name"; then
- cat >>$PSI_TYPES <<<" {PSI_T_STRUCT, \"$1\", \"$1\"}, "
+ psi_add_type "{PSI_T_STRUCT, \"$1\", \"$1\"}"
fi
])
+# psi_add_type(type triplet)
+# Add a pre-defined type to $PSI_TYPES.
+psi_add_type() {
+ cat >>$PSI_TYPES <<<" $1, "
+}
+
# psi_type_pair(type, size)
+# Output a PSI_T_<TYPE>, \"<TYPENAME>\" tuple.
+# Uses stdint types when possible.
psi_type_pair() {
local psi_type_name=`tr -cd A-Za-z0-9_ <<<$1`
local psi_type_lower=`tr A-Z a-z <<<$psi_type_name`
local psi_type_upper=`tr a-z A-Z <<<$psi_type_name`
local psi_type_bits=`expr $2 \* 8`
echo "PSI_T_${psi_type_upper}${psi_type_bits}, \"${psi_type_lower}${psi_type_bits}_t\""
- #eval AS_TR_SH([psi_standard_type_]$1)="${psi_type_lower}${psi_type_bits}_t"
;;
struct*)
echo "PSI_T_STRUCT, \"$2\""
}
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@:>@;], [
])
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)
fi
])
-dnl unsigned char* buf[16] -> unsigned char*
-dnl AC_DEFUN(PSI_VAR_TYPE, [m4_bregexp([$1], [\(\(struct \)?[^ ]+\)[ *]+[^ ]+$], [\1])])
+dnl PSI_VAR_TYPE(decl arg)
+dnl Extracts the type of a decl arg, e.g. dnl unsigned char* buf[16] -> unsigned char*.
AC_DEFUN(PSI_VAR_TYPE, [m4_bregexp([$1], [^\(const \)?\(.*\) \([*]*\)[^ ]+$], [\2\3])])
-dnl unsigned char* buf[16] -> buf
+
+dnl PSI_VAR_NAME(decl arg)
+dnl Extracts the var name of a decl arg, e.g. unsigned char* buf[16] -> buf.
AC_DEFUN(PSI_VAR_NAME, [m4_bregexp(m4_bregexp([$1], [\([^ ]+\)$], [\1]), [\w+], [\&])])
-dnl PSI_TYPE_SIZE(type, pointer level, array size)
-AC_DEFUN(PSI_TYPE_SIZE, [ifelse(
- [$3], 0,
- [ifelse([$2], 0, $AS_TR_SH([ac_cv_sizeof_]$1), $ac_cv_sizeof_void_p)],
- [ifelse([$2], 1, [`expr $3 \* $AS_TR_SH([ac_cv_sizeof_]$1)`], $ac_cv_sizeof_void_p)]
-)])
-dnl PSI_TYPE_BITS(type)
-AC_DEFUN(PSI_TYPE_BITS, [`expr 8 \* $AS_TR_SH([ac_cv_sizeof_]$1)`])
-dnl PSI_TYPE_INDIRECTION(type, size, pointer_level_var, array_size_var)
+dnl PSI_TYPE_INDIRECTION(decl arg, size, pointer_level_var, array_size_var)
+dnl Calculates and assigns pointer_level and array_size of a decl arg to sh vars.
AC_DEFUN(PSI_TYPE_INDIRECTION, [
- dnl AC_MSG_CHECKING(indirection of $1)
m4_define([psi_pointer_level], m4_len(m4_bpatsubst([PSI_VAR_TYPE($1)], [[^*]])))
m4_define([psi_array_size], [m4_bregexp([PSI_VAR_TYPE($1)], [@<:@\([0-9]+\)@:>@], [\1])])
$3=m4_incr(psi_pointer_level)
$4=psi_array_size
])
-
- dnl AC_MSG_RESULT([[$]$3, [$]$4])
])
+dnl PSI_TYPE_PAIR(type)
+dnl Expand to a PSI_T_<TYPE>, \\"<TYPENAME>\\" tuple.
+dnl FIXME: There is also psi_type_pair()?
AC_DEFUN(PSI_TYPE_PAIR, [m4_case(m4_bregexp([$1], [^\w+], [\&]),
[void], [PSI_T_VOID, \"void\"],
[struct], [PSI_T_STRUCT, \"m4_bregexp([$1], [^struct \(\w+\)], [\1])\"],
[PSI_T_NAME, \"m4_bregexp([$1], [^\(\w+ \)*\w+], [\&])\"])])
+dnl PSI_CHECK_STD_TYPES()
+dnl Checks for standard ANSI-C and stdint types.
AC_DEFUN(PSI_CHECK_STD_TYPES, [
AC_CHECK_HEADERS(stdint.h)
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)
])
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)
AC_CHECK_HEADERS(wchar.h)
PSI_TYPE(wint_t, int)
- PSI_TYPE(wctype_t, int)
PSI_STRUCT(mbstate_t)
PSI_CONST(WINT_MIN, int)
PSI_CHECK_WCTYPE() {
AC_CHECK_HEADERS(wctype.h)
+ PSI_TYPE(wctype_t, int)
PSI_TYPE(wctrans_t, int)
PSI_DECL(int iswalnum, [(wint_t wc)])
} psi_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"},
static inline int validate_decl_type(PSI_Data *data, decl_type *type) {
switch (type->type) {
+ case PSI_T_CHAR:
+ case PSI_T_SHORT:
+ case PSI_T_INT:
+ case PSI_T_LONG:
case PSI_T_NAME:
if (!data->defs || !locate_decl_type_alias(data->defs, type)) {
return 0;
dprintf(fd, "typedef ");
dump_decl_type(fd, tdef->type);
- dprintf(fd, " %s;\n", tdef->alias);
+ dprintf(fd, " %s%s;\n", tdef->type->type == PSI_T_POINTER ? "*":"",
+ tdef->alias);
}
dprintf(fd, "\n");
}
#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 */
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);
}
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];
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);
'MIXED' {RETURN(PSI_T_MIXED);}
'VOID' {RETURN(PSI_T_VOID);}
'BOOL' {RETURN(PSI_T_BOOL);}
+ 'CHAR' {RETURN(PSI_T_CHAR);}
+ 'SHORT' {RETURN(PSI_T_SHORT);}
'INT' {RETURN(PSI_T_INT);}
+ 'LONG' {RETURN(PSI_T_LONG);}
'FLOAT' {RETURN(PSI_T_FLOAT);}
'DOUBLE' {RETURN(PSI_T_DOUBLE);}
'INT8_T' {RETURN(PSI_T_INT8);}
'INT64_T' {RETURN(PSI_T_INT64);}
'UINT64_T' {RETURN(PSI_T_UINT64);}
'UNSIGNED' {RETURN(PSI_T_UNSIGNED);}
+ 'SIGNED' {RETURN(PSI_T_SIGNED);}
'STRING' {RETURN(PSI_T_STRING);}
'ARRAY' {RETURN(PSI_T_ARRAY);}
'OBJECT' {RETURN(PSI_T_OBJECT);}
#define PSI_T_LET 9
#define PSI_T_RETURN 10
#define PSI_T_LIB 11
-#define PSI_T_INT 12
-#define PSI_T_UNSIGNED 13
-#define PSI_T_EOF 14
-#define PSI_T_QUOTED_STRING 15
-#define PSI_T_EOS 16
-#define PSI_T_STRUCT 17
-#define PSI_T_LBRACE 18
-#define PSI_T_RBRACE 19
-#define PSI_T_COLON 20
-#define PSI_T_LPAREN 21
-#define PSI_T_NUMBER 22
-#define PSI_T_RPAREN 23
-#define PSI_T_BOOL 24
-#define PSI_T_FLOAT 25
-#define PSI_T_STRING 26
-#define PSI_T_CONST 27
-#define PSI_T_NSNAME 28
-#define PSI_T_EQUALS 29
-#define PSI_T_TYPEDEF 30
-#define PSI_T_VOID 31
-#define PSI_T_LBRACKET 32
-#define PSI_T_RBRACKET 33
-#define PSI_T_COMMA 34
-#define PSI_T_ELLIPSIS 35
-#define PSI_T_DOUBLE 36
-#define PSI_T_INT8 37
-#define PSI_T_UINT8 38
-#define PSI_T_INT16 39
-#define PSI_T_UINT16 40
-#define PSI_T_INT32 41
-#define PSI_T_UINT32 42
-#define PSI_T_INT64 43
-#define PSI_T_UINT64 44
-#define PSI_T_FUNCTION 45
-#define PSI_T_NULL 46
-#define PSI_T_TRUE 47
-#define PSI_T_FALSE 48
-#define PSI_T_DOLLAR 49
-#define PSI_T_CALLOC 50
-#define PSI_T_OBJVAL 51
-#define PSI_T_ARRVAL 52
-#define PSI_T_PATHVAL 53
-#define PSI_T_STRLEN 54
-#define PSI_T_STRVAL 55
-#define PSI_T_FLOATVAL 56
-#define PSI_T_INTVAL 57
-#define PSI_T_BOOLVAL 58
-#define PSI_T_TO_OBJECT 59
-#define PSI_T_TO_ARRAY 60
-#define PSI_T_TO_STRING 61
-#define PSI_T_TO_INT 62
-#define PSI_T_TO_FLOAT 63
-#define PSI_T_TO_BOOL 64
-#define PSI_T_MIXED 65
-#define PSI_T_ARRAY 66
-#define PSI_T_OBJECT 67
-#define PSI_T_AMPERSAND 68
+#define PSI_T_CHAR 12
+#define PSI_T_SHORT 13
+#define PSI_T_INT 14
+#define PSI_T_LONG 15
+#define PSI_T_SIGNED 16
+#define PSI_T_UNSIGNED 17
+#define PSI_T_EOF 18
+#define PSI_T_QUOTED_STRING 19
+#define PSI_T_EOS 20
+#define PSI_T_STRUCT 21
+#define PSI_T_LBRACE 22
+#define PSI_T_RBRACE 23
+#define PSI_T_COLON 24
+#define PSI_T_LPAREN 25
+#define PSI_T_NUMBER 26
+#define PSI_T_RPAREN 27
+#define PSI_T_BOOL 28
+#define PSI_T_FLOAT 29
+#define PSI_T_STRING 30
+#define PSI_T_CONST 31
+#define PSI_T_NSNAME 32
+#define PSI_T_EQUALS 33
+#define PSI_T_TYPEDEF 34
+#define PSI_T_VOID 35
+#define PSI_T_LBRACKET 36
+#define PSI_T_RBRACKET 37
+#define PSI_T_COMMA 38
+#define PSI_T_ELLIPSIS 39
+#define PSI_T_DOUBLE 40
+#define PSI_T_INT8 41
+#define PSI_T_UINT8 42
+#define PSI_T_INT16 43
+#define PSI_T_UINT16 44
+#define PSI_T_INT32 45
+#define PSI_T_UINT32 46
+#define PSI_T_INT64 47
+#define PSI_T_UINT64 48
+#define PSI_T_FUNCTION 49
+#define PSI_T_NULL 50
+#define PSI_T_TRUE 51
+#define PSI_T_FALSE 52
+#define PSI_T_DOLLAR 53
+#define PSI_T_CALLOC 54
+#define PSI_T_OBJVAL 55
+#define PSI_T_ARRVAL 56
+#define PSI_T_PATHVAL 57
+#define PSI_T_STRLEN 58
+#define PSI_T_STRVAL 59
+#define PSI_T_FLOATVAL 60
+#define PSI_T_INTVAL 61
+#define PSI_T_BOOLVAL 62
+#define PSI_T_TO_OBJECT 63
+#define PSI_T_TO_ARRAY 64
+#define PSI_T_TO_STRING 65
+#define PSI_T_TO_INT 66
+#define PSI_T_TO_FLOAT 67
+#define PSI_T_TO_BOOL 68
+#define PSI_T_MIXED 69
+#define PSI_T_ARRAY 70
+#define PSI_T_OBJECT 71
+#define PSI_T_AMPERSAND 72
%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.
def->token = ALIAS;
}
/* support opaque types */
-decl_typedef(def) ::= TYPEDEF VOID(V) NAME(ALIAS) EOS. {
- def = init_decl_typedef(ALIAS->text, init_decl_type(V->type, V->text));
+decl_typedef(def) ::= TYPEDEF VOID(V) indirection(i) NAME(ALIAS) EOS. {
+ def = init_decl_typedef(ALIAS->text, init_decl_type(i?PSI_T_POINTER:V->type, V->text));
def->token = ALIAS;
def->type->token = V;
}
free(SIZ);
}
-%token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME.
-%type decl_type {decl_type*}
-%destructor decl_type {free_decl_type($$);}
-decl_type(type_) ::= decl_type_token(T). {
- 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). {
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($$);}