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/preprocessor
use 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 name
defining directives-
#define name value
object-like macro -
#define name(arg) value
function-like macro -
#define name(arg) xxx##arg
concatenation -
#define name(arg) #arg
stringizing
-
-
#undef name
removing directives -
#ifdef name
"if directive defined" condition -
#ifndef name
"if directive not defined" condition -
#if EXPRESSION
if condition -
#elif EXPRESSION
else if condition -
#else
else condition -
#endif
completion of a condition -
#error message
error message directive -
#warning message
warning message directive -
#line 66 "filename"
line and file override -
#pragma XXX
compiler control-
#pragma once
-
-
#assert XXX
compiler assertion-
#unassert XXX
compiler assertion
-
-
#ident XXX
-
#sccs XXX
-
-
A > B
greater than -
A < B
less than -
A == B
equal -
A != B
not equal -
A >= B
greater than or equal -
A <= B
less than or equal
-
! A
logical NOT -
A && B
conjunction -
A || B
disjunction -
(...)
grouping
-
A + B
math addition -
A - B
math subtraction -
A * B
math multiplication -
A / B
math division -
A % B
modulo -
A++
increment-
++A
prefix form
-
-
A--
decrement-
--A
prefix form
-
-
+A
unary plus -
-A
unary minus -
&A
unary addr -
*A
unary pointer
-
~A
bitwise NOT -
A & B
bitwise AND -
A | B
bitwise OR -
A ^ B
bitwise XOR -
A << B
bitwise left shift -
A >> B
bitwise right shift
-
defined(X)
defined macro -
A ? B : C
ternary -
sizeof VALUE
sizeof-
sizeof(TYPE)
sizeof type
-
-
true
,false
boolean -
42
decimal integer literal-
42u
,42U
unsigned int -
42l
,42L
long int -
42ul
,42UL
unsigned long int -
42ll
,42LL
long long int -
42ull
,42ULL
unsigned long long int
-
-
042
octal integer literal -
0x42
hexadecimal integer literal -
0b42
binary 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.0
double-
42f
,42F
float -
42l
,42L
long double -
42E
exponential form -
0.42e23
exponential form
-
-
NULL
null 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)42
Casting to a long type (long int
,long double
, etc) -
(const type)42
Casting to a constant type (const char
, etc) -
(unsigned type)42
Casting to unsigned type (unsigned int
,unsigned long
, etc) -
(signed type)42
Casting 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")
');