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") ');