ffi / preprocessor
Simple C Preprocessor
Installs: 37 031
Dependents: 13
Suggesters: 0
Security: 0
Stars: 23
Watchers: 2
Forks: 0
Open Issues: 0
pkg:composer/ffi/preprocessor
Requires
- php: ^7.4|^8.0
- ffi/preprocessor-contracts: ^1.0
- phplrt/lexer: ^3.6
- phplrt/parser: ^3.6
- psr/log: ^1.0|^2.0|^3.0
- symfony/polyfill-ctype: ^1.27
- symfony/polyfill-php80: ^1.27
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.53
- monolog/monolog: ^2.9|^3.0
- phplrt/phplrt: ^3.6
- phpstan/phpstan: ^2.0
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^9.5
Provides
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 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
-
Expression Grammar
Comparison Operators
-
A > Bgreater than -
A < Bless than -
A == Bequal -
A != Bnot equal -
A >= Bgreater than or equal -
A <= Bless than or equal
Logical Operators
-
! Alogical NOT -
A && Bconjunction -
A || Bdisjunction -
(...)grouping
Arithmetic Operators
-
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
Bitwise Operators
-
~Abitwise NOT -
A & Bbitwise AND -
A | Bbitwise OR -
A ^ Bbitwise XOR -
A << Bbitwise left shift -
A >> Bbitwise right shift
Other Operators
-
defined(X)defined macro -
A ? B : Cternary -
sizeof VALUEsizeof-
sizeof(TYPE)sizeof type
-
Literals
-
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
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)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)
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") ');