flush
authorMichael Wallner <mike@php.net>
Mon, 18 Jan 2016 06:28:44 +0000 (07:28 +0100)
committerMichael Wallner <mike@php.net>
Mon, 18 Jan 2016 06:29:23 +0000 (07:29 +0100)
.gitignore
config.m4
m4/netinet_in.m4 [new file with mode: 0644]
m4/netinet_tcp.m4 [new file with mode: 0644]
m4/poll.m4 [new file with mode: 0644]
m4/psi.m4
m4/psi_type.m4
src/parser.h
src/parser_proc.y

index 0487d1b..4eafc8b 100644 (file)
@@ -53,3 +53,11 @@ tests/*/*.sh
 /config.cache
 *~
 *.swp
+php_psi_consts.h
+php_psi_decls.h
+php_psi_macros.h
+php_psi_redirs.h
+php_psi_stdinc.h
+php_psi_structs.h
+php_psi_types.h
+php_psi_va_decls.h
index fd41d32..817887d 100644 (file)
--- a/config.m4
+++ b/config.m4
@@ -28,6 +28,9 @@ m4_foreach(incfile, [
        [sys_uio.m4],
        [sys_utsname.m4],
        [netdb.m4],
+       [netinet_in.m4],
+       [netinet_tcp.m4],
+       [poll.m4],
        [syslog.m4],
        [time.m4],
        [wchar.m4],
@@ -67,6 +70,9 @@ if test "$PHP_PSI" != no; then
        PSI_CHECK_SYS_UIO
        PSI_CHECK_SYS_UTSNAME
        PSI_CHECK_NETDB
+       PSI_CHECK_NETINET_IN
+       PSI_CHECK_NETINET_TCP
+       PSI_CHECK_POLL
        PSI_CHECK_SYSLOG
        PSI_CHECK_WCHAR
        PSI_CHECK_WCTYPE
diff --git a/m4/netinet_in.m4 b/m4/netinet_in.m4
new file mode 100644 (file)
index 0000000..4dcca38
--- /dev/null
@@ -0,0 +1,66 @@
+PSI_CHECK_NETINET_IN() {
+       AC_CHECK_HEADERS(netinet/in.h)
+
+       PSI_TYPE(in_port_t, uint)
+       PSI_TYPE(in_addr_t, uint)
+
+       PSI_STRUCT(struct in_addr, [
+               in_addr_t s_addr]
+       )
+
+       PSI_STRUCT(struct sockaddr_in, [
+               sa_family_t sin_family,
+               in_port_t sin_port,
+               struct in_addr sin_addr]
+       )
+
+       PSI_STRUCT(struct in6_addr, [
+               uint8_t s6_addr@<:@16@:>@]
+       )
+       PSI_STRUCT(struct sockaddr_in6, [
+               sa_family_t sin6_family,
+               in_port_t sin6_port,
+               uint32_t sin6_flowinfo,
+               struct in6_addr sin6_addr,
+               uint32_t sin6_scope_id]
+       )
+
+       PSI_STRUCT(struct ipv6_mreq, [
+               struct in6_addr ipv6mr_multiaddr,
+               unsigned ipv6mr_interface]
+       )
+
+       PSI_CONST(IPPROTO_IP, int)
+       PSI_CONST(IPPROTO_IPV6, int)
+       PSI_CONST(IPPROTO_ICMP, int)
+       PSI_CONST(IPPROTO_RAW, int)
+       PSI_CONST(IPPROTO_TCP, int)
+       PSI_CONST(IPPROTO_UDP, int)
+
+       PSI_CONST(INADDR_ANY, int)
+       PSI_CONST(INADDR_BROADCAST, int)
+       PSI_CONST(INET6_ADDRSTRLEN, int)
+
+       PSI_CONST(IPV6_JOIN_GROUP, int)
+       PSI_CONST(IPV6_LEAVE_GROUP, int)
+       PSI_CONST(IPV6_MULTICAST_HOPS, int)
+       PSI_CONST(IPV6_MULTICAST_IF, int)
+       PSI_CONST(IPV6_MULTICAST_LOOP, int)
+       PSI_CONST(IPV6_UNICAST_HOPS, int)
+       PSI_CONST(IPV6_V6ONLY, int)
+
+       PSI_MACRO(int IN6_IS_ADDR_UNSPECIFIED, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_LOOPBACK, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_MULTICAST, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_LINKLOCAL, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_SITELOCAL, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_V4MAPPED, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_V4COMPAT, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_MC_NODELOCAL, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_MC_LINKLOCAL, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_MC_SITELOCAL, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_MC_ORGLOCAL, [(const struct in6_addr *a)])
+       PSI_MACRO(int IN6_IS_ADDR_MC_GLOBAL, [(const struct in6_addr *a)])
+
+       PSI_EXTVAR(struct in6_addr in6addr_loopback)
+}
diff --git a/m4/netinet_tcp.m4 b/m4/netinet_tcp.m4
new file mode 100644 (file)
index 0000000..7c4677c
--- /dev/null
@@ -0,0 +1,5 @@
+PSI_CHECK_NETINET_TCP() {
+       AC_CHECK_HEADERS(netinet/tcp.h)
+
+       PSI_CONST(TCP_NODELAY, int)
+}
diff --git a/m4/poll.m4 b/m4/poll.m4
new file mode 100644 (file)
index 0000000..2105a64
--- /dev/null
@@ -0,0 +1,24 @@
+PSI_CHECK_POLL() {
+       AC_CHECK_HEADERS(poll.h)
+
+       PSI_STRUCT(struct pollfd, [
+               int fd,
+               short events,
+               short revents]
+       )
+
+       PSI_TYPE(nfds_t, uint)
+
+       PSI_CONST(POLLIN, int)
+       PSI_CONST(POLLRDNORM, int)
+       PSI_CONST(POLLRDBAND, int)
+       PSI_CONST(POLLPRI, int)
+       PSI_CONST(POLLOUT, int)
+       PSI_CONST(POLLWRNORM, int)
+       PSI_CONST(POLLRWBAND, int)
+       PSI_CONST(POLLERR, int)
+       PSI_CONST(POLLHUP, int)
+       PSI_CONST(POLLNVAL, int)
+
+       PSI_DECL(int poll, [(struct pollfd *fds, nfds_t nfds, int timeout)])
+}
index 4ea5590..4729740 100644 (file)
--- a/m4/psi.m4
+++ b/m4/psi.m4
@@ -94,12 +94,18 @@ AC_DEFUN(PSI_INCLUDES, [AC_INCLUDES_DEFAULT()
 #ifdef HAVE_NETINET_IN_H
 # include <netinet/in.h>
 #endif
+#ifdef HAVE_NETINET_TCP_H
+# include <netinet/tcp.h>
+#endif
 #ifdef HAVE_ARPA_NAMESER_H
 # include <arpa/nameser.h>
 #endif
 #ifdef HAVE_NETDB_H
 # include <netdb.h>
 #endif
+#ifdef HAVE_POLL_H
+# include <poll.h>
+#endif
 #ifdef HAVE_RESOLV_H
 # include <resolv.h>
 #endif
index 6324c75..85750d9 100644 (file)
@@ -161,16 +161,34 @@ AC_DEFUN(PSI_CHECK_STD_TYPES, [
        AC_CHECK_ALIGNOF(float)
        PSI_TYPE(double)
        AC_CHECK_ALIGNOF(double)
+       PSI_TYPE(long double)
+       AC_CHECK_ALIGNOF(long double)
        PSI_TYPE(void *)
        AC_CHECK_ALIGNOF(void *)
 
        PSI_TYPE(char, int)
+       PSI_TYPE(signed char, int)
        PSI_TYPE(unsigned char, uint)
        PSI_TYPE(short, int)
+       PSI_TYPE(short int, int)
+       PSI_TYPE(signed short, int)
+       PSI_TYPE(signed short int, int)
        PSI_TYPE(unsigned short, uint)
+       PSI_TYPE(unsigned short int, uint)
        PSI_TYPE(int, int)
+       PSI_TYPE(signed int, int)
+       PSI_TYPE(signed, int)
        PSI_TYPE(unsigned int, uint)
        PSI_TYPE(unsigned, uint)
        PSI_TYPE(long, int)
+       PSI_TYPE(long int, int)
+       PSI_TYPE(signed long int, int)
        PSI_TYPE(unsigned long, uint)
+       PSI_TYPE(unsigned long int, uint)
+       PSI_TYPE(long long, int)
+       PSI_TYPE(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)
 ])
index 5129097..8c25e88 100644 (file)
@@ -65,6 +65,40 @@ static inline decl_type *init_decl_type(token_t type, const char *name) {
        return t;
 }
 
+static inline decl_type *init_decl_type_ex(token_t type, int argc, ...) {
+       va_list argv;
+       char *ptr, *arg;
+       unsigned i;
+       size_t len, pos = 0, all = 0;
+       decl_type *t = calloc(1, sizeof(*t));
+
+       va_start(argv, argc);
+       for (i = 0; i < argc; ++i) {
+               arg = va_arg(argv, char *);
+               len = va_arg(argv, size_t);
+
+               if (len) {
+                       if (all) {
+                               pos = all;
+                               ptr = realloc(ptr, 1 + (all += len));
+                       } else {
+                               ptr = malloc(ptr, 1 + (all = len));
+                       }
+                       memcpy(ptr + pos, arg, len);
+               }
+       }
+       va_end(argv);
+
+       if (!all) {
+               ptr = calloc(1, 1);
+       } else {
+               ptr[all] = 0;
+       }
+       t->type = type;
+       t->name = ptr;
+       return t;
+}
+
 static inline decl_type *real_decl_type(decl_type *type) {
        while (type->real) {
                type = type->real;
@@ -1252,6 +1286,10 @@ typedef struct PSI_Parser {
        char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
 } PSI_Parser;
 
+static inline size_t PSI_TokenAllocSize(size_t token_len, size_t fname_len) {
+       return sizeof(PSI_Token) + token_len + fname_len + sizeof(unsigned) + 2;
+}
+
 static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
        PSI_Token *T;
        size_t token_len, fname_len;
@@ -1265,7 +1303,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, sizeof(*T) + token_len + fname_len + sizeof(unsigned) + 2);
+       T = calloc(1, PSI_TokenAllocSize(token_len, fname_len);
        T->type = token_typ;
        T->size = token_len;
        T->text = &T->buf[0];
@@ -1280,8 +1318,7 @@ static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
 }
 
 static inline PSI_Token *PSI_TokenCopy(PSI_Token *src) {
-       size_t fname_len = strlen(src->file);
-       size_t strct_len = sizeof(*src) + src->size + fname_len + sizeof(unsigned) + 2;
+       size_t strct_len = PSI_TokenAllocSize(src->size, strlen(src->file));
        PSI_Token *ptr = malloc(strct_len);
 
        memcpy(ptr, src, strct_len);
@@ -1292,6 +1329,32 @@ static inline PSI_Token *PSI_TokenCopy(PSI_Token *src) {
        return ptr;
 }
 
+static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) {
+       va_list argv;
+       unsigned i;
+       PSI_Token *T = NULL;
+
+       va_start(argv, argc);
+       for (i = 0; i < argc; ++i) {
+               PSI_Token *arg = va_arg(argv, PSI_Token *);
+
+               if (T) {
+                       size_t fname_len = strlen(T->file);
+
+                       T = realloc(T, PSI_TokenAllocSize(T->size + arg->size, fname_len));
+                       memmove(&T->buf[T->size + 1], T->file, fname_len + 1);
+                       memcpy(T->file - 1, arg->text, arg->size + 1)
+                       T->file = &T->buf[T->size + 1];
+               } else {
+                       T = PSI_TokenCopy(arg);
+                       T->type = PSI_T_NAME;
+               }
+       }
+       va_end(argv);
+
+       return T;
+}
+
 static inline const char *PSI_TokenLocation(PSI_Token *t) {
        return t ? t->file : "<builtin>:0:0";
 }
index 5713c85..d82a90f 100644 (file)
@@ -2,6 +2,7 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdarg.h>
 
 #include "parser.h"
 
@@ -27,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 UNSIGNED.
+%fallback NAME TEMP FREE SET LET RETURN LIB INT LONG SIGNED UNSIGNED.
 
 file ::= blocks.
 
@@ -244,20 +245,31 @@ decl_type(type_) ::= decl_type_token(T). {
        type_->token = T;
 }
 /* unsigned, urgh */
-decl_type(type_) ::= UNSIGNED NAME(T). {
+decl_type(type_) ::= UNSIGNED(U) NAME(N). {
+       PSI_Token *T = PSI_TokenCat(2, U, N);
        type_ = init_decl_type(T->type, T->text);
        type_->token = T;
-       type_->name = realloc(type_->name, T->size + sizeof("unsigned"));
-       memmove(type_->name + sizeof("unsigned"), type_->name, T->size);
-       memcpy(type_->name, "unsigned", sizeof("unsigned")-1);
-       type_->name[sizeof("unsigned")] = ' ';
-       type_->name[T->size + sizeof("unsigned")] = 0;
+       free(U);
+       free(N);
+}
+decl_type(type_) ::= SIGNED NAME(T). {
+       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 here because we have it in our lexer rules */
+/* 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;
+}
 /* structs ! */
 decl_type(type_) ::= STRUCT(S) NAME(T). {
        type_ = init_decl_type(S->type, T->text);