PHP_SUBST(PSI_SHARED_LIBADD)
+ dnl PSI_INCLUDES_DEFAULT(include, defines)
+ AC_DEFUN(PSI_INCLUDES_DEFAULT, [
+ AC_INCLUDES_DEFAULT()
+ $2
+ m4_ifnblank($1,
+ m4_expand([#include <]$1[>])
+ )
+ ])
+
+ psi_type_pair() { # (type, size)
+ local psi_type_lower=`tr A-Z a-z <<<$1`
+ case $psi_type_lower in
+ int*|uint*)
+ local psi_type_upper=`tr a-z A-Z <<<$1`
+ local psi_type_bits=`expr $2 \* 8`
+ echo "PSI_T_${psi_type_upper}${psi_type_bits}, \"${psi_type_lower}${psi_type_bits}_t\""
+ ;;
+ struct*)
+ echo "PSI_T_STRUCT, \"$2\""
+ ;;
+ *)
+ echo "PSI_T_NAME, \"$1\""
+ ;;
+ esac
+ }
+
PSI_TYPES=""
- dnl PSI_TYPE(type name, basic type, whether to check alignmnet)
+ dnl PSI_TYPE(type name, basic type, includes)
AC_DEFUN(PSI_TYPE, [
- AC_CHECK_SIZEOF($1)
- if test "$3" && test "$3" != "no"
- then
- AC_CHECK_ALIGNOF($1)
- fi
+ ifdef(AC_TYPE_[]patsubst(translit($1,a-z,A-Z),\W,_),AC_TYPE_[]patsubst(translit($1,a-z,A-Z),\W,_))
+ AC_CHECK_SIZEOF($1, [], PSI_INCLUDES_DEFAULT($3))
if test "$2" && test "$ac_cv_sizeof_[]$1" -gt 0; then
- psi_type_bits=`expr ${AS_TR_SH(ac_cv_sizeof_[]$1)} \* 8`
- PSI_TYPES="{PSI_T_[]translit($2,a-z,A-Z)[]${psi_type_bits}, \""$2[]${psi_type_bits}[]_t"\", \""$1"\"}, $PSI_TYPES"
+ PSI_TYPES="{`psi_type_pair $2 $ac_cv_sizeof_[]$1`, \""$1"\"}, $PSI_TYPES"
fi
])
dnl PSI_CONST(const name, type, headers to include)
AC_DEFUN(PSI_CONST, [
- AC_MSG_CHECKING(value of $1)
- PSI_INCLUDES=
- if test "$3"
+ AC_CACHE_CHECK(value of $1, psi_cv_const_$1, [
+ case $2 in
+ str*|quoted_str*)
+ if test "$cross_compiling" = "yes"
+ then
+ AC_TRY_CPP(PSI_INCLUDES_DEFAULT($3)$1, psi_const_val=`eval "$ac_try|tail -n1"`, psi_const_val=)
+ else
+ PSI_COMPUTE_STR(psi_const_val, $1, PSI_INCLUDES_DEFAULT($3))
+ fi
+ ;;
+ *)
+ AC_COMPUTE_INT(psi_const_val, $1, PSI_INCLUDES_DEFAULT($3))
+ ;;
+ esac
+ psi_cv_const_$1=$psi_const_val
+ ])
+ if test "$psi_cv_const_$1"
then
- for i in $3
- do
- PSI_INCLUDES="$PSI_INCLUDES
-#include <$i>"
- done
+ case $2 in
+ str*|quoted_str*)
+ PSI_CONSTS="{PSI_T_STRING, \"string\", \"$1\", $psi_cv_const_$1, PSI_T_QUOTED_STRING}, $PSI_CONSTS"
+ ;;
+ *)
+ PSI_CONSTS="{PSI_T_INT, \"int\", \"$1\", \"$psi_cv_const_$1\", PSI_T_NUMBER}, $PSI_CONSTS"
+ ;;
+ esac
fi
- case $2 in
- str*|quoted_str*)
- PSI_COMPUTE_STR(psi_const_val, $1, AC_INCLUDES_DEFAULT()$PSI_INCLUDES)
- if test "$psi_const_val"; then
- PSI_CONSTS="{PSI_T_STRING, \"string\", \"$1\", $psi_const_val, PSI_T_QUOTED_STRING}, $PSI_CONSTS"
- fi
- ;;
- *)
- AC_COMPUTE_INT(psi_const_val, $1, AC_INCLUDES_DEFAULT()$PSI_INCLUDES)
- if test "$psi_const_val"; then
- PSI_CONSTS="{PSI_T_INT, \"int\", \"$1\", \"$psi_const_val\", PSI_T_NUMBER}, $PSI_CONSTS"
- fi
- ;;
- esac
-
- AC_MSG_RESULT($psi_const_val)
])
AC_DEFUN([AX_CHECK_SIGN], [
$3
fi
])
+ dnl PSI_CHECK_OFFSETOF(struct, member, include)
+ dnl[AS_LITERAL_IF([$1], [], [m4_fatal([$0: requires literal arguments])])]dnl
+ dnl[AS_LITERAL_IF([$2], [], [m4_fatal([$0: requires literal arguments])])]dnl
+ AC_DEFUN(PSI_CHECK_OFFSETOF, [
+ _AC_CACHE_CHECK_INT(
+ [offset of $2 in $1],
+ [AS_TR_SH([ac_cv_offsetof_$1_$2])],
+ [(long int) (offsetof ($1, $2))],
+ [AC_INCLUDES_DEFAULT([$3])],
+ [AC_MSG_FAILURE([cannot compute offsetof ($1, $2)])]
+ )
+ AC_DEFINE_UNQUOTED(
+ AS_TR_CPP(offsetof_$1_$2),
+ $AS_TR_SH([ac_cv_offsetof_$1_$2]),
+ [The offset of `$1' in `$2', as computed by offsetof.]
+ )
+ ])
+
+ dnl PSI_STRUCT(name, members, member type cases, includes)
+ PSI_STRUCTS=
+ AC_DEFUN(PSI_STRUCT, [
+ psi_struct_members=
+ m4_foreach(member, [$2], [
+ AC_CHECK_MEMBER(struct $1.member, [
+ case member in
+ $3
+ *) psi_member_type=int ;;
+ esac
+ AC_CHECK_SIZEOF(struct_$1[_]member, [], PSI_INCLUDES_DEFAULT($4,
+ [#define struct_$1_]member ((struct $1 *)0)->member
+ ))
+ PSI_CHECK_OFFSETOF(struct $1, member, PSI_INCLUDES_DEFAULT($4))
+ # pointer level
+ psi_struct_member_pl=`echo $psi_member_type | tr -cd '*' | wc -c`
+ # array size
+ psi_struct_member_as=`echo $psi_member_type | $AWK -F'\x5b\x5d\x5b\x5d' 'END {print 0} /\\x5b\x5b\x5b:digit:\x5d\x5d+\\x5d/ {print$[]2; exit}'`
+ if test $psi_struct_member_as -gt 0
+ then
+ psi_struct_member_pl=`expr $psi_struct_member_pl + 1`
+ fi
+ psi_struct_members="{`psi_type_pair $psi_member_type $ac_cv_sizeof_struct_$1[]_[]member`, \"[]member[]\", $ac_cv_offsetof_struct_$1[]_[]member, $ac_cv_sizeof_struct_$1[]_[]member, $psi_struct_member_pl, $psi_struct_member_as}, $psi_struct_members"
+ ], [], PSI_INCLUDES_DEFAULT($4))
+ ])
+ PSI_STRUCTS="{\"$1\", {$psi_struct_members}}, $PSI_STRUCTS"
+ ])
+
+ AC_TYPE_INT8_T
+ AC_CHECK_ALIGNOF(int8_t)
+ AC_TYPE_UINT8_T
+ AC_CHECK_ALIGNOF(uint8_t)
+ AC_TYPE_INT16_T
+ AC_CHECK_ALIGNOF(int16_t)
+ AC_TYPE_UINT16_T
+ AC_CHECK_ALIGNOF(uint16_t)
+ AC_TYPE_INT32_T
+ AC_CHECK_ALIGNOF(int32_t)
+ AC_TYPE_UINT32_T
+ AC_CHECK_ALIGNOF(uint32_t)
+ AC_TYPE_INT64_T
+ AC_CHECK_ALIGNOF(int64_t)
+ AC_TYPE_UINT64_T
+ AC_CHECK_ALIGNOF(uint64_t)
PSI_TYPE(char, int)
PSI_TYPE(short, int)
PSI_TYPE(float)
PSI_TYPE(double)
PSI_TYPE(void *)
+
+ dnl 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(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(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(uintptr_t, uint)
+ PSI_TYPE(intmax_t, int)
+ PSI_TYPE(uintmax_t, uint)
+
+ PSI_CONST(INT8_MIN, int)
+ PSI_CONST(INT8_MAX, int)
+ PSI_CONST(UINT8_MAX, int)
+ PSI_CONST(INT16_MIN, int)
+ PSI_CONST(INT16_MAX, int)
+ PSI_CONST(UINT16_MAX, int)
+ PSI_CONST(INT32_MIN, int)
+ PSI_CONST(INT32_MAX, int)
+ PSI_CONST(UINT32_MAX, int)
+ PSI_CONST(INT64_MIN, int)
+ PSI_CONST(INT64_MAX, int)
+ PSI_CONST(UINT64_MAX, int)
+
+ PSI_CONST(INT_LEAST8_MIN, int)
+ PSI_CONST(INT_LEAST8_MAX, int)
+ PSI_CONST(UINT_LEAST8_MAX, int)
+ PSI_CONST(INT_LEAST16_MIN, int)
+ PSI_CONST(INT_LEAST16_MAX, int)
+ PSI_CONST(UINT_LEAST16_MAX, int)
+ PSI_CONST(INT_LEAST32_MIN, int)
+ PSI_CONST(INT_LEAST32_MAX, int)
+ PSI_CONST(UINT_LEAST32_MAX, int)
+ PSI_CONST(INT_LEAST64_MIN, int)
+ PSI_CONST(INT_LEAST64_MAX, int)
+ PSI_CONST(UINT_LEAST64_MAX, int)
+
+ PSI_CONST(INT_FAST8_MIN, int)
+ PSI_CONST(INT_FAST8_MAX, int)
+ PSI_CONST(UINT_FAST8_MAX, int)
+ PSI_CONST(INT_FAST16_MIN, int)
+ PSI_CONST(INT_FAST16_MAX, int)
+ PSI_CONST(UINT_FAST16_MAX, int)
+ PSI_CONST(INT_FAST32_MIN, int)
+ PSI_CONST(INT_FAST32_MAX, int)
+ PSI_CONST(UINT_FAST32_MAX, int)
+ PSI_CONST(INT_FAST64_MIN, int)
+ PSI_CONST(INT_FAST64_MAX, int)
+ PSI_CONST(UINT_FAST64_MAX, int)
+
+ PSI_CONST(INTPTR_MIN, int)
+ PSI_CONST(INTPTR_MAX, int)
+ PSI_CONST(UINTPTR_MAX, int)
+ PSI_CONST(INTMAX_MIN, int)
+ PSI_CONST(INTMAX_MAX, int)
+ PSI_CONST(UINTMAX_MAX, int)
dnl stddef.h
PSI_TYPE(ptrdiff_t, int)
+ PSI_CONST(PTRDIFF_MIN, int)
+ PSI_CONST(PTRDIFF_MAX, int)
PSI_TYPE(size_t, uint)
+ PSI_CONST(SIZE_MAX, int)
AC_CHECK_TYPE(wchar_t, [
AX_CHECK_SIGN(wchar_t, psi_wchar_t=int, psi_wchar_t=uint)
PSI_TYPE(wchar_t, $psi_wchar_t)
+ PSI_CONST(WCHAR_MIN, int)
+ PSI_CONST(WCHAR_MAX, int)
])
dnl stdio.h
PSI_CONST(EXIT_SUCCESS, int)
PSI_CONST(RAND_MAX, int)
PSI_CONST(MB_CUR_MAX, int)
+ dnl sys/stat.h
+ PSI_STRUCT(stat, [
+ [st_dev],
+ [st_ino],
+ [st_mode],
+ [st_nlink],
+ [st_uid],
+ [st_gid],
+ [st_rdev],
+ [st_size],
+ [st_atim],
+ [st_mtim],
+ [st_ctim],
+ [st_blksize],
+ [st_blocks]], [
+ st_?tim) psi_member_type="struct timespec" ;;
+ ], sys/stat.h)
dnl sys/time.h
PSI_CONST(ITIMER_REAL, int, sys/time.h)
PSI_CONST(ITIMER_VIRTUAL, int, sys/time.h)
PSI_TYPE(time_t, int)
PSI_TYPE(timer_t, int)
PSI_TYPE(uid_t)
+
+ dnl wchar.h
+ AC_CHECK_TYPE(wint_t, [
+ AX_CHECK_SIGN(wint_t, psi_wint_t=int, psi_wint_t=uint)
+ PSI_TYPE(wint_t, $psi_wint_t, wchar.h)
+ PSI_CONST(WINT_MIN, int, wchar.h)
+ PSI_CONST(WINT_MAX, int, wchar.h)
+ PSI_CONST(WEOF, int, wchar.h)
+ ], [], [
+ AC_INCLUDES_DEFAULT()
+ #include <wchar.h>
+ ])
+
AC_DEFINE_UNQUOTED(PHP_PSI_TYPES, $PSI_TYPES, Predefined types)
AC_DEFINE_UNQUOTED(PHP_PSI_CONSTS, $PSI_CONSTS, Predefined constants)
+ AC_DEFINE_UNQUOTED(PHP_PSI_STRUCTS, $PSI_STRUCTS, Predefined structs)
PHP_PSI_SRCDIR=PHP_EXT_SRCDIR(psi)
PHP_PSI_BUILDDIR=PHP_EXT_BUILDDIR(psi)
#include "parser.h"
#include "validator.h"
-#define psi_predef_count(s) (sizeof(psi_predef_ ##s## s)/sizeof(psi_predef ##s))
+#define psi_predef_count(of) ((sizeof(psi_predef ##of## s)/sizeof(psi_predef ##of))-1)
typedef struct psi_predef_type {
token_t type_tag;
const char *type_name;
const char *alias;
} psi_predef_type;
-#define psi_predef_type_count() psi_predef_count(type)
-static const psi_predef_types[] = {
- PHP_PSI_TYPES
+static const psi_predef_type psi_predef_types[] = {
+ PHP_PSI_TYPES{0}
};
+#define psi_predef_type_count() psi_predef_count(_type)
typedef struct psi_predef_const {
token_t type_tag;
const char *val_text;
token_t val_type_tag;
} psi_predef_const;
-#define psi_predef_const_count() psi_predef_count(const)
-static const psi_predef_consts[] = {
- PHP_PSI_CONSTS
+static const psi_predef_const psi_predef_consts[] = {
+ PHP_PSI_CONSTS{0}
};
+#define psi_predef_const_count() psi_predef_count(_const)
+
+typedef struct psi_predef_struct_member {
+ token_t type_tag;
+ const char *type_name;
+ const char *name;
+ size_t off;
+ size_t len;
+ size_t pointer_level;
+ size_t array_size;
+} psi_predef_struct_member;
+#define PSI_PREDEF_STRUCT_MEMBERS 32
+typedef struct psi_predef_struct {
+ const char *name;
+ psi_predef_struct_member members[PSI_PREDEF_STRUCT_MEMBERS];
+} psi_predef_struct;
+static const psi_predef_struct psi_predef_structs[] = {
+ PHP_PSI_STRUCTS{0}
+};
+#define psi_predef_struct_count() psi_predef_count(_struct)
PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error)
{
- size_t i;
+ size_t i, j;
PSI_Data data;
if (!C) {
memset(&data, 0, sizeof(data));
for (i = 0; i < psi_predef_type_count(); ++i) {
- psi_predef_type *pre = &psi_predef_types[i];
+ const psi_predef_type *pre = &psi_predef_types[i];
decl_type *type = init_decl_type(pre->type_tag, pre->type_name);
decl_typedef *def = init_decl_typedef(pre->alias, type);
data.defs = add_decl_typedef(data.defs, def);
}
for (i = 0; i < psi_predef_const_count(); ++i) {
- psi_predef_const *pre = psi_predef_const[i];
+ const psi_predef_const *pre = &psi_predef_consts[i];
impl_def_val *val = init_impl_def_val(pre->val_type_tag, pre->val_text);
const_type *type = init_const_type(pre->type_tag, pre->type_name);
constant *constant = init_constant(type, pre->name, val);
data.consts = add_constant(data.consts, constant);
}
+ for (i = 0; i < psi_predef_struct_count(); ++i) {
+ const psi_predef_struct *pre = &psi_predef_structs[i];
+ decl_args *dargs = init_decl_args(NULL);
+
+ for (j = 0; j < PSI_PREDEF_STRUCT_MEMBERS; ++j) {
+ const psi_predef_struct_member *member = &pre->members[j];
+ decl_type *type;
+ decl_var *dvar;
+
+ if (!member->name) {
+ break;
+ }
+
+ type = init_decl_type(member->type_tag, member->type_name);
+ dvar = init_decl_var(member->name, member->pointer_level, member->array_size);
+ dargs = add_decl_arg(dargs, init_decl_arg(type, dvar));
+ }
+
+ data.structs = add_decl_struct(data.structs,
+ init_decl_struct(pre->name, dargs));
+ }
return C;
}
struct decl_struct *strct;
} decl_type;
-static inline decl_type *init_decl_type(token_t type, char *name) {
+static inline decl_type *init_decl_type(token_t type, const char *name) {
decl_type *t = calloc(1, sizeof(*t));
t->type = type;
t->name = strdup(name);
decl_type *type;
} decl_typedef;
-static inline decl_typedef *init_decl_typedef(char *name, decl_type *type) {
+static inline decl_typedef *init_decl_typedef(const char *name, decl_type *type) {
decl_typedef *t = calloc(1, sizeof(*t));
t->alias = strdup(name);
t->type = type;
struct decl_arg *arg;
} decl_var;
-static inline decl_var *init_decl_var(char *name, unsigned pl, unsigned as) {
+static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as) {
decl_var *v = calloc(1, sizeof(*v));
v->name = (char *) strdup((const char *) name);
v->pointer_level = pl;
char *convention;
} decl_abi;
-static inline decl_abi *init_decl_abi(char *convention) {
+static inline decl_abi *init_decl_abi(const char *convention) {
decl_abi *abi = calloc(1, sizeof(*abi));
abi->convention = strdup(convention);
return abi;
decl_struct_layout *layout;
} decl_struct;
-static inline decl_struct *init_decl_struct(char *name, decl_args *args) {
+static inline decl_struct *init_decl_struct(const char *name, decl_args *args) {
decl_struct *s = calloc(1, sizeof(*s));
s->name = strdup(name);
s->args = args;
token_t type;
} impl_type;
-static inline impl_type *init_impl_type(token_t type, char *name) {
+static inline impl_type *init_impl_type(token_t type, const char *name) {
impl_type *t = calloc(1, sizeof(*t));
t->type = type;
- t->name = (char *) strdup((const char *) name);
+ t->name = strdup(name);
return t;
}
unsigned reference:1;
} impl_var;
-static inline impl_var *init_impl_var(char *name, int is_reference) {
+static inline impl_var *init_impl_var(const char *name, int is_reference) {
impl_var *var = calloc(1, sizeof(*var));
var->name = strdup(name);
var->reference = is_reference;
char *text;
} impl_def_val;
-static inline impl_def_val *init_impl_def_val(token_t t, char *text) {
+static inline impl_def_val *init_impl_def_val(token_t t, const char *text) {
impl_def_val *def = calloc(1, sizeof(*def));
def->type = t;
def->text = strdup(text);
let_calloc *alloc;
} let_func;
-static inline let_func *init_let_func(token_t type, char *name, let_calloc *alloc) {
+static inline let_func *init_let_func(token_t type, const char *name, let_calloc *alloc) {
let_func *func = calloc(1, sizeof(*func));
func->type = type;
func->name = strdup(name);
char *name;
} set_func;
-static inline set_func *init_set_func(token_t type, char *name) {
+static inline set_func *init_set_func(token_t type, const char *name) {
set_func *func = calloc(1, sizeof(*func));
func->type = type;
- func->name = (char *) strdup((const char *) name);
+ func->name = strdup(name);
return func;
}
impl_def_val *val;
} constant;
-static inline constant *init_constant(const_type *type, char *name, impl_def_val *val) {
+static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) {
constant *c = calloc(1, sizeof(*c));
c->type = type;
c->name = strdup(name);