CCPP logo

CCPP

C Compatible Preprocessor for PHP.

Contents

What?!?!?!

This is a preprocessor. That means it processes the code before execution/compilation. It is common for C language and it's used for inline optimizations, templating, defining constants, loading headers and many other things.

Why?

That's quite good question. With more and more people using PHP, Zend Engine (the PHP interpreter) inevitably becomes more and more powerful. People start to use PHP CLI functionality more often, on may platforms. For instance Phoronix Test Suite runs on Linux, *BSD and OpenSolaris.

When writing cross-platform application, the code usually includes platform checks. In C, this is done using the preprocessor directives

#ifdef WINDOWS
printf("You are running Windows.");
#else
printf("You are not running Windows.");
#endif
PHP lacks this feature. In PHP you should use something like
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'){
...
Unfortunately, if this condition is in a loop, it is checked every time the loop repeats. It's even worse with nested loops. The solution is to make different codebase for every different platform. Another solution is to preprocess the code before execution, and this is where CCPP takes place.

What is "C Compatible"?

It means, that is done using the guidelines from ISO/IEC 9899:1990 TC2 WG14/N1124 which is approoved standard for C language and it's preprocessor. Thus, this C Compatible Preprocessor for PHP is compatible with other implementations of C preprocessor (like GNU CPP).

Features

* trigraphs replacement
* line-slicing
* comment removal
* directives: #if, #else, #elif, #endif, #include, #define, #warning, #error
* non-standard directives: #includephp, #literal
* Object-like macros
* Function-like macros (Function-like macros in Function-like macros are not supported)
* ## preprocessor operator

License

The license is 2-clause BSD (similar to FreeBSD's one, as of 3rd May 2009). That means it's open-source and you are free to distribute, modify, sell or use in a commercial software and many others, as long as you keep the copyright. You may find full copy of the license here.

Download

<? CCPP Preprocessor for PHP - 0.1 Beta 2
<? CCPP Preprocessor for PHP - 0.1 Beta 1

Examples

Source

<?php
#define macroFunction(op1,op2,op3) ((int)op1/((int)op2+(int)op3))
#define hash_hash # ## #
#define showCExamples 1

#if showCExamples
//Reference: http://en.wikipedia.org/wiki/C_preprocessor#Token_concatenation
#define MYCASE(item,id) \
case id: \
  item##_##id = id;\
break

switch(x) {
    MYCASE(widget,23);
}

//Reference: http://en.wikipedia.org/wiki/C_preprocessor#Multiple_statements
#define CMDS \
   a = b; \
   c = d

  if (var == 13)
    CMDS;
  else
    return;

#endif
MYCASE(widget,23);
#define VERBOSE 1
#if VERBOSE >= 2
echo 'This is debug info which shows only if you have increased verbosity level';
#else
echo '1 == '.macroFunction(12, '5', 7);
#endif

#ifdef WINDOWS
print 'You are running Windows';
#else
print 'You are not running Windows';
#endif

#if _CCPP_PHP_VERSION >= 5.3
//Supports closures
$array = array_filter($array, function($value){return $value > 3;});
#else
//Creating lambda function
$array = array_filter($array, create_function('$value', 'return $value > 3;'));
#endif
If you are running Linux and PHP 5.2.6, the output will be:
<?php



switch(x) {
    case 23:   widget_23 = 23;break;
}


  if (var == 13)
    a = b;    c = d;
  else
    return;

case 23:   widget_23 = 23;break;
echo '1 == '.((int)12/((int)'5'+(int)7));

print 'You are not running Windows';


$array = array_filter($array, create_function('$value', 'return $value > 3;'));

Hacks

Interesting way to make you application working with or without preprocessor is to use this "hack"

// \
This line is disabled when using C preprocessor, but is enabled when not using one.

//An example
#ifdef WINDOWS
// \
/*
Here is code that will be executed, when running Windows, but is disabled (commented) by default. Only when using CCPP this code will be available
// \
*/
#endif
It can be done using the #literal directive, which is a hack (it's not standard compilant).

New directive "includephp" is added, which is not in the ISO/IEC 9899:1990 standard. It is used when there is no starting <?php tag in a file and you want to include it as PHP.
while (1){
	#includephp "macros/loopbody.macro"
}
This will result in processing the loopbody.macro file and the processed code to be put in the place of the directive.

Not implemented features

* defined() function-like macro in directives
* function-like macro in function-like macro
* pragma directive
* single hash (quoting string) in function-like macros
* caching the compiled code

Some PHP5 propaganda for our own good.

Support GoPHP5.org