ffi / preprocessor
Simple C Preprocessor
Installs: 36 176
Dependents: 13
Suggesters: 0
Security: 0
Stars: 19
Watchers: 2
Forks: 0
Open Issues: 0
Requires
- php: ^7.4|^8.0
- ffi/preprocessor-contracts: ^1.0
- phplrt/lexer: ^3.2
- phplrt/parser: ^3.2
- psr/log: ^1.0|^2.0|^3.0
- symfony/polyfill-ctype: ^1.27
- symfony/polyfill-php80: ^1.27
Requires (Dev)
- jetbrains/phpstorm-attributes: ^1.0
- monolog/monolog: ^2.9|^3.0
- phplrt/phplrt: ^3.2
- phpunit/phpunit: ^9.6
- squizlabs/php_codesniffer: ^3.7
- vimeo/psalm: ^5.14
Provides
This package is auto-updated.
Last update: 2024-12-17 00:28:09 UTC
README
This implementation of a preprocessor based in part on ISO/IEC 9899:TC2.
Requirements
- PHP >= 7.4
Installation
Library is available as composer repository and can be installed using the following command in a root of your project.
$ composer require ffi/preprocessor
Usage
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; //
Directives
Supported Directives
-
#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
-
Expression Grammar
Comparison Operators
-
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
Logical Operators
-
! A
logical NOT -
A && B
conjunction -
A || B
disjunction -
(...)
grouping
Arithmetic Operators
-
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
Bitwise Operators
-
~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
Other Operators
-
defined(X)
defined macro -
A ? B : C
ternary -
sizeof VALUE
sizeof-
sizeof(TYPE)
sizeof type
-
Literals
-
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
Type Casting
-
(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)
Object Like Directive
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'));
Function Like Directive
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'));
Include Directories
use FFI\Preprocessor\Preprocessor; $pre = new Preprocessor(); $pre->include('/path/to/directory'); $pre->exclude('some');
Message Handling
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") ');