Code Twister

This text is from my arcives. It may be out of date, but I thought it should be preserved.

This tool loads all files required by a project (including binaries) into one file.
All unused functions will be removed, all function and variable names will be replaced
by shorter (and unreadable) ones, all not needed whitespaces will be removed, debugging code will be removed, ...
You'll get informed when a global or local variable is not used.
The resulting file is still a regular php-file. (No extra softeate is required!) Requirements: PHP 4.3.0 and up, CLI or CGI (developed under 5.0 beta)
You have to use it from a shell and it requires much memory. (The coding of twister [60kB code = 2k5 lines] needs about 8MB).
Version 0.9 (2004-03-11) Should now be run also on 500b4 and further versions
Fixed include paths
Added -c, -I, conf: input, conf: inverse
New in 0.9
Version 0.8 (2003-10-09) Merged the versions for PHP 4 and 5 into one
Fixed the default.conf
Version 0.7 (2003-10-07) Fixed a big bug with PHP 4.3.x
Now you can buy twister
Version 0.6 (internal) Added config:target and the -t option (removed config:define)
Changed -d4
Version 0.5 (internal) Improved the -r2 option much
Version 0.4 (2003-09-18) Added a PHP version check
Made the error more readable
Added the option -r2 (see below)
Rewrote parts of the source
Added an option in comment for packit and fileloader
Version 0.3 (2003-09-14) First release
example Here is an basic example output. (currently n/a)
Here is an complex -r2 example output. (currently n/a)
Get version 0.9 tar.gz (about 20 KB)
(Note: in the demo -n, -r2, -d4, -t, -S and -F are disabled) Please mail me, and tell me what do you think about it.
basics Usage: php twister.php <options...> <file>
If <file> will be obmitted stdin will be used as source. All options have the syntax: -X value or -Xvalue.
Some options are bit masks. Example usage: -X <1,2,4> you have to add the number of all features you want to use. For 1 and 4 use -X 5. To diable all -X 0. If a option is omitted the default will be used. (Either builtin or from a config-file, see -f.) Some functions are controlled by comments, you have to use exact that comment. (But you can add whitespaces outside of the comment like you want.)
quick Here is a quick overview about the options.
-i <1>: include other code, 1=on, default=1
-d <1,2,4>: replace defines, 1=user, 2=system, 4=target, default=3
-t <target>: selects the specified target for -d4
-r <1,2>: remove unused code, 1=on, 2=optimize if, default=3
-p <1,2,4>: packit/fileloader, 1=on, 2=diable gzip, 4=disable base64, default=3
-n <1,2>: name substituation, 1=on, 2=string, default=3
-z <1,2>: compress output, 1=enable gzip, 2=enable base64, default=0
-c <1,2>: replace variable constants, 1=originals, 2=dummy, default=1
-f <config.conf>: read options from config.conf
-I <path[:path[...]]>: define the include path, default=./
-o <out.php>: write final to out.php
-1 <stage1.php>, -2 <stage2.php>, -3 <stage3.php>, -4 <stage4.php>,
-S <scan.php>, -F <files.php>: debugging output
config The config-file contains the defaults for all options in the config: opts section.
All other sections are described later. In the config: opts section is now a way to specify the input file.
manual What do the colors mean?
Command line options, References to the config-file, Example code, Things that don't work yet In the left column is the described option noted, in the right column the config-file.
  Here is a detailed description, what the tool will do in which order, and what options can be used:  
-f First option: -f <config.conf> to load the default configuration from the file config.conf instead of using the builtin. (The file default.conf of the distribution contains the builtin configuration.) All options can be overwritten by the command line.  
  The main script will be load and parsed.  
-i Option: -i <1>. Now all files included by the main file will be also parsed and included. You have to use the command include, include_once, require, require_once with exactly one string as parameter, a trailing semicolon and NO whitespaces or comments.
Example: include('file.php'); will work, include($file.'.php'); will not be replaced, cause the tool don't know what's in $file. To disable it for one include you may use include('file.php' );. See -F for debug.
-I Option: -i <path[:path:[...]]>. With this option you can set the include path which is used for the including -i.
Multiple paths can be entered, seperated by a colon.
The default path is ./, where ./ is the path of the file to twist, which must not be the actual directory. In case of your are using stdin the current directory will used.
-1 If -1 <stage1.php> is used, the actual state will be dumped to stage1.php.  
-d The option -d <1,2,4> allows you to replace defines with their definitions.
1 Revoves all user defines with define('DEF', 'INE') where 'DEF' has to be a single constant string and 'INE' a single constant string, a single positive integer, a single positive float, a boolean constant (true, false) or null. And all occurencies of DEF will be replaced with 'INE'.
2 Replaces all systemwide defines with their definitions.
4 Enables the target replacement. First you have to submit a list of all targets in a config-file (see -f) or use the default's RELEASE and DEVELOP. By default the target to generate is the first in the config. This can be overwritten with the -t option. The selected target will be replaced by true all others with false.
You should place something like the following in your code:
define('DEVELOP', true);
define('RELEASE', false);

So, in a regular run DEVELOP is true but it is RELEASE in the generated code.
The option -d4 requires that -d1 is enabled.
-c With the option -c <1,2> you can switch the replacement of variable constants on.
Variable constants are: __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__.
1 it will be replaced by the original values.
2 __FILE__ will be replaced by "(twisted)" and __LINE__ by 0.
-p The option -p <1,2,4> selects the packit functionality.
A part of the code will be evaluated now and replaced by a packed version. Only strings and pure constant arrays can be packed. (For arrays (un)serialize will be used.) A gzip compression will be used if it decreases the length. At least base64 encoding is used, so it's a plain ASCII text.
Code: $x = /*PACKIT*/ array(0=>'big array', 1=>'really big') will be replaced by $x = P(1, 'XXXX...') The name of the function is PHP_CODE_TWISTER_PACKIT_FUNCTION, not P, which will be created automatically. So the code is less readable.
1 Enable packit functionality. (And also fileloader, see below)
2 the gzip compression is disabled, if you don't want to use it. (maybe your php can't use it)
4 the base64 encoding is disabled.
-p A second feature wich is also enabled by -p1 is the fileloader function.
Code like $x = /*FILELOADER*/ file_get_contents('file.gif') will be replaced by the contents of the file, like packit: $x = P(1, 'XXXX...'). So now the file is IN your php program. Note: only a single constant string as parameter for file_get_contents is supported. Alternative fileloader usage: $x = /*PACKIT*/ array( filemtime('file.gif'), file_get_contents('file.gif') ) will be replaced with something like this: $x = array(105523325, P(1, 'XXXX...')). The switches 2 and 4 are also used by the fileloader.
-p With /*PACKIT:X*/ and /*FILELOADER:X*/ you can set the -p options to X for this call. The option 1 is ignored for now, but should be set. Example: $x = /*PACKIT:7*/ 'Hello'." ".'World'."\n" will be packed, but neither gzip nor base64 encoded, the result is a single string.  
-2 Now a second stage can be written on disk with -2 <stage2.php>.  
  The following loop will remove unused code.  
1 This do enable remove unused functions, classes, methods, members from the code. Everything named in config: function, class, method, member will not be removed. If the first entry of config: function, class, method, member is '*' then the list is interpreted as a white list. (Only functions, classes, methods, members which are listed there will be maybe removed. A list containing only '*' just says that nothing sould be removed)
2 All if statements will be evaluated, if possible. Which means that if the statement are only constants and operators (or, and, +, ...) and no funcitions or variables the block will maybe killed or all following will killed. See the 2. demo.
The alternative syntax for control structures is also supported. Note: With -d 1 you can replace defines by their value (e.g. false) and then let this function remove the if's.
-3 After finishing this loop a third stage can be written on disk with -3 <stage3.php>.  
1 Whis this option allmost all function, variable, class, method and member names are replaced by a shorter (and less readable) one. Now the config-file is important! First all $this inside a method will never be replaced. Please never add $this to any config value. Don't add $GLOBALS to the config, this variable is handeled especially.
All variables which are defined in config: superblobal will not be changed.
All global variables which are defined in config: global will not be replaced.
All other global variables will replaced.
All local variables which are not noted in config: local will be replaced.
All function names which are not noted in config: function will be replaced.
All class names which are not noted in config: class will be replaced.
All method names which are not noted in config: method will be replaced.
All member names which are not noted in config: member will be replaced.
A language constucts named in config: language will never be used for a function, class, method or member name. If the first entry of config: global, function, class, method, member is '*' then the list is interpreted as a white list. (Only globals, functions, classes, methods, members which are listed there will be renamed. A list containing only '*' just says that nothing sould be renamed)
2 Enables name in string replacement. If you use callback functions or variables/functions in a string, which will be evaluated you have to mark them so they can be replaced.
Example: eval('$x = dummy(0,1);'); Now you must mark the variable/function name in the text so that they can be replaced. To mark, write the comment /*VAR*/ before a string, which contain ONLY the variable name, with or without the $ sign. Use /*FUNCTION*/ for functions.
Usage: eval(/*VAR*/'$x'.' = './*FUNCTION*/'dummy'.'(0,1);');
Usage: $a = /*VAR*/'b'; $$a = 'this changes $b';
See -S for debug.
local function
member language
-4 Now a fourth stage can be written on disk with -4 <stage4.php>.  
Use -o <out.php> to write the resulting code without any comment and only a minimum of whitespaces to disk. The switch -z <1,2> contols the encoding of the output. The option 1 enables gzip compression, which makes the code much smaller. It requires gzip decompression in the php which should interpret your code. And it's not longer ASCII source, which may have some pitfalls. To make it ASCII compatible again, you may want to use option 2 to enable base64 encoding.  
  Now we're trough. At last you can get two debugging files:  
-F With -F <files.php> will write a php code which contains an array of all files which are included or loaded while fileloader and a number which shows how often the file was loaded.  
-S With -S <scan.php> will write a php code which contains an array of all name replacements which are made.  

0 Responses to “Code Twister”

Comments are currently closed.