about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xwrapperhelper/Makefile2
-rw-r--r--wrapperhelper/example-libc.h2
-rw-r--r--wrapperhelper/include-override/common/bits/floatn.h118
-rw-r--r--wrapperhelper/include-override/common/bits/stdint-intn.h (renamed from wrapperhelper/include-fixed/bits/stdint-intn.h)0
-rw-r--r--wrapperhelper/include-override/common/bits/stdint-least.h (renamed from wrapperhelper/include-fixed/bits/stdint-least.h)0
-rw-r--r--wrapperhelper/include-override/common/bits/stdint-uintn.h (renamed from wrapperhelper/include-fixed/bits/stdint-uintn.h)0
-rw-r--r--wrapperhelper/include-override/common/bits/types.h (renamed from wrapperhelper/include-fixed/bits/types.h)0
-rw-r--r--wrapperhelper/include-override/common/stdint.h (renamed from wrapperhelper/include-fixed/stdint.h)145
-rw-r--r--wrapperhelper/include-override/x86_64/stdc-predef.h405
-rw-r--r--wrapperhelper/src/generator.c34
-rw-r--r--wrapperhelper/src/generator.h1
-rw-r--r--wrapperhelper/src/lang.c4
-rw-r--r--wrapperhelper/src/lang.h4
-rw-r--r--wrapperhelper/src/machine.c171
-rw-r--r--wrapperhelper/src/machine.h5
-rw-r--r--wrapperhelper/src/parse.c227
-rw-r--r--wrapperhelper/src/preproc.c291
-rw-r--r--wrapperhelper/src/preproc_private.h39
18 files changed, 943 insertions, 505 deletions
diff --git a/wrapperhelper/Makefile b/wrapperhelper/Makefile
index 31a3e7b0..da1aa1d6 100755
--- a/wrapperhelper/Makefile
+++ b/wrapperhelper/Makefile
@@ -114,7 +114,7 @@ ifneq ($(MAKECMDGOALS:distclean=clean),clean)
 bin obj: ; $(SILENCER)test -d $@ || mkdir $@
 # $(eval $(call reproduce_tree,<base>))
 define reproduce_tree =
-$(1) $(1)/parser: | $$$$(@D) ; $(SILENCER)test -d $$@ || mkdir $$@
+$(1): | $$$$(@D) ; $(SILENCER)test -d $$@ || mkdir $$@
 endef
 $(eval $(call reproduce_tree,obj/$(OBJDIR)))
 $(eval $(call reproduce_tree,obj/$(OBJDIR)/tests))
diff --git a/wrapperhelper/example-libc.h b/wrapperhelper/example-libc.h
index d17d475b..b4df17d2 100644
--- a/wrapperhelper/example-libc.h
+++ b/wrapperhelper/example-libc.h
@@ -131,6 +131,8 @@
 
 #pragma wrappers type_letters S FILE*
 #pragma wrappers type_letters S const FILE*
+#pragma wrappers type_letters S FILE* restrict
+#pragma wrappers type_letters S const FILE* restrict
 #pragma wrappers type_letters p FTS*
 #pragma wrappers type_letters p const FTS*
 #pragma wrappers type_letters p FTS64*
diff --git a/wrapperhelper/include-override/common/bits/floatn.h b/wrapperhelper/include-override/common/bits/floatn.h
new file mode 100644
index 00000000..ebd359f9
--- /dev/null
+++ b/wrapperhelper/include-override/common/bits/floatn.h
@@ -0,0 +1,118 @@
+/* Macros to control TS 18661-3 glibc features on x86.
+   Copyright (C) 2017-2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.
+
+This file has been adapted to work with the 'wrapperhelper' project on the 09/10/2024.
+*/
+
+#ifndef _BITS_FLOATN_H
+#define _BITS_FLOATN_H
+
+#include <features.h>
+
+/* Defined to 1 if the current compiler invocation provides a
+   floating-point type with the IEEE 754 binary128 format, and this
+   glibc includes corresponding *f128 interfaces for it.  The required
+   libgcc support was added some time after the basic compiler
+   support, for x86_64 and x86.  */
+# define __HAVE_FLOAT128 1
+
+/* Defined to 1 if __HAVE_FLOAT128 is 1 and the type is ABI-distinct
+   from the default float, double and long double types in this glibc.  */
+#if __HAVE_FLOAT128
+# define __HAVE_DISTINCT_FLOAT128 1
+#else
+# define __HAVE_DISTINCT_FLOAT128 0
+#endif
+
+/* Defined to 1 if the current compiler invocation provides a
+   floating-point type with the right format for _Float64x, and this
+   glibc includes corresponding *f64x interfaces for it.  */
+#define __HAVE_FLOAT64X 1
+
+/* Defined to 1 if __HAVE_FLOAT64X is 1 and _Float64x has the format
+   of long double.  Otherwise, if __HAVE_FLOAT64X is 1, _Float64x has
+   the format of _Float128, which must be different from that of long
+   double.  */
+#define __HAVE_FLOAT64X_LONG_DOUBLE 1
+
+#ifndef __ASSEMBLER__
+
+/* Defined to concatenate the literal suffix to be used with _Float128
+   types, if __HAVE_FLOAT128 is 1. */
+# if __HAVE_FLOAT128
+#  if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
+/* The literal suffix f128 exists only since GCC 7.0.  */
+#   define __f128(x) x##q
+#  else
+#   define __f128(x) x##f128
+#  endif
+# endif
+
+/* Defined to a complex binary128 type if __HAVE_FLOAT128 is 1.  */
+# if __HAVE_FLOAT128
+#  if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
+/* Add a typedef for older GCC compilers which don't natively support
+   _Complex _Float128.  */
+typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
+#   define __CFLOAT128 __cfloat128
+#  else
+#   define __CFLOAT128 _Complex _Float128
+#  endif
+# endif
+
+/* The remaining of this file provides support for older compilers.  */
+# if __HAVE_FLOAT128
+
+/* The type _Float128 exists only since GCC 7.0.  */
+#  if !__GNUC_PREREQ (7, 0) || (defined __cplusplus && !__GNUC_PREREQ (13, 0))
+typedef __float128 _Float128;
+#  endif
+
+/* __builtin_huge_valf128 doesn't exist before GCC 7.0.  */
+#  if !__GNUC_PREREQ (7, 0)
+#   define __builtin_huge_valf128() ((_Float128) __builtin_huge_val ())
+#  endif
+
+/* Older GCC has only a subset of built-in functions for _Float128 on
+   x86, and __builtin_infq is not usable in static initializers.
+   Converting a narrower sNaN to _Float128 produces a quiet NaN, so
+   attempts to use _Float128 sNaNs will not work properly with older
+   compilers.  */
+#  if !__GNUC_PREREQ (7, 0)
+#   define __builtin_copysignf128 __builtin_copysignq
+#   define __builtin_fabsf128 __builtin_fabsq
+#   define __builtin_inff128() ((_Float128) __builtin_inf ())
+#   define __builtin_nanf128(x) ((_Float128) __builtin_nan (x))
+#   define __builtin_nansf128(x) ((_Float128) __builtin_nans (x))
+#  endif
+
+/* In math/math.h, __MATH_TG will expand signbit to __builtin_signbit*,
+   e.g.: __builtin_signbitf128, before GCC 6.  However, there has never
+   been a __builtin_signbitf128 in GCC and the type-generic builtin is
+   only available since GCC 6.  */
+#  if !__GNUC_PREREQ (6, 0)
+#   define __builtin_signbitf128 __signbitf128
+#  endif
+
+# endif
+
+#endif /* !__ASSEMBLER__.  */
+
+#include <bits/floatn-common.h>
+
+#endif /* _BITS_FLOATN_H */
diff --git a/wrapperhelper/include-fixed/bits/stdint-intn.h b/wrapperhelper/include-override/common/bits/stdint-intn.h
index 14abdb46..14abdb46 100644
--- a/wrapperhelper/include-fixed/bits/stdint-intn.h
+++ b/wrapperhelper/include-override/common/bits/stdint-intn.h
diff --git a/wrapperhelper/include-fixed/bits/stdint-least.h b/wrapperhelper/include-override/common/bits/stdint-least.h
index d9753d7d..d9753d7d 100644
--- a/wrapperhelper/include-fixed/bits/stdint-least.h
+++ b/wrapperhelper/include-override/common/bits/stdint-least.h
diff --git a/wrapperhelper/include-fixed/bits/stdint-uintn.h b/wrapperhelper/include-override/common/bits/stdint-uintn.h
index cf2e8b4e..cf2e8b4e 100644
--- a/wrapperhelper/include-fixed/bits/stdint-uintn.h
+++ b/wrapperhelper/include-override/common/bits/stdint-uintn.h
diff --git a/wrapperhelper/include-fixed/bits/types.h b/wrapperhelper/include-override/common/bits/types.h
index 7d1eddda..7d1eddda 100644
--- a/wrapperhelper/include-fixed/bits/types.h
+++ b/wrapperhelper/include-override/common/bits/types.h
diff --git a/wrapperhelper/include-fixed/stdint.h b/wrapperhelper/include-override/common/stdint.h
index a3341ad2..0389d24b 100644
--- a/wrapperhelper/include-fixed/stdint.h
+++ b/wrapperhelper/include-override/common/stdint.h
@@ -50,14 +50,14 @@ This file has been adapted to work with the 'wrapperhelper' project on the 09/06
 
 /* Signed.  */
 typedef int8_t int_fast8_t;
-typedef int16_t int_fast16_t;
-typedef int32_t int_fast32_t;
+typedef long int_fast16_t;
+typedef long int_fast32_t;
 typedef int64_t int_fast64_t;
 
 /* Unsigned.  */
 typedef uint8_t uint_fast8_t;
-typedef uint16_t uint_fast16_t;
-typedef uint32_t uint_fast32_t;
+typedef unsigned long uint_fast16_t;
+typedef unsigned long uint_fast32_t;
 typedef uint64_t uint_fast64_t;
 
 
@@ -103,132 +103,93 @@ typedef uint64_t		uintmax_t;
 
 
 /* Minimum of signed integral types having a minimum size.  */
-# define INT_LEAST8_MIN		(-128)
-# define INT_LEAST16_MIN	(-32767-1)
-# define INT_LEAST32_MIN	(-2147483647-1)
-# define INT_LEAST64_MIN	(-__INT64_C(9223372036854775807)-1)
+# define INT_LEAST8_MIN  (-__INT_LEAST8_MAX__-1)
+# define INT_LEAST16_MIN (-__INT_LEAST16_MAX__-1)
+# define INT_LEAST32_MIN (-__INT_LEAST32_MAX__-1)
+# define INT_LEAST64_MIN (-__INT_LEAST64_MAX__-1)
 /* Maximum of signed integral types having a minimum size.  */
-# define INT_LEAST8_MAX		(127)
-# define INT_LEAST16_MAX	(32767)
-# define INT_LEAST32_MAX	(2147483647)
-# define INT_LEAST64_MAX	(__INT64_C(9223372036854775807))
+# define INT_LEAST8_MAX  __INT_LEAST8_MAX__
+# define INT_LEAST16_MAX __INT_LEAST16_MAX__
+# define INT_LEAST32_MAX __INT_LEAST32_MAX__
+# define INT_LEAST64_MAX __INT_LEAST64_MAX__
 
 /* Maximum of unsigned integral types having a minimum size.  */
-# define UINT_LEAST8_MAX	(255)
-# define UINT_LEAST16_MAX	(65535)
-# define UINT_LEAST32_MAX	(4294967295U)
-# define UINT_LEAST64_MAX	(__UINT64_C(18446744073709551615))
+# define UINT_LEAST8_MAX  __UINT_LEAST8_MAX__
+# define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
+# define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
+# define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
 
 
 /* Minimum of fast signed integral types having a minimum size.  */
-# define INT_FAST8_MIN		(-128)
-# define INT_FAST16_MIN    INT16_MIN
-# define INT_FAST32_MIN    INT32_MIN
-# define INT_FAST64_MIN		(-__INT64_C(9223372036854775807)-1)
+# define INT_FAST8_MIN  (-__INT_FAST8_MAX__-1)
+# define INT_FAST16_MIN (-__INT_FAST16_MAX__-1)
+# define INT_FAST32_MIN (-__INT_FAST32_MAX__-1)
+# define INT_FAST64_MIN (-__INT_FAST64_MAX__-1)
 /* Maximum of fast signed integral types having a minimum size.  */
-# define INT_FAST8_MAX		(127)
-# define INT_FAST16_MAX    INT16_MAX
-# define INT_FAST32_MAX    INT32_MAX
-# define INT_FAST64_MAX		(__INT64_C(9223372036854775807))
+# define INT_FAST8_MAX  __INT_FAST8_MAX__
+# define INT_FAST16_MAX __INT_FAST16_MAX__
+# define INT_FAST32_MAX __INT_FAST32_MAX__
+# define INT_FAST64_MAX __INT_FAST64_MAX__
 
 /* Maximum of fast unsigned integral types having a minimum size.  */
-# define UINT_FAST8_MAX		(255)
-# define UINT_FAST16_MAX   UINT16_MAX
-# define UINT_FAST32_MAX   UINT32_MAX
-# define UINT_FAST64_MAX	(__UINT64_C(18446744073709551615))
+# define UINT_FAST8_MAX  __UINT_FAST8_MAX__
+# define UINT_FAST16_MAX __UINT_FAST16_MAX__
+# define UINT_FAST32_MAX __UINT_FAST32_MAX__
+# define UINT_FAST64_MAX __UINT_FAST64_MAX__
 
 
 /* Values to test for integral types holding `void *' pointer.  */
-# if __WORDSIZE == 64
-#  define INTPTR_MIN		(-9223372036854775807L-1)
-#  define INTPTR_MAX		(9223372036854775807L)
-#  define UINTPTR_MAX		(18446744073709551615UL)
-# else
-#  define INTPTR_MIN		(-2147483647-1)
-#  define INTPTR_MAX		(2147483647)
-#  define UINTPTR_MAX		(4294967295U)
-# endif
-
+# define INTPTR_MIN  (-__INTPTR_MAX__-1)
+# define INTPTR_MAX  __INTPTR_MAX__
+# define UINTPTR_MAX __UINTPTR_MAX__
 
 /* Minimum for largest signed integral type.  */
-# define INTMAX_MIN		(-__INT64_C(9223372036854775807)-1)
+# define INTMAX_MIN (-__INTMAX_MAX__-1)
 /* Maximum for largest signed integral type.  */
-# define INTMAX_MAX		(__INT64_C(9223372036854775807))
+# define INTMAX_MAX __INTMAX_MAX__
 
 /* Maximum for largest unsigned integral type.  */
-# define UINTMAX_MAX		(__UINT64_C(18446744073709551615))
-
+# define UINTMAX_MAX __UINTMAX_MAX__
 
 /* Limits of other integer types.  */
 
 /* Limits of `ptrdiff_t' type.  */
-# if __WORDSIZE == 64
-#  define PTRDIFF_MIN		(-9223372036854775807L-1)
-#  define PTRDIFF_MAX		(9223372036854775807L)
-# else
-#  if __WORDSIZE32_PTRDIFF_LONG
-#   define PTRDIFF_MIN		(-2147483647L-1)
-#   define PTRDIFF_MAX		(2147483647L)
-#  else
-#   define PTRDIFF_MIN		(-2147483647-1)
-#   define PTRDIFF_MAX		(2147483647)
-#  endif
-# endif
+# define PTRDIFF_MIN (-__PTRDIFF_MAX__-1)
+# define PTRDIFF_MAX __PTRDIFF_MAX__
 
 /* Limits of `sig_atomic_t'.  */
-# define SIG_ATOMIC_MIN		(-2147483647-1)
-# define SIG_ATOMIC_MAX		(2147483647)
+# define SIG_ATOMIC_MIN (-__SIG_ATOMIC_MAX__-1)
+# define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
 
 /* Limit of `size_t' type.  */
-# if __WORDSIZE == 64
-#  define SIZE_MAX		(18446744073709551615UL)
-# else
-#  if __WORDSIZE32_SIZE_ULONG
-#   define SIZE_MAX		(4294967295UL)
-#  else
-#   define SIZE_MAX		(4294967295U)
-#  endif
-# endif
+# define SIZE_MAX __SIZE_MAX__
 
 /* Limits of `wchar_t'.  */
 # ifndef WCHAR_MIN
 /* These constants might also be defined in <wchar.h>.  */
-#  define WCHAR_MIN		__WCHAR_MIN
-#  define WCHAR_MAX		__WCHAR_MAX
+#  define WCHAR_MIN __WCHAR_MIN__
+#  define WCHAR_MAX __WCHAR_MAX__
 # endif
 
 /* Limits of `wint_t'.  */
-# define WINT_MIN		(0u)
-# define WINT_MAX		(4294967295u)
+# define WINT_MIN __WINT_MIN__
+# define WINT_MAX __WINT_MAX__
 
 /* Signed.  */
-# define INT8_C(c)	c
-# define INT16_C(c)	c
-# define INT32_C(c)	c
-# if __WORDSIZE == 64
-#  define INT64_C(c)	c ## L
-# else
-#  define INT64_C(c)	c ## LL
-# endif
+# define INT8_C(c)  __INT8_C(c)
+# define INT16_C(c) __INT16_C(c)
+# define INT32_C(c) __INT32_C(c)
+# define INT64_C(c) __INT64_C(c)
 
 /* Unsigned.  */
-# define UINT8_C(c)	c
-# define UINT16_C(c)	c
-# define UINT32_C(c)	c ## U
-# if __WORDSIZE == 64
-#  define UINT64_C(c)	c ## UL
-# else
-#  define UINT64_C(c)	c ## ULL
-# endif
+# define UINT8_C(c)  __UINT8_C(c)
+# define UINT16_C(c) __UINT16_C(c)
+# define UINT32_C(c) __UINT32_C(c)
+# define UINT64_C(c) __UINT64_C(c)
 
 /* Maximal type.  */
-# if __WORDSIZE == 64
-#  define INTMAX_C(c)	c ## L
-#  define UINTMAX_C(c)	c ## UL
-# else
-#  define INTMAX_C(c)	c ## LL
-#  define UINTMAX_C(c)	c ## ULL
-# endif
+# define INTMAX_C(c)  __INTMAX_C(c)
+# define UINTMAX_C(c) __UINTMAX_C(c)
 
 #if __GLIBC_USE (IEC_60559_BFP_EXT_C23)
 
diff --git a/wrapperhelper/include-override/x86_64/stdc-predef.h b/wrapperhelper/include-override/x86_64/stdc-predef.h
new file mode 100644
index 00000000..0d3228e6
--- /dev/null
+++ b/wrapperhelper/include-override/x86_64/stdc-predef.h
@@ -0,0 +1,405 @@
+// C standard
+#define __STDC__         1
+#define __STDC_HOSTED__  1
+#define __STDC_UTF_16__  1
+#define __STDC_UTF_32__  1
+#define __STDC_VERSION__ 201710L
+// Generic x86_64 infos
+#define __ELF__                 1
+#define __NO_INLINE__           1
+#define __ORDER_BIG_ENDIAN__    4321
+#define __ORDER_LITTLE_ENDIAN__ 1234
+#define __ORDER_PDP_ENDIAN__    3412
+#define __PIC__                 2
+#define __pic__                 2
+#define __PIE__                 2
+#define __pie__                 2
+#define __SSP_STRONG__          3
+#define __USER_LABEL_PREFIX__
+#define __gnu_linux__           1
+#define __linux__               1
+#define __linux                 1
+#define linux                   1
+#define __unix__                1
+#define __unix                  1
+#define unix                    1
+// GCC
+//#define __GCC_ASM_FLAG_OUTPUTS__ 1
+//#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+//#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+//#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+//#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+//#define __GCC_ATOMIC_INT_LOCK_FREE 2
+//#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
+//#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+//#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+//#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+//#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+//#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+//#define __GCC_CONSTRUCTIVE_SIZE 64
+//#define __GCC_DESTRUCTIVE_SIZE 64
+//#define __GCC_HAVE_DWARF2_CFI_ASM 1
+//#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+//#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+//#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+//#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+//#define __GCC_IEC_559 2
+//#define __GCC_IEC_559_COMPLEX 2
+//#define __GNUC__ 14
+//#define __GNUC_EXECUTION_CHARSET_NAME "UTF-8"
+//#define __GNUC_MINOR__ 2
+//#define __GNUC_PATCHLEVEL__ 1
+//#define __GNUC_STDC_INLINE__ 1
+//#define __GNUC_WIDE_EXECUTION_CHARSET_NAME "UTF-32LE"
+//#define __GXX_ABI_VERSION 1019
+//#define __PRAGMA_REDEFINE_EXTNAME 1
+//#define __VERSION__ "14.2.1 20240805"
+// Specific x86_64 architecture
+#define __FXSR__                      1
+#define __FINITE_MATH_ONLY__          0
+#define __HAVE_SPECULATION_SAFE_VALUE 1
+#define __LP64__                      1
+#define _LP64                         1
+#define __MMX__                       1
+#define __MMX_WITH_SSE__              1
+#define __REGISTER_PREFIX__
+#define __SEG_FS                      1
+#define __SEG_GS                      1
+#define __SSE__                       1
+#define __SSE_MATH__                  1
+#define __SSE2__                      1
+#define __SSE2_MATH__                 1
+#define __amd64__                     1
+#define __amd64                       1
+#define __code_model_small__          1
+#define __k8__                        1
+#define __k8                          1
+#define __x86_64__                    1
+#define __x86_64                      1
+// Atomic
+#define __ATOMIC_RELAXED     0
+#define __ATOMIC_CONSUME     1
+#define __ATOMIC_ACQUIRE     2
+#define __ATOMIC_RELEASE     3
+#define __ATOMIC_ACQ_REL     4
+#define __ATOMIC_SEQ_CST     5
+#define __ATOMIC_HLE_ACQUIRE 65536
+#define __ATOMIC_HLE_RELEASE 131072
+// Metainfo on types
+#define __BIGGEST_ALIGNMENT__  16
+#define __BYTE_ORDER__         __ORDER_LITTLE_ENDIAN__
+#define __FLOAT_WORD_ORDER__   __ORDER_LITTLE_ENDIAN__
+#define __CHAR_BIT__           8
+#define __SIZEOF_SHORT__       2
+#define __SIZEOF_WCHAR_T__     4
+#define __SIZEOF_INT__         4
+#define __SIZEOF_WINT_T__      4
+#define __SIZEOF_LONG__        8
+#define __SIZEOF_LONG_LONG__   8
+#define __SIZEOF_POINTER__     8
+#define __SIZEOF_PTRDIFF_T__   8
+#define __SIZEOF_SIZE_T__      8
+#define __SIZEOF_INT128__      16
+#define __SIZEOF_FLOAT__       4
+#define __SIZEOF_DOUBLE__      8
+#define __SIZEOF_LONG_DOUBLE__ 16
+#define __SIZEOF_FLOAT80__     16
+#define __SIZEOF_FLOAT128__    16
+// Integers
+//#define __BITINT_MAXWIDTH__ 65535
+//#define __CHAR16_TYPE__ short unsigned int
+//#define __CHAR32_TYPE__ unsigned int
+#define __INT8_C(c) c
+#define __INT8_MAX__ 0x7f
+//#define __INT8_TYPE__ signed char
+#define __INT16_C(c) c
+#define __INT16_MAX__ 0x7fff
+//#define __INT16_TYPE__ short int
+#define __INT32_C(c) c
+#define __INT32_MAX__ 0x7fffffff
+//#define __INT32_TYPE__ int
+#define __INT64_C(c) c ## L
+#define __INT64_MAX__ 0x7fffffffffffffffL
+//#define __INT64_TYPE__ long int
+#define __INT_FAST8_MAX__ 0x7f
+//#define __INT_FAST8_TYPE__ signed char
+#define __INT_FAST8_WIDTH__ 8
+#define __INT_FAST16_MAX__ 0x7fffffffffffffffL
+//#define __INT_FAST16_TYPE__ long int
+#define __INT_FAST16_WIDTH__ 64
+#define __INT_FAST32_MAX__ 0x7fffffffffffffffL
+//#define __INT_FAST32_TYPE__ long int
+#define __INT_FAST32_WIDTH__ 64
+#define __INT_FAST64_MAX__ 0x7fffffffffffffffL
+//#define __INT_FAST64_TYPE__ long int
+#define __INT_FAST64_WIDTH__ 64
+#define __INT_LEAST8_MAX__ 0x7f
+//#define __INT_LEAST8_TYPE__ signed char
+#define __INT_LEAST8_WIDTH__ 8
+#define __INT_LEAST16_MAX__ 0x7fff
+//#define __INT_LEAST16_TYPE__ short int
+#define __INT_LEAST16_WIDTH__ 16
+#define __INT_LEAST32_MAX__ 0x7fffffff
+//#define __INT_LEAST32_TYPE__ int
+#define __INT_LEAST32_WIDTH__ 32
+#define __INT_LEAST64_MAX__ 0x7fffffffffffffffL
+//#define __INT_LEAST64_TYPE__ long int
+#define __INT_LEAST64_WIDTH__ 64
+#define __INT_MAX__ 0x7fffffff
+#define __INT_WIDTH__ 32
+#define __INTMAX_C(c) c ## L
+#define __INTMAX_MAX__ 0x7fffffffffffffffL
+//#define __INTMAX_TYPE__ long int
+#define __INTMAX_WIDTH__ 64
+#define __INTPTR_MAX__ 0x7fffffffffffffffL
+//#define __INTPTR_TYPE__ long int
+#define __INTPTR_WIDTH__ 64
+#define __LONG_LONG_MAX__ 0x7fffffffffffffffLL
+#define __LONG_LONG_WIDTH__ 64
+#define __LONG_MAX__ 0x7fffffffffffffffL
+#define __LONG_WIDTH__ 64
+#define __PTRDIFF_MAX__ 0x7fffffffffffffffL
+//#define __PTRDIFF_TYPE__ long int
+#define __PTRDIFF_WIDTH__ 64
+#define __SCHAR_MAX__ 0x7f
+#define __SCHAR_WIDTH__ 8
+#define __SHRT_MAX__ 0x7fff
+#define __SHRT_WIDTH__ 16
+#define __SIG_ATOMIC_MAX__ 0x7fffffff
+#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)
+//#define __SIG_ATOMIC_TYPE__ int
+#define __SIG_ATOMIC_WIDTH__ 32
+#define __SIZE_MAX__ 0xffffffffffffffffUL
+//#define __SIZE_TYPE__ long unsigned int
+#define __SIZE_WIDTH__ 64
+#define __UINT8_C(c) c
+#define __UINT8_MAX__ 0xff
+//#define __UINT8_TYPE__ unsigned char
+#define __UINT16_C(c) c
+#define __UINT16_MAX__ 0xffff
+//#define __UINT16_TYPE__ short unsigned int
+#define __UINT32_C(c) c ## U
+#define __UINT32_MAX__ 0xffffffffU
+//#define __UINT32_TYPE__ unsigned int
+#define __UINT64_C(c) c ## UL
+#define __UINT64_MAX__ 0xffffffffffffffffUL
+//#define __UINT64_TYPE__ long unsigned int
+#define __UINT_FAST8_MAX__ 0xff
+//#define __UINT_FAST8_TYPE__ unsigned char
+#define __UINT_FAST16_MAX__ 0xffffffffffffffffUL
+//#define __UINT_FAST16_TYPE__ long unsigned int
+#define __UINT_FAST32_MAX__ 0xffffffffffffffffUL
+//#define __UINT_FAST32_TYPE__ long unsigned int
+#define __UINT_FAST64_MAX__ 0xffffffffffffffffUL
+//#define __UINT_FAST64_TYPE__ long unsigned int
+#define __UINT_LEAST8_MAX__ 0xff
+//#define __UINT_LEAST8_TYPE__ unsigned char
+#define __UINT_LEAST16_MAX__ 0xffff
+//#define __UINT_LEAST16_TYPE__ short unsigned int
+#define __UINT_LEAST32_MAX__ 0xffffffffU
+//#define __UINT_LEAST32_TYPE__ unsigned int
+#define __UINT_LEAST64_MAX__ 0xffffffffffffffffUL
+//#define __UINT_LEAST64_TYPE__ long unsigned int
+#define __UINTMAX_C(c) c ## UL
+#define __UINTMAX_MAX__ 0xffffffffffffffffUL
+//#define __UINTMAX_TYPE__ long unsigned int
+#define __UINTPTR_MAX__ 0xffffffffffffffffUL
+//#define __UINTPTR_TYPE__ long unsigned int
+#define __WCHAR_MAX__ 0x7fffffff
+#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
+//#define __WCHAR_TYPE__ int
+#define __WCHAR_WIDTH__ 32
+#define __WINT_MAX__ 0xffffffffU
+#define __WINT_MIN__ 0U
+//#define __WINT_TYPE__ unsigned int
+#define __WINT_WIDTH__ 32
+// Floats
+//#define __BFLT16_DECIMAL_DIG__ 4
+//#define __BFLT16_DENORM_MIN__ 9.18354961579912115600575419704879436e-41BF16
+//#define __BFLT16_DIG__ 2
+//#define __BFLT16_EPSILON__ 7.81250000000000000000000000000000000e-3BF16
+//#define __BFLT16_HAS_DENORM__ 1
+//#define __BFLT16_HAS_INFINITY__ 1
+//#define __BFLT16_HAS_QUIET_NAN__ 1
+//#define __BFLT16_IS_IEC_60559__ 0
+//#define __BFLT16_MANT_DIG__ 8
+//#define __BFLT16_MAX_10_EXP__ 38
+//#define __BFLT16_MAX__ 3.38953138925153547590470800371487867e+38BF16
+//#define __BFLT16_MAX_EXP__ 128
+//#define __BFLT16_MIN_10_EXP__ (-37)
+//#define __BFLT16_MIN__ 1.17549435082228750796873653722224568e-38BF16
+//#define __BFLT16_MIN_EXP__ (-125)
+//#define __BFLT16_NORM_MAX__ 3.38953138925153547590470800371487867e+38BF16
+#define __DBL_DECIMAL_DIG__ 17
+#define __DBL_DENORM_MIN__ ((double)4.94065645841246544176568792868221372e-324L)
+#define __DBL_DIG__ 15
+#define __DBL_EPSILON__ ((double)2.22044604925031308084726333618164062e-16L)
+#define __DBL_HAS_DENORM__ 1
+#define __DBL_HAS_INFINITY__ 1
+#define __DBL_HAS_QUIET_NAN__ 1
+#define __DBL_IS_IEC_60559__ 1
+#define __DBL_MANT_DIG__ 53
+#define __DBL_MAX_10_EXP__ 308
+#define __DBL_MAX__ ((double)1.79769313486231570814527423731704357e+308L)
+#define __DBL_MAX_EXP__ 1024
+#define __DBL_MIN_10_EXP__ (-307)
+#define __DBL_MIN__ ((double)2.22507385850720138309023271733240406e-308L)
+#define __DBL_MIN_EXP__ (-1021)
+#define __DBL_NORM_MAX__ ((double)1.79769313486231570814527423731704357e+308L)
+//#define __DEC32_EPSILON__ 1E-6DF
+//#define __DEC32_MANT_DIG__ 7
+//#define __DEC32_MAX__ 9.999999E96DF
+//#define __DEC32_MAX_EXP__ 97
+//#define __DEC32_MIN__ 1E-95DF
+//#define __DEC32_MIN_EXP__ (-94)
+//#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF
+//#define __DEC64_EPSILON__ 1E-15DD
+//#define __DEC64_MANT_DIG__ 16
+//#define __DEC64_MAX__ 9.999999999999999E384DD
+//#define __DEC64_MAX_EXP__ 385
+//#define __DEC64_MIN__ 1E-383DD
+//#define __DEC64_MIN_EXP__ (-382)
+//#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
+//#define __DEC128_EPSILON__ 1E-33DL
+//#define __DEC128_MANT_DIG__ 34
+//#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
+//#define __DEC128_MAX_EXP__ 6145
+//#define __DEC128_MIN__ 1E-6143DL
+//#define __DEC128_MIN_EXP__ (-6142)
+//#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
+//#define __DEC_EVAL_METHOD__ 2
+//#define __DECIMAL_BID_FORMAT__ 1
+//#define __DECIMAL_DIG__ 21
+//#define __FLT16_DECIMAL_DIG__ 5
+//#define __FLT16_DENORM_MIN__ 5.96046447753906250000000000000000000e-8F16
+//#define __FLT16_DIG__ 3
+//#define __FLT16_EPSILON__ 9.76562500000000000000000000000000000e-4F16
+//#define __FLT16_HAS_DENORM__ 1
+//#define __FLT16_HAS_INFINITY__ 1
+//#define __FLT16_HAS_QUIET_NAN__ 1
+//#define __FLT16_IS_IEC_60559__ 1
+//#define __FLT16_MANT_DIG__ 11
+//#define __FLT16_MAX_10_EXP__ 4
+//#define __FLT16_MAX__ 6.55040000000000000000000000000000000e+4F16
+//#define __FLT16_MAX_EXP__ 16
+//#define __FLT16_MIN_10_EXP__ (-4)
+//#define __FLT16_MIN__ 6.10351562500000000000000000000000000e-5F16
+//#define __FLT16_MIN_EXP__ (-13)
+//#define __FLT16_NORM_MAX__ 6.55040000000000000000000000000000000e+4F16
+//#define __FLT32_DECIMAL_DIG__ 9
+//#define __FLT32_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F32
+//#define __FLT32_DIG__ 6
+//#define __FLT32_EPSILON__ 1.19209289550781250000000000000000000e-7F32
+//#define __FLT32_HAS_DENORM__ 1
+//#define __FLT32_HAS_QUIET_NAN__ 1
+//#define __FLT32_HAS_INFINITY__ 1
+//#define __FLT32_IS_IEC_60559__ 1
+//#define __FLT32_MAX_10_EXP__ 38
+//#define __FLT32_MAX__ 3.40282346638528859811704183484516925e+38F32
+//#define __FLT32_MAX_EXP__ 128
+//#define __FLT32_MIN_10_EXP__ (-37)
+//#define __FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32
+//#define __FLT32_MIN_EXP__ (-125)
+//#define __FLT32_MANT_DIG__ 24
+//#define __FLT32_NORM_MAX__ 3.40282346638528859811704183484516925e+38F32
+//#define __FLT32X_DECIMAL_DIG__ 17
+//#define __FLT32X_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F32x
+//#define __FLT32X_DIG__ 15
+//#define __FLT32X_EPSILON__ 2.22044604925031308084726333618164062e-16F32x
+//#define __FLT32X_HAS_DENORM__ 1
+//#define __FLT32X_HAS_INFINITY__ 1
+//#define __FLT32X_HAS_QUIET_NAN__ 1
+//#define __FLT32X_IS_IEC_60559__ 1
+//#define __FLT32X_MANT_DIG__ 53
+//#define __FLT32X_MAX_10_EXP__ 308
+//#define __FLT32X_MAX__ 1.79769313486231570814527423731704357e+308F32x
+//#define __FLT32X_MAX_EXP__ 1024
+//#define __FLT32X_MIN_10_EXP__ (-307)
+//#define __FLT32X_MIN__ 2.22507385850720138309023271733240406e-308F32x
+//#define __FLT32X_MIN_EXP__ (-1021)
+//#define __FLT32X_NORM_MAX__ 1.79769313486231570814527423731704357e+308F32x
+//#define __FLT64_DECIMAL_DIG__ 17
+//#define __FLT64_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F64
+//#define __FLT64_DIG__ 15
+//#define __FLT64_EPSILON__ 2.22044604925031308084726333618164062e-16F64
+//#define __FLT64_HAS_DENORM__ 1
+//#define __FLT64_HAS_INFINITY__ 1
+//#define __FLT64_HAS_QUIET_NAN__ 1
+//#define __FLT64_IS_IEC_60559__ 1
+//#define __FLT64_MANT_DIG__ 53
+//#define __FLT64_MAX_10_EXP__ 308
+//#define __FLT64_MAX__ 1.79769313486231570814527423731704357e+308F64
+//#define __FLT64_MAX_EXP__ 1024
+//#define __FLT64_MIN_10_EXP__ (-307)
+//#define __FLT64_MIN__ 2.22507385850720138309023271733240406e-308F64
+//#define __FLT64_MIN_EXP__ (-1021)
+//#define __FLT64_NORM_MAX__ 1.79769313486231570814527423731704357e+308F64
+//#define __FLT64X_DECIMAL_DIG__ 21
+//#define __FLT64X_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951F64x
+//#define __FLT64X_DIG__ 18
+//#define __FLT64X_EPSILON__ 1.08420217248550443400745280086994171e-19F64x
+//#define __FLT64X_HAS_DENORM__ 1
+//#define __FLT64X_HAS_INFINITY__ 1
+//#define __FLT64X_HAS_QUIET_NAN__ 1
+//#define __FLT64X_IS_IEC_60559__ 1
+//#define __FLT64X_MANT_DIG__ 64
+//#define __FLT64X_MAX_10_EXP__ 4932
+//#define __FLT64X_MAX__ 1.18973149535723176502126385303097021e+4932F64x
+//#define __FLT64X_MAX_EXP__ 16384
+//#define __FLT64X_MIN_10_EXP__ (-4931)
+//#define __FLT64X_MIN__ 3.36210314311209350626267781732175260e-4932F64x
+//#define __FLT64X_MIN_EXP__ (-16381)
+//#define __FLT64X_NORM_MAX__ 1.18973149535723176502126385303097021e+4932F64x
+//#define __FLT128_DECIMAL_DIG__ 36
+//#define __FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128
+//#define __FLT128_DIG__ 33
+//#define __FLT128_EPSILON__ 1.92592994438723585305597794258492732e-34F128
+//#define __FLT128_HAS_DENORM__ 1
+//#define __FLT128_HAS_INFINITY__ 1
+//#define __FLT128_HAS_QUIET_NAN__ 1
+//#define __FLT128_IS_IEC_60559__ 1
+//#define __FLT128_MANT_DIG__ 113
+//#define __FLT128_MAX__ 1.18973149535723176508575932662800702e+4932F128
+//#define __FLT128_MAX_10_EXP__ 4932
+//#define __FLT128_MAX_EXP__ 16384
+//#define __FLT128_MIN_10_EXP__ (-4931)
+//#define __FLT128_MIN__ 3.36210314311209350626267781732175260e-4932F128
+//#define __FLT128_MIN_EXP__ (-16381)
+//#define __FLT128_NORM_MAX__ 1.18973149535723176508575932662800702e+4932F128
+#define __FLT_DECIMAL_DIG__ 9
+#define __FLT_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F
+#define __FLT_DIG__ 6
+#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F
+#define __FLT_EVAL_METHOD__ 0
+#define __FLT_EVAL_METHOD_TS_18661_3__ 0
+#define __FLT_HAS_DENORM__ 1
+#define __FLT_HAS_INFINITY__ 1
+#define __FLT_HAS_QUIET_NAN__ 1
+#define __FLT_IS_IEC_60559__ 1
+#define __FLT_MANT_DIG__ 24
+#define __FLT_MAX_10_EXP__ 38
+#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F
+#define __FLT_MAX_EXP__ 128
+#define __FLT_MIN_10_EXP__ (-37)
+#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F
+#define __FLT_MIN_EXP__ (-125)
+#define __FLT_NORM_MAX__ 3.40282346638528859811704183484516925e+38F
+#define __FLT_RADIX__ 2
+#define __LDBL_DECIMAL_DIG__ 21
+#define __LDBL_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951L
+#define __LDBL_DIG__ 18
+#define __LDBL_EPSILON__ 1.08420217248550443400745280086994171e-19L
+#define __LDBL_HAS_DENORM__ 1
+#define __LDBL_HAS_INFINITY__ 1
+#define __LDBL_HAS_QUIET_NAN__ 1
+#define __LDBL_IS_IEC_60559__ 1
+#define __LDBL_MANT_DIG__ 64
+#define __LDBL_MAX_10_EXP__ 4932
+#define __LDBL_MAX__ 1.18973149535723176502126385303097021e+4932L
+#define __LDBL_MAX_EXP__ 16384
+#define __LDBL_MIN_10_EXP__ (-4931)
+#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+#define __LDBL_MIN_EXP__ (-16381)
+#define __LDBL_NORM_MAX__ 1.18973149535723176502126385303097021e+4932L
+
+#include_next "stdc-predef.h"
diff --git a/wrapperhelper/src/generator.c b/wrapperhelper/src/generator.c
index 63102f48..33ace369 100644
--- a/wrapperhelper/src/generator.c
+++ b/wrapperhelper/src/generator.c
@@ -9,7 +9,6 @@ static const char *rft2str[8] = {
 	[RQT_FUN_MY] = " (my)",
 	[RQT_FUN_D] = " (D)",
 	[RQT_DATA] = "",
-	[RQT_DATAV] = " (V)",
 	[RQT_DATAB] = " (B)",
 	[RQT_DATAM] = " (my)",
 };
@@ -34,7 +33,6 @@ void request_print(const request_t *req) {
 		}
 		break;
 	case RQT_DATA:
-	case RQT_DATAV:
 	case RQT_DATAB:
 	case RQT_DATAM:
 		if (req->def.dat.has_size) {
@@ -62,7 +60,6 @@ void request_print(const request_t *req) {
 			}
 			break;
 		case RQT_DATA:
-		case RQT_DATAV:
 		case RQT_DATAB:
 		case RQT_DATAM:
 			if (req->val.dat.has_size) {
@@ -124,7 +121,6 @@ void request_print_check(const request_t *req) {
 		}
 		break;
 	case RQT_DATA:
-	case RQT_DATAV:
 	case RQT_DATAB:
 	case RQT_DATAM:
 		similar = 1;
@@ -170,7 +166,6 @@ static void request_del(request_t *req) {
 	case RQT_FUN_MY: if (req->def.fun.typ) string_del(req->def.fun.typ);                                                       break;
 	case RQT_FUN_D:  if (req->def.fun.typ) string_del(req->def.fun.typ); if (req->def.fun.fun2) string_del(req->def.fun.fun2); break;
 	case RQT_DATA:   break;
-	case RQT_DATAV:  break;
 	case RQT_DATAB:  break;
 	case RQT_DATAM:  break;
 	}
@@ -181,7 +176,6 @@ static void request_del(request_t *req) {
 		case RQT_FUN_MY: string_del(req->val.fun.typ);                                break;
 		case RQT_FUN_D:  string_del(req->val.fun.typ); string_del(req->val.fun.fun2); break;
 		case RQT_DATA:   break;
-		case RQT_DATAV:  break;
 		case RQT_DATAB:  break;
 		case RQT_DATAM:  break;
 		}
@@ -218,7 +212,6 @@ static const char *rqt_suffix[8] = {
 	[RQT_FUN_MY] = "M",
 	[RQT_FUN_D] = "D",
 	[RQT_DATA] = "",
-	[RQT_DATAV] = "V",
 	[RQT_DATAB] = "B",
 	[RQT_DATAM] = "M",
 };
@@ -245,14 +238,14 @@ static void request_output(FILE *f, const request_t *req) {
 			if (req->def.dat.has_size) {
 				fprintf(f, "%sDATA%s%s(%s, %zu)%s\n",
 					req->default_comment ? "//" : "",
-					req->weak ? "W" : "",
+					req->weak ? "V" : "",
 					rqt_suffix[req->def.rty],
 					string_content(req->obj_name),
 					req->def.dat.sz,
 					(req->ignored || req->default_comment) ? "" : " // Warning: failed to confirm");
 			} else {
 				fprintf(f, "//DATA%s%s(%s, \n",
-					req->weak ? "W" : "",
+					req->weak ? "V" : "",
 					rqt_suffix[req->def.rty],
 					string_content(req->obj_name));
 			}
@@ -273,13 +266,15 @@ static void request_output(FILE *f, const request_t *req) {
 		} else {
 			if (req->val.dat.has_size) {
 				int is_comment = IS_RQT_FUNCTION(req->def.rty) || !req->def.dat.has_size || req->default_comment || (req->def.rty != req->val.rty);
-				fprintf(f, "%sDATA%s(%s, %zu)\n",
+				fprintf(f, "%sDATA%s%s(%s, %zu)\n",
 					is_comment ? "//" : "",
+					req->weak ? "V" : "",
 					rqt_suffix[req->val.rty],
 					string_content(req->obj_name),
 					req->val.dat.sz);
 			} else {
-				fprintf(f, "//DATA%s(%s, \n",
+				fprintf(f, "//DATA%s%s(%s, \n",
+					req->weak ? "V" : "",
 					rqt_suffix[req->val.rty],
 					string_content(req->obj_name));
 			}
@@ -584,17 +579,17 @@ VECTOR(references) *references_from_file(const char *filename, FILE *f) {
 		         || !strcmp(string_content(tok.tokv.str), "DATAM"))) {
 			string_clear(line);
 			if (is_comment) prepare_mark_nocomment(prep);
+			int isweak = (string_content(tok.tokv.str)[4] == 'V');
 			request_t req = {
 				.default_comment = is_comment,
 				.has_val = 0,
 				.ignored = 0,
 				.obj_name = NULL,
-				.weak = (string_content(tok.tokv.str)[4] == 'V'),
+				.weak = isweak,
 				.def = {
 					.rty =
-						(string_content(tok.tokv.str)[4] == 'V') ? RQT_DATAV :
-						(string_content(tok.tokv.str)[4] == 'B') ? RQT_DATAB :
-						(string_content(tok.tokv.str)[4] == 'M') ? RQT_DATAM : RQT_DATA,
+						(string_content(tok.tokv.str)[isweak ? 5 : 4] == 'B') ? RQT_DATAB :
+						(string_content(tok.tokv.str)[isweak ? 5 : 4] == 'M') ? RQT_DATAM : RQT_DATA,
 					.dat.has_size = 0,
 					.dat.sz = 0,
 				},
@@ -751,7 +746,9 @@ static int is_simple_type(type_t *typ, int *needs_D, int *needs_my) {
 	}
 	switch (typ->typ) {
 	case TYPE_BUILTIN:
-		return 1; // Assume pointers to builtin are simple
+		return (typ->val.builtin != BTT_FLOAT128)
+		    && (typ->val.builtin != BTT_CFLOAT128)
+		    && (typ->val.builtin != BTT_IFLOAT128); // Assume builtin are simple except for __float128
 	case TYPE_ARRAY:
 		if (typ->val.array.array_sz == (size_t)-1) return 0; // VLA are not simple
 		return is_simple_type_ptr_to(typ->val.array.typ, needs_D, needs_my);
@@ -837,6 +834,9 @@ static int convert_type(string_t *dest, type_t *typ, int is_ret, int *needs_D, i
 		case BTT_LONGDOUBLE: *needs_D = 1; has_char = 1; c = 'D'; break;
 		case BTT_CLONGDOUBLE: *needs_D = 1; has_char = 1; c = 'Y'; break;
 		case BTT_ILONGDOUBLE: *needs_D = 1; has_char = 1; c = 'D'; break;
+		case BTT_FLOAT128: printf("Error: TODO: %s\n", builtin2str[typ->val.builtin]); has_char = 0; break;
+		case BTT_CFLOAT128: printf("Error: TODO: %s\n", builtin2str[typ->val.builtin]); has_char = 0; break;
+		case BTT_IFLOAT128: printf("Error: TODO: %s\n", builtin2str[typ->val.builtin]); has_char = 0; break;
 		case BTT_VA_LIST: *needs_my = 1; has_char = 1; c = 'A'; break;
 		default:
 			printf("Error: convert_type on unknown builtin %u\n", typ->val.builtin);
@@ -1043,7 +1043,7 @@ int solve_request(request_t *req, type_t *typ) {
 		int needs_D = 0, needs_my = req->def.dat.has_size && (req->def.rty == RQT_DATAM);
 		if (is_simple_type(typ, &needs_D, &needs_my)) {
 			// TODO: Hmm...
-			req->val.rty = needs_my ? RQT_DATAM : req->def.dat.has_size ? req->def.rty : req->weak ? RQT_DATAV : RQT_DATA;
+			req->val.rty = needs_my ? RQT_DATAM : req->def.rty;
 			req->val.dat.has_size = 1;
 			req->val.dat.sz = typ->szinfo.size;
 			req->has_val = 1;
diff --git a/wrapperhelper/src/generator.h b/wrapperhelper/src/generator.h
index 5e08577d..8e892f0e 100644
--- a/wrapperhelper/src/generator.h
+++ b/wrapperhelper/src/generator.h
@@ -21,7 +21,6 @@ typedef struct request_s {
 			RQT_FUN_D,
 			
 			RQT_DATA,
-			RQT_DATAV,
 			RQT_DATAB,
 			RQT_DATAM,
 		} rty;
diff --git a/wrapperhelper/src/lang.c b/wrapperhelper/src/lang.c
index 78cc66c1..65c8c742 100644
--- a/wrapperhelper/src/lang.c
+++ b/wrapperhelper/src/lang.c
@@ -233,6 +233,7 @@ const char *kw2str[LAST_KEYWORD + 1] = {
 	[KW_ENUM] = "enum",
 	[KW_EXTERN] = "extern",
 	[KW_FLOAT] = "float",
+	[KW_FLOAT128] = "__float128",
 	[KW_FOR] = "for",
 	[KW_GENERIC] = "_Generic",
 	[KW_GOTO] = "goto",
@@ -963,6 +964,9 @@ const char *builtin2str[LAST_BUILTIN + 1] = {
 	[BTT_LONGDOUBLE] = "long double",
 	[BTT_CLONGDOUBLE] = "long double _Complex",
 	[BTT_ILONGDOUBLE] = "long double _Imaginary",
+	[BTT_FLOAT128] = "__float128",
+	[BTT_CFLOAT128] = "__float128 _Complex",
+	[BTT_IFLOAT128] = "__float128 _Imaginary",
 	[BTT_VA_LIST] = "__builtin_va_list",
 };
 void type_print(type_t *typ) {
diff --git a/wrapperhelper/src/lang.h b/wrapperhelper/src/lang.h
index f5807f97..9611df82 100644
--- a/wrapperhelper/src/lang.h
+++ b/wrapperhelper/src/lang.h
@@ -108,6 +108,7 @@ enum token_keyword_type_e {
 	KW_ENUM,
 	KW_EXTERN,
 	KW_FLOAT,
+	KW_FLOAT128,
 	KW_FOR,
 	KW_GENERIC,
 	KW_GOTO,
@@ -350,6 +351,9 @@ typedef struct type_s {
 			BTT_LONGDOUBLE,
 			BTT_CLONGDOUBLE,
 			BTT_ILONGDOUBLE,
+			BTT_FLOAT128,
+			BTT_CFLOAT128,
+			BTT_IFLOAT128,
 			BTT_VA_LIST,
 		} builtin;
 #define LAST_BUILTIN BTT_VA_LIST
diff --git a/wrapperhelper/src/machine.c b/wrapperhelper/src/machine.c
index d20c3e1f..9b54df7a 100644
--- a/wrapperhelper/src/machine.c
+++ b/wrapperhelper/src/machine.c
@@ -1,6 +1,8 @@
 #include "machine.h"
 
-#include "preproc_private.h"
+#include <stdio.h>
+
+#include "lang.h"
 
 machine_t machine_x86_64;
 // machine_t machine_x86;
@@ -11,92 +13,35 @@ machine_t machine_x86_64;
 #define STRINGIFY2(a) #a
 #define STRINGIFY(a) STRINGIFY2(a)
 #define MACHINE_STR STRINGIFY(CUR_MACHINE)
-#define INIT_PATHS \
-	PASTE(machine_, CUR_MACHINE).npaths = 1 + npaths;
-#define INCR_NPATHS(_path) \
-	++PASTE(machine_, CUR_MACHINE).npaths;
-#define DO_PATHS \
-	if (!(PASTE(machine_, CUR_MACHINE).include_path =                                                                \
-	      malloc(PASTE(machine_, CUR_MACHINE).npaths * sizeof *PASTE(machine_, CUR_MACHINE).include_path))) {        \
-		printf("Failed to add include path to " MACHINE_STR " platform\n");                                          \
-		goto PASTE(failed_, PASTE(CUR_MACHINE, _nopath));                                                            \
-	}                                                                                                                \
-	failure_id = 0;                                                                                                  \
-	ADD_PATH("include-fixed")                                                                                        \
-	for (; failure_id < npaths + 1; ++failure_id) {                                                                  \
-		if (!(PASTE(machine_, CUR_MACHINE).include_path[failure_id] = strdup(extra_include_path[failure_id - 1]))) { \
-			printf("Failed to add include path to " MACHINE_STR " platform\n");                                      \
-			goto PASTE(failed_, PASTE(CUR_MACHINE, _paths));                                                         \
-		}                                                                                                            \
-	}
+
+#define PATHS_OFFSET_PRE 2 // There are two paths that are always included before any other
 #define ADD_PATH(path) \
 	if (!(PASTE(machine_, CUR_MACHINE).include_path[failure_id] = strdup(path))) { \
 		printf("Failed to add include path to " MACHINE_STR " platform\n");        \
 		goto PASTE(failed_, PASTE(CUR_MACHINE, _paths));                           \
 	}                                                                              \
 	++failure_id;
-#define EXTRA_MACROS \
-	PASTE(machine_, CUR_MACHINE).npredefs = PASTE(CUR_MACHINE, _NPREDEFS);                                       \
-	if (!(PASTE(machine_, CUR_MACHINE).predef_macros_name =                                                      \
-	      malloc((PASTE(CUR_MACHINE, _NPREDEFS)) * sizeof *PASTE(machine_, CUR_MACHINE).predef_macros_name))) {  \
-		printf("Failed to add predefined macro to " MACHINE_STR " platform\n");                                  \
-		goto PASTE(failed_, PASTE(CUR_MACHINE, _paths));                                                         \
-	}                                                                                                            \
-	if (!(PASTE(machine_, CUR_MACHINE).predef_macros =                                                           \
-	      malloc((PASTE(CUR_MACHINE, _NPREDEFS)) * sizeof *PASTE(machine_, CUR_MACHINE).predef_macros))) {       \
-		printf("Failed to add predefined macro to " MACHINE_STR " platform\n");                                  \
-		free(machine_x86_64.predef_macros_name);                                                                 \
-		goto PASTE(failed_, PASTE(CUR_MACHINE, _paths));                                                         \
-	}                                                                                                            \
-	failure_id = 0;
-#define ADD_NAME(mname) \
-	if (!(PASTE(machine_, CUR_MACHINE).predef_macros_name[failure_id] = strdup(#mname))) { \
-		printf("Failed to add predefined macro to " MACHINE_STR " platform\n");            \
-		goto PASTE(failed_, PASTE(CUR_MACHINE, _macros));                                  \
-	}
-#define ADD_MACRO(ntoks) \
-	if (!(PASTE(machine_, CUR_MACHINE).predef_macros[failure_id] =                   \
-	      malloc(sizeof *PASTE(machine_, CUR_MACHINE).predef_macros[failure_id]))) { \
-		printf("Failed to add predefined macro to " MACHINE_STR " platform\n");      \
-		free(machine_x86_64.predef_macros_name[failure_id]);                         \
-		goto PASTE(failed_, PASTE(CUR_MACHINE, _macros));                            \
-	}                                                                                \
-	*PASTE(machine_, CUR_MACHINE).predef_macros[failure_id] = (macro_t){             \
-		.is_funlike = 0,                                                             \
-		.has_varargs = 0,                                                            \
-		.nargs = 0,                                                                  \
-		.toks = vector_new_cap(mtoken, (ntoks)),                                     \
-	};                                                                               \
-	++failure_id;                                                                    \
-	if (!PASTE(machine_, CUR_MACHINE).predef_macros[failure_id - 1]->toks) {         \
-		printf("Failed to add predefined macro to " MACHINE_STR " platform\n");      \
-		goto PASTE(failed_, PASTE(CUR_MACHINE, _macros));                            \
+#define INIT_PATHS \
+	PASTE(machine_, CUR_MACHINE).npaths = PATHS_OFFSET_PRE + npaths + paths_offset_post;                      \
+	if (!(PASTE(machine_, CUR_MACHINE).include_path =                                                         \
+	      malloc(PASTE(machine_, CUR_MACHINE).npaths * sizeof *PASTE(machine_, CUR_MACHINE).include_path))) { \
+		printf("Failed to add include path to " MACHINE_STR " platform\n");                                   \
+		goto PASTE(failed_, PASTE(CUR_MACHINE, _nopath));                                                     \
+	}                                                                                                         \
+	failure_id = 0;                                                                                           \
+	ADD_PATH("include-override/" MACHINE_STR)                                                                 \
+	ADD_PATH("include-override/common")                                                                       \
+	while (failure_id < PATHS_OFFSET_PRE + npaths) {                                                          \
+		ADD_PATH(extra_include_path[failure_id - PATHS_OFFSET_PRE])                                           \
 	}
-#define ADD_SYM(s) \
-	mtok = mtoken_new_token((preproc_token_t){.tokt = PPTOK_SYM, .tokv.sym = SYM_ ## s}); \
-	if (!mtok) {                                                                          \
-		printf("Failed to add predefined macro to " MACHINE_STR " platform\n");           \
-		goto PASTE(failed_, PASTE(CUR_MACHINE, _macros));                                 \
-	}                                                                                     \
-	vector_push(mtoken, PASTE(machine_, CUR_MACHINE).predef_macros[failure_id - 1]->toks, mtok);
-#define ADD_STR(typ, n) \
-	s = string_new_cstr(#n);                                                          \
-	if (!s) {                                                                         \
-		printf("Failed to add predefined macro to " MACHINE_STR " platform\n");       \
-		goto PASTE(failed_, PASTE(CUR_MACHINE, _macros));                             \
-	}                                                                                 \
-	mtok = mtoken_new_token((preproc_token_t){.tokt = PPTOK_ ## typ, .tokv.str = s}); \
-	if (!mtok) {                                                                      \
-		printf("Failed to add predefined macro to " MACHINE_STR " platform\n");       \
-		string_del(s);                                                                \
-		goto PASTE(failed_, PASTE(CUR_MACHINE, _macros));                             \
-	}                                                                                 \
-	vector_push(mtoken, PASTE(machine_, CUR_MACHINE).predef_macros[failure_id - 1]->toks, mtok);
 
 int init_machines(size_t npaths, const char *const *extra_include_path) {
 	size_t failure_id;
-	string_t *s;
-	mtoken_t *mtok;
+	
+	size_t paths_offset_post = 0;
+#define DO_PATH(_path) ++paths_offset_post;
+#include "machine.gen"
+#undef DO_PATH
 	
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
@@ -105,60 +50,14 @@ int init_machines(size_t npaths, const char *const *extra_include_path) {
 	machine_x86_64.align_valist = 8;
 	machine_x86_64.size_valist = 24;
 	INIT_PATHS
-#define DO_PATH INCR_NPATHS
-#include "machine.gen"
-#undef DO_PATH
-	DO_PATHS
 #define DO_PATH ADD_PATH
 #include "machine.gen"
 #undef DO_PATH
-#define x86_64_NPREDEFS 9
-	EXTRA_MACROS
-	ADD_NAME(__x86_64__)
-	ADD_MACRO(1)
-	ADD_STR(NUM, 1)
-	ADD_NAME(__WCHAR_MAX__)
-	ADD_MACRO(1)
-	ADD_STR(NUM, 2147483647)
-	ADD_NAME(__WCHAR_MIN__)
-	ADD_MACRO(5)
-	ADD_SYM(LPAREN)
-	ADD_SYM(DASH)
-	ADD_STR(IDENT, __WCHAR_MAX__)
-	ADD_SYM(DASH)
-	ADD_STR(NUM, 1)
-	ADD_NAME(__CHAR_BIT__)
-	ADD_MACRO(1)
-	ADD_STR(NUM, 8)
-	ADD_NAME(__SCHAR_MAX__)
-	ADD_MACRO(1)
-	ADD_STR(NUM, 127)
-	ADD_NAME(__SHRT_MAX__)
-	ADD_MACRO(1)
-	ADD_STR(NUM, 32767)
-	ADD_NAME(__INT_MAX__)
-	ADD_MACRO(1)
-	ADD_STR(NUM, 2147483647)
-	ADD_NAME(__LONG_MAX__)
-	ADD_MACRO(1)
-	ADD_STR(NUM, 9223372036854775807L)
-	ADD_NAME(__LONG_LONG_MAX__)
-	ADD_MACRO(1)
-	ADD_STR(NUM, 9223372036854775807LL)
 #undef CUR_MACHINE
 #pragma GCC diagnostic pop
 	
 	return 1;
 	
-failed_x86_64_macros:
-	while (failure_id--) {
-		macro_del(machine_x86_64.predef_macros[failure_id]);
-		free(machine_x86_64.predef_macros[failure_id]);
-		free(machine_x86_64.predef_macros_name[failure_id]);
-	}
-	free(machine_x86_64.predef_macros);
-	free(machine_x86_64.predef_macros_name);
-	failure_id = machine_x86_64.npaths;
 failed_x86_64_paths:
 	while (failure_id--) {
 		free(machine_x86_64.include_path[failure_id]);
@@ -169,13 +68,6 @@ failed_x86_64_nopath:
 }
 
 static void machine_del(machine_t *m) {
-	for (size_t predef_id = m->npredefs; predef_id--;) {
-		macro_del(m->predef_macros[predef_id]);
-		free(m->predef_macros[predef_id]);
-		free(m->predef_macros_name[predef_id]);
-	}
-	free(m->predef_macros);
-	free(m->predef_macros_name);
 	for (size_t path_no = m->npaths; path_no--;) {
 		free(m->include_path[path_no]);
 	}
@@ -242,8 +134,11 @@ int validate_type(machine_t *target, type_t *typ) {
 		case BTT_CDOUBLE:     typ->szinfo.align = typ->szinfo.size = 16; break;
 		case BTT_IDOUBLE:     typ->szinfo.align = typ->szinfo.size = 8; break;
 		case BTT_LONGDOUBLE:  typ->szinfo.align = typ->szinfo.size = 16; break;
-		case BTT_CLONGDOUBLE: typ->szinfo.align = typ->szinfo.size = 32; break;
+		case BTT_CLONGDOUBLE: typ->szinfo.align = 16; typ->szinfo.size = 32; break;
 		case BTT_ILONGDOUBLE: typ->szinfo.align = typ->szinfo.size = 16; break;
+		case BTT_FLOAT128:    typ->szinfo.align = typ->szinfo.size = 16; break;
+		case BTT_CFLOAT128:   typ->szinfo.align = 16; typ->szinfo.size = 32; break;
+		case BTT_IFLOAT128:   typ->szinfo.align = typ->szinfo.size = 16; break;
 		case BTT_VA_LIST:     typ->szinfo.align = target->align_valist; typ->szinfo.size = target->size_valist; break;
 		default:
 			printf("Unknown builtin %u, cannot fill size info\n", typ->val.builtin);
@@ -288,11 +183,12 @@ int validate_type(machine_t *target, type_t *typ) {
 		if (typ->val.fun.nargs != (size_t)-1) {
 			for (size_t i = 0; i < typ->val.fun.nargs; ++i) {
 				// Adjust the argument if necessary
+				// Assume arrays are already converted
 				if (typ->val.fun.args[i]->typ == TYPE_ARRAY) {
-					// Adjustment to pointer
-					typ->val.fun.args[i]->typ = TYPE_PTR;
-					typ->val.fun.args[i]->val.typ = typ->val.fun.args[i]->val.array.typ;
-				} else if (typ->val.fun.args[i]->typ == TYPE_FUNCTION) {
+					printf("Error: function argument %zu is an array\n", i + 1);
+					return 0;
+				}
+				if (typ->val.fun.args[i]->typ == TYPE_FUNCTION) {
 					// Adjustment to pointer
 					type_t *t2 = type_new_ptr(typ->val.fun.args[i]);
 					if (!t2) {
@@ -390,7 +286,10 @@ int validate_type(machine_t *target, type_t *typ) {
 		typ->szinfo.size = (cur_sz + max_align - 1) & ~(max_align - 1);
 		return 1; }
 	case TYPE_ENUM:
-		if (typ->val.typ->typ != TYPE_BUILTIN) return 0;
+		if (typ->val.typ->typ != TYPE_BUILTIN) {
+			printf("Error: the underlying type of an enum is not a builtin type\n");
+			return 0;
+		}
 		typ->szinfo = typ->val.typ->szinfo;
 		return 1;
 	}
diff --git a/wrapperhelper/src/machine.h b/wrapperhelper/src/machine.h
index 5570a4af..b5a5b0ea 100644
--- a/wrapperhelper/src/machine.h
+++ b/wrapperhelper/src/machine.h
@@ -7,7 +7,6 @@
 #include "khash.h"
 #include "vector.h"
 
-struct macro_s; // preproc_private.h
 struct type_s;  // lang.h
 
 typedef struct machine_s {
@@ -15,10 +14,6 @@ typedef struct machine_s {
 	size_t npaths;
 	char **include_path;
 	
-	size_t npredefs;
-	char **predef_macros_name;
-	struct macro_s **predef_macros;
-	
 	// Parsing
 	size_t size_long;
 	size_t align_valist, size_valist;
diff --git a/wrapperhelper/src/parse.c b/wrapperhelper/src/parse.c
index 8b56cb15..b1f9ed90 100644
--- a/wrapperhelper/src/parse.c
+++ b/wrapperhelper/src/parse.c
@@ -398,6 +398,7 @@ static int is_type_spec_qual_kw(enum token_keyword_type_e kw) {
 		(kw == KW_DOUBLE)    ||
 		(kw == KW_ENUM)      ||
 		(kw == KW_FLOAT)     ||
+		(kw == KW_FLOAT128)  ||
 		(kw == KW_IMAGINARY) ||
 		(kw == KW_INT)       ||
 		(kw == KW_INT128)    ||
@@ -1064,7 +1065,7 @@ failed:
 	if (e) expr_del(e);
 	return NULL;
 }
-static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constant_t *dest) {
+static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constant_t *dest, int fatal) {
 	// Evaluate the expression (we suppose it is constant)
 	switch (e->typ) {
 	case ETY_VAR: {
@@ -1073,7 +1074,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 			*dest = kh_val(const_map, it);
 			return 1;
 		}
-		printf("Error: failed to evaluate expression: expression is not constant (variable)\n");
+		if (fatal) printf("Error: failed to evaluate expression: expression is not constant (variable)\n");
 		return 0; }
 		
 	case ETY_CONST:
@@ -1083,18 +1084,18 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 	// case ETY_GENERIC:
 		
 	case ETY_CALL:
-		printf("Error: failed to evaluate expression: expression is not constant (function call)\n");
+		if (fatal) printf("Error: failed to evaluate expression: expression is not constant (function call)\n");
 		return 0;
 		
 	case ETY_ACCESS:
 	case ETY_PTRACCESS:
-		printf("Error: failed to evaluate expression: expression is not constant (member access)\n");
+		if (fatal) printf("Error: failed to evaluate expression: expression is not constant (member access)\n");
 		return 0;
 		
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wfloat-equal"
 	case ETY_UNARY:
-		if (!eval_expression(e->val.unary.e, const_map, dest)) return 0;
+		if (!eval_expression(e->val.unary.e, const_map, dest, fatal)) return 0;
 		
 		switch (e->val.unary.typ) {
 		case UOT_POSTINCR:
@@ -1103,7 +1104,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 		case UOT_PREDECR:
 		case UOT_REF:
 		case UOT_DEREF:
-			printf("Error: failed to evaluate expression: expression is not constant (assignment or memory accesses)\n");
+			if (fatal) printf("Error: failed to evaluate expression: expression is not constant (assignment or memory accesses)\n");
 			return 0;
 		case UOT_POS:
 			return 1; // Nothing to do
@@ -1123,7 +1124,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 			case NCT_FLOAT:
 			case NCT_DOUBLE:
 			case NCT_LDOUBLE:
-				printf("Error: failed to evaluate expression: cannot bitwise-negate a floating point number\n");
+				if (fatal) printf("Error: failed to evaluate expression: cannot bitwise-negate a floating point number\n");
 				return 0;
 			case NCT_INT32:  dest->val.i32 = ~dest->val.i32; return 1;
 			case NCT_UINT32: dest->val.u32 = ~dest->val.u32; return 1;
@@ -1147,8 +1148,8 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 		
 	case ETY_BINARY: {
 		num_constant_t dest1, dest2;
-		if (!eval_expression(e->val.binary.e1, const_map, &dest1)) return 0;
-		if (!eval_expression(e->val.binary.e2, const_map, &dest2)) return 0;
+		if (!eval_expression(e->val.binary.e1, const_map, &dest1, fatal)) return 0;
+		if (!eval_expression(e->val.binary.e2, const_map, &dest2, fatal)) return 0;
 		
 		switch (e->val.binary.typ) {
 		case BOT_ASSGN_EQ:
@@ -1163,7 +1164,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 		case BOT_ASSGN_AXOR:
 		case BOT_ASSGN_AOR:
 		case BOT_ARRAY: // Is this possible?
-			printf("Error: failed to evaluate expression: expression is not constant (assignments)\n");
+			if (fatal) printf("Error: failed to evaluate expression: expression is not constant (assignments)\n");
 			return 0;
 #define DOIT(op) \
 			promote_csts(&dest1, &dest2); \
@@ -1183,7 +1184,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 			case NCT_FLOAT: \
 			case NCT_DOUBLE: \
 			case NCT_LDOUBLE: \
-				printf("Error: failed to evaluate expression: binary operation %u incompatible with floating point numbers\n", e->val.binary.typ); \
+				if (fatal) printf("Error: failed to evaluate expression: binary operation %u incompatible with floating point numbers\n", e->val.binary.typ); \
 				return 0; \
 			case NCT_INT32:   dest->val.i32 = dest1.val.i32 op dest2.val.i32; return 1; \
 			case NCT_UINT32:  dest->val.u32 = dest1.val.u32 op dest2.val.u32; return 1; \
@@ -1230,9 +1231,9 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 		
 	case ETY_TERNARY: {
 		num_constant_t dest1, dest2, dest3;
-		if (!eval_expression(e->val.ternary.e1, const_map, &dest1)) return 0;
-		if (!eval_expression(e->val.ternary.e2, const_map, &dest2)) return 0;
-		if (!eval_expression(e->val.ternary.e3, const_map, &dest3)) return 0;
+		if (!eval_expression(e->val.ternary.e1, const_map, &dest1, fatal)) return 0;
+		if (!eval_expression(e->val.ternary.e2, const_map, &dest2, fatal)) return 0;
+		if (!eval_expression(e->val.ternary.e3, const_map, &dest3, fatal)) return 0;
 		
 		switch (e->val.ternary.typ) {
 		case TOT_COND:
@@ -1254,7 +1255,7 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 	// case ETY_INIT_LIST:
 		
 	case ETY_CAST:
-		if (!eval_expression(e->val.cast.e, const_map, dest)) return 0;
+		if (!eval_expression(e->val.cast.e, const_map, dest, fatal)) return 0;
 		
 		if (e->val.cast.typ->typ == TYPE_BUILTIN) {
 			switch (e->val.cast.typ->val.builtin) {
@@ -1340,13 +1341,16 @@ static int eval_expression(expr_t *e, khash_t(const_map) *const_map, num_constan
 			case BTT_LONGDOUBLE:
 			case BTT_CLONGDOUBLE:
 			case BTT_ILONGDOUBLE:
+			case BTT_FLOAT128:
+			case BTT_CFLOAT128:
+			case BTT_IFLOAT128:
 			case BTT_VA_LIST:
 			default:
-				printf("Error: TODO: cast to builtin %s in constant expression\n", builtin2str[e->val.cast.typ->val.builtin]);
+				if (fatal) printf("Error: TODO: cast to builtin %s in constant expression\n", builtin2str[e->val.cast.typ->val.builtin]);
 				return 0;
 			}
 		} else {
-			printf("Error: cast in constant expression\n");
+			if (fatal) printf("Error: cast in constant expression\n");
 			return 0;
 		}
 		
@@ -1382,7 +1386,7 @@ static int parse_declaration_specifier(machine_t *target, khash_t(struct_map) *s
 			goto failed;
 		}
 		num_constant_t eval;
-		if (!eval_expression(e, const_map, &eval)) {
+		if (!eval_expression(e, const_map, &eval, 1)) {
 			expr_del(e);
 			// Empty destructor
 			goto failed;
@@ -1567,6 +1571,8 @@ parse_cur_token_decl:
 			*spec = SPEC_LONGCOMPLEX;
 		} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_FLOAT)) {
 			typ->val.builtin = BTT_CFLOAT;
+		} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_FLOAT128)) {
+			typ->val.builtin = BTT_CFLOAT128;
 		} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_DOUBLE)) {
 			typ->val.builtin = BTT_CDOUBLE;
 		} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_LONGDOUBLE)) {
@@ -1584,6 +1590,8 @@ parse_cur_token_decl:
 			*spec = SPEC_LONGIMAGINARY;
 		} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_FLOAT)) {
 			typ->val.builtin = BTT_IFLOAT;
+		} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_FLOAT128)) {
+			typ->val.builtin = BTT_IFLOAT128;
 		} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_DOUBLE)) {
 			typ->val.builtin = BTT_IDOUBLE;
 		} else if ((*spec == SPEC_BUILTIN) && (typ->val.builtin == BTT_LONGDOUBLE)) {
@@ -1643,6 +1651,25 @@ parse_cur_token_decl:
 		}
 		*tok = proc_next_token(prep);
 		goto parse_cur_token_decl;
+	} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_FLOAT128)) {
+		if (*spec == SPEC_NONE) {
+			*spec = SPEC_BUILTIN;
+			typ->typ = TYPE_BUILTIN;
+			typ->val.builtin = BTT_FLOAT128;
+		} else if (*spec == SPEC_COMPLEX) {
+			*spec = SPEC_BUILTIN;
+			typ->typ = TYPE_BUILTIN;
+			typ->val.builtin = BTT_CFLOAT128;
+		} else if (*spec == SPEC_IMAGINARY) {
+			*spec = SPEC_BUILTIN;
+			typ->typ = TYPE_BUILTIN;
+			typ->val.builtin = BTT_IFLOAT128;
+		} else {
+			printf("Error: unexpected type specifier '%s' in declaration\n", kw2str[tok->tokv.kw]);
+			goto failed;
+		}
+		*tok = proc_next_token(prep);
+		goto parse_cur_token_decl;
 	} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_CHAR)) {
 		SPEC_SIGNED(CHAR, 0)
 	} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_INT)) {
@@ -2058,7 +2085,7 @@ parse_cur_token_decl:
 					proc_token_del(tok);
 					goto failed;
 				}
-				if (!eval_expression(e, const_map, &cst)) {
+				if (!eval_expression(e, const_map, &cst, 1)) {
 					expr_del(e);
 					if (tag) string_del(tag);
 					// Empty destructor
@@ -2203,6 +2230,7 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
 	int has_list = 0, has_ident = 0;
 	// TODO: allow_abstract and 'direct-abstract-declarator(opt) ( parameter-type-list(opt) )'
 	
+	_Bool array_atomic = 0, array_const = 0, array_restrict = 0, array_static = 0, array_volatile = 0;
 	string_t *cur_ident = NULL;
 	type_t *typ = base_type; ++typ->nrefs;
 	type_t *cur_bottom = NULL;
@@ -2324,6 +2352,27 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
 							}
 							if ((tok->tokt == PTOK_SYM) && (tok->tokv.sym == SYM_RPAREN)) {
 								// Unnamed argument
+								if (typ2->typ == TYPE_ARRAY) {
+									// Need to convert type to a pointer
+									type_t *typ3 = type_new();
+									if (!typ3) {
+										printf("Error: failed to allocate new type\n");
+										type_del(typ2);
+										// Empty destructor
+										goto failed;
+									}
+									if (!type_copy_into(typ3, typ2)) {
+										printf("Error: failed to duplicate array type to temporary type\n");
+										type_del(typ3);
+										type_del(typ2);
+										// Empty destructor
+										goto failed;
+									}
+									type_del(typ2);
+									typ3->typ = TYPE_PTR;
+									typ3->val.typ = typ3->val.array.typ;
+									typ2 = type_try_merge(typ3, PDECL_TYPE_SET);
+								}
 								if (!vector_push(types, args, typ2)) {
 									printf("Error: failed to add argument to argument vector\n");
 									vector_del(types, args);
@@ -2452,23 +2501,76 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
 					}
 					has_ident = 1;
 				}
+				if (array_atomic || array_const || array_restrict || array_static || array_volatile) {
+					printf("Error: invalid array after array with type qualifier(s) and/or 'static'\n");
+					// Empty destructor
+					goto failed;
+				}
 				// Empty destructor
 				*tok = proc_next_token(prep);
-				// Here we have only two array constructors:
-				//  direct-declaration [ assignment-expression(opt) ]
-				//  direct-declaration [ * ]   (complete VLA)
+				// From the standard:
+				//   direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ]
+				//   direct-declarator [ static type-qualifier-list(opt) assignment-expression ]
+				//   direct-declarator [ type-qualifier-list static assignment-expression ]
+				//   direct-declarator [ type-qualifier-list(opt) * ]
+				//  The optional type qualifiers and the keyword static shall appear only in a
+				//  declaration of a function parameter with an array type, and then only in the outermost
+				//  array type derivation.
 				size_t nelems; _Bool is_incomplete;
+				while (1) {
+#define DO_CHECKS \
+	if (is_init || is_list || !allow_decl || (cur_bottom && (typ->typ != TYPE_ARRAY))) {                         \
+		printf("Error: type qualifiers and 'static' may only appear in function argument array declarations\n"); \
+		/* Empty destructor */                                                                                   \
+		goto failed;                                                                                             \
+	}
+					if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_ATOMIC)) {
+						DO_CHECKS
+						array_atomic = 1;
+						*tok = proc_next_token(prep);
+					} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_CONST)) {
+						DO_CHECKS
+						array_const = 1;
+						*tok = proc_next_token(prep);
+					} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_RESTRICT)) {
+						DO_CHECKS
+						array_restrict = 1;
+						*tok = proc_next_token(prep);
+					} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_STATIC)) {
+						DO_CHECKS
+						array_static = 1;
+						*tok = proc_next_token(prep);
+					} else if ((tok->tokt == PTOK_KEYWORD) && (tok->tokv.kw == KW_VOLATILE)) {
+						DO_CHECKS
+						array_volatile = 1;
+						*tok = proc_next_token(prep);
+					} else break;
+#undef DO_CHECKS
+				}
 				if ((tok->tokt == PTOK_SYM) && (tok->tokv.sym == SYM_RSQBRACKET)) {
+					if (array_static) {
+						// Missing expression
+						printf("Error: unexpected token ']' in static length array declaration\n");
+						// Empty destructor
+						goto failed;
+					}
 					// Incomplete VLA
 					nelems = (size_t)-1;
 					is_incomplete = 1;
 				} else if ((tok->tokt == PTOK_SYM) && (tok->tokv.sym == SYM_STAR)) {
+					if (array_static) {
+						// Missing expression
+						printf("Error: unexpected token '*' in static length array declaration\n");
+						// Empty destructor
+						goto failed;
+					}
 					// Complete VLA, expecting a ']'
 					nelems = (size_t)-1;
 					is_incomplete = 0;
 					// Empty destructor
 					*tok = proc_next_token(prep);
 					if ((tok->tokt != PTOK_SYM) || (tok->tokv.sym != SYM_RSQBRACKET)) {
+						// TODO: ...[*expr]
 						printf("Error: unexpected token during variable length array declaration\n");
 						proc_token_del(tok);
 						goto failed;
@@ -2488,27 +2590,32 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
 						goto failed;
 					}
 					num_constant_t cst;
-					if (!eval_expression(e, PDECL_CONST_MAP, &cst)) {
+					if (eval_expression(e, PDECL_CONST_MAP, &cst, is_init || is_list || !allow_decl)) {
 						expr_del(e);
-						// Empty destructor
-						goto failed;
-					}
-					expr_del(e);
-					int is_neg;
-					switch (cst.typ) {
-					case NCT_FLOAT:   is_neg = cst.val.f < 0; nelems = (size_t)cst.val.f; break;
-					case NCT_DOUBLE:  is_neg = cst.val.d < 0; nelems = (size_t)cst.val.d; break;
-					case NCT_LDOUBLE: is_neg = cst.val.l < 0; nelems = (size_t)cst.val.l; break;
-					case NCT_INT32:   is_neg = cst.val.i32 < 0; nelems = (size_t)cst.val.i32; break;
-					case NCT_UINT32:  is_neg = 0; nelems = (size_t)cst.val.u32; break;
-					case NCT_INT64:   is_neg = cst.val.i64 < 0; nelems = (size_t)cst.val.i64; break;
-					case NCT_UINT64:  is_neg = 0; nelems = (size_t)cst.val.u64; break;
-					default: is_neg = 1;
-					}
-					if (is_neg) {
-						printf("Error: the size of an array must be nonnegative");
-						// Empty destructor
-						goto failed;
+						int is_neg;
+						switch (cst.typ) {
+						case NCT_FLOAT:   is_neg = cst.val.f < 0; nelems = (size_t)cst.val.f; break;
+						case NCT_DOUBLE:  is_neg = cst.val.d < 0; nelems = (size_t)cst.val.d; break;
+						case NCT_LDOUBLE: is_neg = cst.val.l < 0; nelems = (size_t)cst.val.l; break;
+						case NCT_INT32:   is_neg = cst.val.i32 < 0; nelems = (size_t)cst.val.i32; break;
+						case NCT_UINT32:  is_neg = 0; nelems = (size_t)cst.val.u32; break;
+						case NCT_INT64:   is_neg = cst.val.i64 < 0; nelems = (size_t)cst.val.i64; break;
+						case NCT_UINT64:  is_neg = 0; nelems = (size_t)cst.val.u64; break;
+						default: is_neg = 1;
+						}
+						if (is_neg) {
+							printf("Error: the size of an array must be nonnegative");
+							// Empty destructor
+							goto failed;
+						}
+					} else {
+						expr_del(e);
+						// Treated as '*' as function argument (TODO: as anything else)
+						if (is_init || is_list || !allow_decl) {
+							// Empty destructor
+							goto failed;
+						}
+						nelems = (size_t)-1;
 					}
 				}
 				// Token is ']'
@@ -2713,6 +2820,32 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
 							kh_val(dest->f->decl_map, it) = typ;
 						}
 					} else if (!is_init && !is_list) {
+						if (allow_decl) {
+							// Function argument
+							if (typ->typ == TYPE_ARRAY) {
+								// Convert to pointer
+								if (typ == base_type) {
+									typ = type_new();
+									if (!typ) {
+										printf("Error: failed to allocate new type\n");
+										// Empty destructor
+										goto failed;
+									}
+									if (!type_copy_into(typ, base_type)) {
+										printf("Error: failed to allocate new type\n");
+										// Empty destructor
+										goto failed;
+									}
+								}
+								typ->typ = TYPE_PTR;
+								typ->val.typ = typ->val.array.typ;
+								if (array_atomic)   typ->is_atomic   = 1;
+								if (array_const)    typ->is_const    = 1;
+								if (array_restrict) typ->is_restrict = 1;
+								if (array_volatile) typ->is_volatile = 1;
+								typ = type_try_merge(typ, PDECL_TYPE_SET);
+							}
+						}
 						dest->argt.dest = typ;
 						if (cur_ident) string_del(cur_ident);
 						goto success;
@@ -2802,7 +2935,7 @@ static int parse_declarator(machine_t *target, struct parse_declarator_dest_s *d
 					goto failed;
 				}
 				num_constant_t eval;
-				if (!eval_expression(e, dest->structms.const_map, &eval)) {
+				if (!eval_expression(e, dest->structms.const_map, &eval, 1)) {
 					expr_del(e);
 					// Empty destructor
 					goto failed;
@@ -3067,9 +3200,13 @@ file_t *parse_file(machine_t *target, const char *filename, FILE *file) {
 			if (spec == SPEC_NONE) continue; // Declaration was an assert, typ is unchanged
 			typ = type_try_merge(typ, ret->type_set);
 			if ((tok.tokt != PTOK_SYM) || (tok.tokv.sym != SYM_SEMICOLON)) {
-				if (!parse_declarator(target, &(struct parse_declarator_dest_s){.f = ret}, prep, &tok, storage, fspec, typ, 1, 1, 1, 0)) goto failed;
+				if (!parse_declarator(target, &(struct parse_declarator_dest_s){.f = ret}, prep, &tok, storage, fspec, typ, 1, 1, 1, 0)) {
+					goto failed;
+				}
 			} else {
-				if (validate_storage_type(target, storage, typ, tok.tokv.sym) != VALIDATION_LAST_DECL) goto failed;
+				if (validate_storage_type(target, storage, typ, tok.tokv.sym) != VALIDATION_LAST_DECL) {
+					goto failed;
+				}
 				if (fspec != FSPEC_NONE) {
 					printf("Error: unexpected function specifier\n");
 					// Empty destructor
diff --git a/wrapperhelper/src/preproc.c b/wrapperhelper/src/preproc.c
index f402d82a..0f67762a 100644
--- a/wrapperhelper/src/preproc.c
+++ b/wrapperhelper/src/preproc.c
@@ -1,7 +1,6 @@
 // I think this file is too big for GCC to handle properly, there are curious false-positive analyzer warnings
 //  that didn't appear before adding preproc_eval
 #include "preproc.h"
-#include "preproc_private.h"
 
 #include <stdint.h>
 #include <string.h>
@@ -11,6 +10,39 @@
 #include "machine.h"
 #include "prepare.h"
 
+typedef struct mtoken_s {
+	enum mtoken_e {
+		MTOK_TOKEN,
+		MTOK_ARG,
+		MTOK_STRINGIFY,
+		MTOK_CONCAT,
+	} typ;
+	union {
+		preproc_token_t tok;
+		unsigned argid;
+		struct { struct mtoken_s *l, *r; } concat;
+	} val;
+} mtoken_t;
+static void mtoken_del(mtoken_t *tok) {
+	switch (tok->typ) {
+	case MTOK_TOKEN:
+		preproc_token_del(&tok->val.tok);
+		free(tok);
+		return;
+		
+	case MTOK_CONCAT:
+		mtoken_del(tok->val.concat.l);
+		mtoken_del(tok->val.concat.r);
+		free(tok);
+		return;
+		
+	case MTOK_ARG:
+	case MTOK_STRINGIFY:
+		free(tok);
+		return;
+	}
+}
+
 KHASH_MAP_INIT_STR(argid_map, unsigned)
 static void argid_map_del(khash_t(argid_map) *args) {
 	kh_cstr_t str;
@@ -20,21 +52,21 @@ static void argid_map_del(khash_t(argid_map) *args) {
 #pragma GCC diagnostic pop
 	kh_destroy(argid_map, args);
 }
-mtoken_t *mtoken_new_token(preproc_token_t tok) {
+static mtoken_t *mtoken_new_token(preproc_token_t tok) {
 	mtoken_t *ret = malloc(sizeof *ret);
 	if (!ret) return NULL;
 	ret->typ = MTOK_TOKEN;
 	ret->val.tok = tok;
 	return ret;
 }
-mtoken_t *mtoken_new_arg(unsigned argid, int as_string) {
+static mtoken_t *mtoken_new_arg(unsigned argid, int as_string) {
 	mtoken_t *ret = malloc(sizeof *ret);
 	if (!ret) return NULL;
 	ret->typ = as_string ? MTOK_STRINGIFY : MTOK_ARG;
 	ret->val.argid = argid;
 	return ret;
 }
-mtoken_t *mtoken_new_concat(mtoken_t *l, mtoken_t *r) { // Takes ownership of l and r
+static mtoken_t *mtoken_new_concat(mtoken_t *l, mtoken_t *r) { // Takes ownership of l and r
 	mtoken_t *ret = malloc(sizeof *ret);
 	if (!ret) {
 		mtoken_del(l);
@@ -46,48 +78,6 @@ mtoken_t *mtoken_new_concat(mtoken_t *l, mtoken_t *r) { // Takes ownership of l
 	ret->val.concat.r = r;
 	return ret;
 }
-void mtoken_del(mtoken_t *tok) {
-	switch (tok->typ) {
-	case MTOK_TOKEN:
-		preproc_token_del(&tok->val.tok);
-		free(tok);
-		return;
-		
-	case MTOK_CONCAT:
-		mtoken_del(tok->val.concat.l);
-		mtoken_del(tok->val.concat.r);
-		free(tok);
-		return;
-		
-	case MTOK_ARG:
-	case MTOK_STRINGIFY:
-		free(tok);
-		return;
-	}
-}
-mtoken_t *mtoken_dup(mtoken_t *src) {
-	switch (src->typ) {
-	case MTOK_TOKEN:
-		return mtoken_new_token(preproc_token_dup(src->val.tok));
-		
-	case MTOK_ARG:
-		return mtoken_new_arg(src->val.argid, 0);
-		
-	case MTOK_STRINGIFY:
-		return mtoken_new_arg(src->val.argid, 1);
-		
-	case MTOK_CONCAT: {
-		mtoken_t *l = mtoken_dup(src->val.concat.l);
-		if (!l) return NULL;
-		mtoken_t *r = mtoken_dup(src->val.concat.r);
-		if (!r) {
-			mtoken_del(l);
-			return NULL;
-		}
-		return mtoken_new_concat(l, r); }
-	}
-	return NULL;
-}
 
 static inline void print_macro_tok(mtoken_t *m) {
 	switch (m->typ) {
@@ -116,13 +106,21 @@ static inline void print_macro_tok(mtoken_t *m) {
 	}
 }
 
+VECTOR_DECLARE_STATIC(mtoken, mtoken_t*)
 #define mtoken_ptr_del(m) mtoken_del(*(m))
-VECTOR_IMPL(mtoken, mtoken_ptr_del)
+VECTOR_IMPL_STATIC(mtoken, mtoken_ptr_del)
 #undef mtoken_ptr_del
 
+typedef struct macro_s {
+	int is_funlike;
+	int has_varargs;
+	unsigned nargs;
+	VECTOR(mtoken) *toks;
+} macro_t;
+
 KHASH_MAP_INIT_STR(macros_map, macro_t)
 KHASH_SET_INIT_STR(string_set)
-void macro_del(macro_t *m) {
+static void macro_del(macro_t *m) {
 	vector_del(mtoken, m->toks);
 }
 static void macros_map_del(khash_t(macros_map) *args) {
@@ -143,32 +141,6 @@ static void macros_set_del(khash_t(string_set) *strset) {
 	kh_destroy(string_set, strset);
 }
 
-VECTOR(mtoken) *mtokens_dup(const VECTOR(mtoken) *src) {
-	VECTOR(mtoken) *ret = vector_new_cap(mtoken, vector_size(mtoken, src));
-	if (!ret) return NULL;
-	vector_for(mtoken, mtok, src) {
-		mtoken_t *mtok2 = mtoken_dup(*mtok);
-		if (!mtok2) {
-			vector_del(mtoken, ret);
-			return NULL;
-		}
-		if (!vector_push(mtoken, ret, mtok2)) {
-			mtoken_del(mtok2);
-			vector_del(mtoken, ret);
-			return NULL;
-		}
-	}
-	return ret;
-}
-int macro_dup(macro_t *dest, const macro_t *src) {
-	dest->is_funlike = src->is_funlike;
-	dest->has_varargs = src->has_varargs;
-	dest->nargs = src->nargs;
-	dest->toks = mtokens_dup(src->toks);
-	if (!dest->toks) return 0;
-	return 1;
-}
-
 typedef struct ppsource_s {
 	enum ppsrc_e {
 		PPSRC_PREPARE = 0,
@@ -275,6 +247,64 @@ static preproc_token_t ppsrc_next_token(preproc_t *src) {
 	}
 }
 
+static int try_open_dir(preproc_t *src, string_t *filename) {
+	size_t fnlen = string_len(filename);
+	size_t incl_len = src->dirname ? strlen(src->dirname) : 1;
+	char *fn = malloc(incl_len + fnlen + 2);
+	if (!fn) return 0;
+	if (src->dirname) {
+		memcpy(fn, src->dirname, incl_len);
+		fn[incl_len] = '/';
+	} else {
+		fn[0] = '.';
+		fn[1] = '/';
+	}
+	strcpy(fn + incl_len + 1, string_content(filename));
+	FILE *f = fopen(fn, "r");
+	// printf("Trying %s: %p\n", fn, f);
+	int ret;
+	if (f) {
+		char *new_dirname = strchr(fn, '/') ? strndup(fn, (size_t)(strrchr(fn, '/') - fn)) : NULL;
+		ret = vector_push(ppsource, src->prep, PREPARE_NEW_FILE(f, fn, src->cur_file, src->dirname, src->is_sys, src->cur_pathno));
+		if (ret) {
+			src->is_sys = 0;
+			src->cur_file = fn;
+			src->dirname = new_dirname;
+			src->cur_pathno = 0;
+		}
+	} else {
+		free(fn);
+		ret = 0;
+	}
+	return ret;
+}
+static int try_open_sys(preproc_t *src, string_t *filename, size_t array_off) {
+	size_t fnlen = string_len(filename);
+	for (; array_off < src->target->npaths; ++array_off) {
+		size_t incl_len = strlen(src->target->include_path[array_off]);
+		char *fn = malloc(incl_len + fnlen + 2);
+		if (!fn) return 0;
+		memcpy(fn, src->target->include_path[array_off], incl_len);
+		fn[incl_len] = '/';
+		strcpy(fn + incl_len + 1, string_content(filename));
+		FILE *f = fopen(fn, "r");
+		// printf("Trying %s: %p\n", fn, f);
+		if (f) {
+			char *new_dirname = strchr(fn, '/') ? strndup(fn, (size_t)(strrchr(fn, '/') - fn)) : NULL;
+			int ret = vector_push(ppsource, src->prep, PREPARE_NEW_FILE(f, fn, src->cur_file, src->dirname, src->is_sys, src->cur_pathno));
+			if (ret) {
+				src->is_sys = 1;
+				src->cur_file = fn;
+				src->dirname = new_dirname;
+				src->cur_pathno = array_off + 1;
+			}
+			return ret;
+		}
+		free(fn);
+	}
+	return 0;
+}
+
 preproc_t *preproc_new_file(machine_t *target, FILE *f, char *dirname, const char *filename) {
 	preproc_t *ret = malloc(sizeof *ret);
 	if (!ret) {
@@ -316,42 +346,7 @@ preproc_t *preproc_new_file(machine_t *target, FILE *f, char *dirname, const cha
 	ret->cur_file = NULL;
 	// ret can now be deleted by preproc_del
 	
-	// First add predefined macros
-	for (size_t i = 0; i < target->npredefs; ++i) {
-		// NL and EOF have empty destructors
-		khiter_t kh_k;
-		int iret;
-		char *mname_dup = strdup(target->predef_macros_name[i]);
-		if (!mname_dup) {
-			printf("Error: failed to initialize preprocessor (predefined macros), aborting\n");
-			preproc_del(ret);
-			return NULL;
-		}
-		kh_k = kh_put(string_set, ret->macros_defined, mname_dup, &iret);
-		// TODO: check iret?
-		if (iret >= 1) {
-			mname_dup = strdup(mname_dup);
-		}
-		kh_k = kh_put(macros_map, ret->macros_map, mname_dup, &iret);
-		if (iret < 0) {
-			printf("Error: failed to initialize preprocessor (predefined macros), aborting\n");
-			preproc_del(ret);
-			return NULL;
-		} else if (iret == 0) {
-			printf("Error: duplicated predefined macros, aborting\n");
-			preproc_del(ret);
-			return NULL;
-		}
-		if (!macro_dup(&kh_val(ret->macros_map, kh_k), target->predef_macros[i])) {
-			printf("Error: failed to initialize preprocessor (predefined macros), aborting\n");
-			free(mname_dup);
-			kh_del(macros_map, ret->macros_map, kh_k);
-			preproc_del(ret);
-			return NULL;
-		}
-	}
-	
-	// Next include the first file
+	// Include the first file
 	if (!vector_push(ppsource, ret->prep, PREPARE_NEW_FILE(f, filename, NULL, NULL, 0, 0))) {
 		preproc_del(ret);
 		return NULL;
@@ -360,72 +355,30 @@ preproc_t *preproc_new_file(machine_t *target, FILE *f, char *dirname, const cha
 		preproc_del(ret);
 		return NULL;
 	}
-	// Last finish setting up ret
+	// Next finish setting up ret
 	ret->st = PPST_NL;
 	ret->is_sys = 0;
 	ret->dirname = dirname;
 	ret->cur_file = strdup(filename);
 	ret->cur_pathno = 0;
-	return ret;
-}
-
-static int try_open_dir(preproc_t *src, string_t *filename) {
-	size_t fnlen = string_len(filename);
-	size_t incl_len = src->dirname ? strlen(src->dirname) : 1;
-	char *fn = malloc(incl_len + fnlen + 2);
-	if (!fn) return 0;
-	if (src->dirname) {
-		memcpy(fn, src->dirname, incl_len);
-		fn[incl_len] = '/';
-	} else {
-		fn[0] = '.';
-		fn[1] = '/';
+	
+	// Also include 'stdc-predef.h' (it will be parsed before the requested file)
+	string_t *stdc_predef = string_new_cstr("stdc-predef.h");
+	if (!stdc_predef) {
+		printf("Error: failed to create new string 'stdc-predef.h'\n");
+		preproc_del(ret);
+		return NULL;
 	}
-	strcpy(fn + incl_len + 1, string_content(filename));
-	FILE *f = fopen(fn, "r");
-	// printf("Trying %s: %p\n", fn, f);
-	int ret;
-	if (f) {
-		char *new_dirname = strchr(fn, '/') ? strndup(fn, (size_t)(strrchr(fn, '/') - fn)) : NULL;
-		ret = vector_push(ppsource, src->prep, PREPARE_NEW_FILE(f, fn, src->cur_file, src->dirname, src->is_sys, src->cur_pathno));
-		if (ret) {
-			src->is_sys = 0;
-			src->cur_file = fn;
-			src->dirname = new_dirname;
-			src->cur_pathno = 0;
-		}
-	} else {
-		free(fn);
-		ret = 0;
+	if (!try_open_sys(ret, stdc_predef, 0)) {
+		printf("Error: failed to open file 'stdc-predef.h'\n");
+		string_del(stdc_predef);
+		preproc_del(ret);
+		return NULL;
 	}
+	string_del(stdc_predef);
+	
 	return ret;
 }
-static int try_open_sys(preproc_t *src, string_t *filename, size_t array_off) {
-	size_t fnlen = string_len(filename);
-	for (; array_off < src->target->npaths; ++array_off) {
-		size_t incl_len = strlen(src->target->include_path[array_off]);
-		char *fn = malloc(incl_len + fnlen + 2);
-		if (!fn) return 0;
-		memcpy(fn, src->target->include_path[array_off], incl_len);
-		fn[incl_len] = '/';
-		strcpy(fn + incl_len + 1, string_content(filename));
-		FILE *f = fopen(fn, "r");
-		// printf("Trying %s: %p\n", fn, f);
-		if (f) {
-			char *new_dirname = strchr(fn, '/') ? strndup(fn, (size_t)(strrchr(fn, '/') - fn)) : NULL;
-			int ret = vector_push(ppsource, src->prep, PREPARE_NEW_FILE(f, fn, src->cur_file, src->dirname, src->is_sys, src->cur_pathno));
-			if (ret) {
-				src->is_sys = 1;
-				src->cur_file = fn;
-				src->dirname = new_dirname;
-				src->cur_pathno = array_off + 1;
-			}
-			return ret;
-		}
-		free(fn);
-	}
-	return 0;
-}
 
 static void preprocs_del(VECTOR(preproc) **p) {
 	if (!*p) return;
@@ -446,8 +399,7 @@ static VECTOR(preproc) *
 	// May change margs if m->has_varargs, but takes no ownership
 	// opt_used_macros is NULL in regular expansion, non-NULL in #if-expansions
 
-static VECTOR(preproc) *
-proc_solve_macro(const khash_t(macros_map) *macros, char *mname, const macro_t *m, VECTOR(preprocs) *margs,
+static VECTOR(preproc) *proc_solve_macro(const khash_t(macros_map) *macros, char *mname, const macro_t *m, VECTOR(preprocs) *margs,
                  khash_t(string_set) *solved_macros, khash_t(string_set) *opt_used_macros) {
 	if (m->is_funlike && !margs) {
 		printf("<internal error: m->is_funlike && !margs>\n");
@@ -3132,6 +3084,7 @@ start_cur_token:
 		if ((vector_last(ppsource, src->prep).srct == PPSRC_PREPARE) && vector_last(ppsource, src->prep).srcv.prep.cond_depth) {
 			printf("Error: file ended before closing all conditionals (ignoring)\n");
 		}
+		// printf("Closing %s\n", src->cur_file);
 		if (vector_last(ppsource, src->prep).srct == PPSRC_PREPARE) {
 			if (src->dirname) free(src->dirname);
 			if (src->cur_file) free(src->cur_file);
diff --git a/wrapperhelper/src/preproc_private.h b/wrapperhelper/src/preproc_private.h
deleted file mode 100644
index d1b5f804..00000000
--- a/wrapperhelper/src/preproc_private.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-#ifndef PREPROC_PRIVATE_H
-#define PREPROC_PRIVATE_H
-
-#include <stdio.h>
-
-#include "lang.h"
-
-typedef struct mtoken_s {
-	enum mtoken_e {
-		MTOK_TOKEN,
-		MTOK_ARG,
-		MTOK_STRINGIFY,
-		MTOK_CONCAT,
-	} typ;
-	union {
-		preproc_token_t tok;
-		unsigned argid;
-		struct { struct mtoken_s *l, *r; } concat;
-	} val;
-} mtoken_t;
-
-VECTOR_DECLARE(mtoken, mtoken_t*)
-
-typedef struct macro_s {
-	int is_funlike;
-	int has_varargs;
-	unsigned nargs;
-	VECTOR(mtoken) *toks;
-} macro_t;
-
-mtoken_t *mtoken_new_token(preproc_token_t tok);
-mtoken_t *mtoken_new_arg(unsigned argid, int as_string);
-mtoken_t *mtoken_new_concat(mtoken_t *l, mtoken_t *r);
-void mtoken_del(mtoken_t *tok);
-void macro_del(macro_t *m);
-
-#endif // PREPROC_PRIVATE_H