summaryrefslogtreecommitdiff
path: root/concat/concat.php
blob: 6594fd9abdce55c57cd905edfd39641df9241fae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
define('DEBUG_TOKENS', false);
$deferred_close_tag = '';
for ($argi=1; $argi<$argc; $argi++) {
	// Parse current arg file's content
	$filepath = $argv[$argi];
	$src = file_get_contents($filepath) or die("Can't read '$filepath'".PHP_EOL);
	$tokens = token_get_all($src) or die("Can't parse '$filepath'".PHP_EOL);
	$tcount = count($tokens);

	// Process all tokens for the current file
	if ( DEBUG_TOKENS ) fwrite(STDERR, "file $filepath ($tcount)".PHP_EOL);
	$in_php = false;
	$file_first_open_tag = true;
	$token_to_add_after = '';
	$token_to_add_before = $deferred_close_tag;
	$deferred_close_tag = '';
	for ($i=0; $i<$tcount; $i++) {
		$token = $tokens[$i];
		if ( DEBUG_TOKENS ) fwrite(STDERR, (is_array($token)?token_name($token[0])." $token[1]":"LITTERAL $token").PHP_EOL);
		// Manipulate tokens 
		switch ( is_array($token)?$token[0]:$token ) {
		case T_CLOSE_TAG:
			$in_php = false;
			// if close tag as last token, defer it, will be processed at first token of next file
			if ( $i == ($tcount-1) ) {
				$deferred_close_tag = $token;
				$token = '';
			}
			break;
		case T_OPEN_TAG:
		case T_OPEN_TAG_WITH_ECHO:
			$in_php = true;
			// insert a "#line" annotation in output at first php block of each source file
			if ( $file_first_open_tag ) {
				$line = $token[2];
				// insert carriage return after this open tag if not already there
				if ( strrpos($token[1], PHP_EOL) !== (strlen($token[1])-1) ) {
					$comment = PHP_EOL;
				} else {
					$comment = '';
					$line++;
				}
				$comment .= "#line $line $filepath".PHP_EOL;
				$token_to_add_after = [ T_COMMENT, $comment, $line ];
				$file_first_open_tag = false;
			}
			// if first token in current file is T_OPEN_TAG and a previous T_CLOSE_TAG is pending
			if (  ( $i == 0 ) && is_array($token_to_add_before) && $token_to_add_before[0]==T_CLOSE_TAG ) {
				// Strip previous file T_CLOSE_TAG
				$token_to_add_before = '';
				// and current file T_OPEN_TAG
				$token = '';
			}
			break;
		} /* switch */

		// Output current token with additions and reset them
		foreach ( [$token_to_add_before, $token, $token_to_add_after] as $t ) {
			echo is_array($t)?$t[1]:$t;
		}
		$token_to_add_before = '';
		$token_to_add_after = '';

	} /* foreach $tokens */

	// Add implicit T_CLOSE_TAG at end of file and if we are still $in_php
	if ( $in_php ) {
		$deferred_close_tag = [ T_CLOSE_TAG, '?>'.PHP_EOL, 0 ];
	}

} /* foreach args */

/* Optionnal : output T_CLOSE_TAG if was deferred and it's the last file
if ( is_array($deferred_close_tag) ) {
	echo $deferred_close_tag[1];
}*/