This implementation of a preprocessor based in part on ISO/IEC 9899:TC2.
- PHP >= 7.4
Library is available as composer repository and can be installed using the following command in a root of your project.
$ composer require ffi/preprocessoruse FFI\Preprocessor\Preprocessor;
$pre = new Preprocessor();
echo $pre->process('
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE)
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
#else
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
#endif
#endif
VK_DEFINE_HANDLE(VkInstance)
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
');
//
// Expected Output:
//
// typedef struct VkInstance_T* VkInstance;
// typedef uint64_t VkSemaphore;
//-
#include "file.h"local-first include -
#include <file.h>global-first include -
#define namedefining directives-
#define name valueobject-like macro -
#define name(arg) valuefunction-like macro -
#define name(arg) xxx##argconcatenation -
#define name(arg) #argstringizing
-
-
#undef nameremoving directives -
#ifdef name"if directive defined" condition -
#ifndef name"if directive not defined" condition -
#if EXPRESSIONif condition -
#elif EXPRESSIONelse if condition -
#elseelse condition -
#endifcompletion of a condition -
#error messageerror message directive -
#warning messagewarning message directive -
#line 66 "filename"line and file override -
#pragma XXXcompiler control-
#pragma once
-
-
#assert XXXcompiler assertion-
#unassert XXXcompiler assertion
-
-
#ident XXX-
#sccs XXX
-
-
A > Bgreater than -
A < Bless than -
A == Bequal -
A != Bnot equal -
A >= Bgreater than or equal -
A <= Bless than or equal
-
! Alogical NOT -
A && Bconjunction -
A || Bdisjunction -
(...)grouping
-
A + Bmath addition -
A - Bmath subtraction -
A * Bmath multiplication -
A / Bmath division -
A % Bmodulo -
A++increment-
++Aprefix form
-
-
A--decrement-
--Aprefix form
-
-
+Aunary plus -
-Aunary minus -
&Aunary addr -
*Aunary pointer
-
~Abitwise NOT -
A & Bbitwise AND -
A | Bbitwise OR -
A ^ Bbitwise XOR -
A << Bbitwise left shift -
A >> Bbitwise right shift
-
defined(X)defined macro -
A ? B : Cternary -
sizeof VALUEsizeof-
sizeof(TYPE)sizeof type
-
-
true,falseboolean -
42decimal integer literal-
42u,42Uunsigned int -
42l,42Llong int -
42ul,42ULunsigned long int -
42ll,42LLlong long int -
42ull,42ULLunsigned long long int
-
-
042octal integer literal -
0x42hexadecimal integer literal -
0b42binary integer literal -
"string"string (char array)-
L"string"string (wide char array) -
"\•"escape sequences in strings -
"\•••"arbitrary octal value in strings -
"\X••"arbitrary hexadecimal value in strings
-
-
'x'char literal-
'\•'escape sequences -
'\•••'arbitrary octal value -
'\X••'arbitrary hexadecimal value -
L'x'wide character literal
-
-
42.0double-
42f,42Ffloat -
42l,42Llong double -
42Eexponential form -
0.42e23exponential form
-
-
NULLnull macro
-
(char)42 -
(short)42 -
(int)42 -
(long)42 -
(float)42 -
(double)42 -
(bool)42(Out of ISO/IEC 9899:TC2 specification) -
(string)42(Out of ISO/IEC 9899:TC2 specification) -
(void)42 -
(long type)42Casting to a long type (long int,long double, etc) -
(const type)42Casting to a constant type (const char, etc) -
(unsigned type)42Casting to unsigned type (unsigned int,unsigned long, etc) -
(signed type)42Casting to signed type (signed int,signed long, etc) - Pointers (
void *, etc) - References (
unsigned int,unsigned long, etc)
use FFI\Preprocessor\Preprocessor;
use FFI\Preprocessor\Directive\ObjectLikeDirective;
$pre = new Preprocessor();
// #define A
$pre->define('A');
// #define B 42
$pre->define('B', '42');
// #define С 42
$pre->define('С', new ObjectLikeDirective('42'));use FFI\Preprocessor\Preprocessor;
use FFI\Preprocessor\Directive\FunctionLikeDirective;
$pre = new Preprocessor();
// #define C(object) object##_T* object;
$pre->define('C', function (string $arg) {
return "${arg}_T* ${arg};";
});
// #define D(object) object##_T* object;
$pre->define('D', new FunctionLikeDirective(['object'], 'object##_T* object'));use FFI\Preprocessor\Preprocessor;
$pre = new Preprocessor();
$pre->include('/path/to/directory');
$pre->exclude('some');use FFI\Preprocessor\Preprocessor;
$logger = new Psr3LoggerImplementation();
$pre = new Preprocessor($logger);
$pre->process('
#error Error message
// Will be sent to the logger:
// - LoggerInterface::error("Error message")
#warning Warning message
// Will be sent to the logger:
// - LoggerInterface::warning("Warning message")
');