PageRenderTime 53ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/build/build.php

http://github.com/polygonplanet/Pot.js
PHP | 189 lines | 156 code | 15 blank | 18 comment | 17 complexity | 93bdd285e924f0acd02b9d29f45de261 MD5 | raw file
  1. <?php
  2. //
  3. // Pot.js / PotLite.js
  4. // Simple script compiler
  5. //
  6. // Usage:
  7. // Run server.
  8. // Access http://localhost/{this-directory}/build.php?debug=true&type=full
  9. // Parameters:
  10. // - debug:
  11. // "true" or "false"
  12. // Output PHP comiled code if "debug" is "true".
  13. // - type:
  14. // "lite" or "full"
  15. // Build "PotLite.js" if "type" is "lite".
  16. // Build "Pot.js" if "type" is "full".
  17. // - version:
  18. // Optional.
  19. //
  20. pot_build();
  21. class Pot_Builder {
  22. const POT_SETTINGS = 'pot.package.json';
  23. const POTLITE_SETTINGS = 'potlite.package.json';
  24. const SOURCE_DIR = '../src/';
  25. private $debug;
  26. private $version;
  27. private $date;
  28. private $year;
  29. private $type;
  30. private $settings;
  31. private $code;
  32. private $enclosureCode;
  33. private $fileName;
  34. function __construct() {
  35. $this->init();
  36. if (empty($_GET)) {
  37. die('Error: Need to access with HTTP GET.');
  38. }
  39. $this->type = isset($_GET['type']) ? strtolower($_GET['type']) : 'full';
  40. if ($this->type === 'lite') {
  41. $path = self::POTLITE_SETTINGS;
  42. define('POTLITE', true, true);
  43. define('POT', false, true);
  44. } else {
  45. $this->type = 'full';
  46. $path = self::POT_SETTINGS;
  47. define('POTLITE', false, true);
  48. define('POT', true, true);
  49. }
  50. $this->settings = json_decode(file_get_contents($path));
  51. $this->fileName = $this->settings->fileName;
  52. if (isset($_GET['debug'])) {
  53. $this->debug = (bool)preg_match('{^(?:true|1|on|yes)$}i', $_GET['debug']);
  54. } else if (isset($this->settings->debug)) {
  55. $this->debug = (bool)$this->settings->debug;
  56. } else {
  57. $this->debug = false;
  58. }
  59. define('DEBUG', $this->debug, true);
  60. if (!empty($_GET['version'])) {
  61. $this->version = $_GET['version'];
  62. } else if (isset($this->settings->version)) {
  63. $this->version = (string)$this->settings->version;
  64. } else {
  65. $this->version = '$Version$';
  66. }
  67. $this->code = '';
  68. $this->date = date('Y-m-d');
  69. $this->year = date('Y');
  70. }
  71. function init() {
  72. error_reporting(E_ALL);
  73. @ini_set('display_errors', 1);
  74. @ini_set('log_errors', false);
  75. @ini_set('track_errors', false);
  76. @ini_set('default_charset', 'UTF-8');
  77. if (function_exists('date_default_timezone_set') &&
  78. function_exists('date_default_timezone_get')) {
  79. @date_default_timezone_set(@date_default_timezone_get());
  80. }
  81. header('Content-Type: application/javascript');
  82. }
  83. function build() {
  84. $this->load();
  85. $this->flush();
  86. }
  87. function load() {
  88. $codes = array();
  89. foreach ($this->settings->files as $file) {
  90. $code = file_get_contents(self::SOURCE_DIR . $file);
  91. $codes[] = $this->assign($code);
  92. }
  93. if ($this->debug) {
  94. $this->code = implode("\x0A", $codes);
  95. $wrap = file_get_contents(self::SOURCE_DIR . $this->settings->enclosure);
  96. $enclosure = $this->evaluate($this->assign($wrap));
  97. file_put_contents(sprintf('%s-~obj.js', $this->fileName), $enclosure);
  98. unset($wrap, $enclosure);
  99. }
  100. $this->code = $this->evaluate(implode("\x0A", $codes));
  101. $code = file_get_contents(self::SOURCE_DIR . $this->settings->enclosure);
  102. $this->enclosureCode = $this->assign($code);
  103. $this->code = $this->evaluate($this->enclosureCode);
  104. file_put_contents($this->fileName, $this->code);
  105. }
  106. function flush() {
  107. echo $this->code;
  108. flush();
  109. }
  110. function evaluate($code) {
  111. ob_start();
  112. echo eval(sprintf('?>%s', $code));
  113. $code = ob_get_contents();
  114. ob_end_clean();
  115. return $this->normalize($code);
  116. }
  117. function normalize($code) {
  118. return preg_replace('{(\x0D\x0A|\x0A|\x0D)}', "\x0A", $code);
  119. }
  120. function assign($code) {
  121. if (preg_match('{<[?]|[?]>}', $code)) {
  122. die('Error: Invalid code');
  123. }
  124. $code = preg_replace_callback(
  125. '<
  126. (?:/(?:/[\x09\x20]*|[*])|)
  127. \{\#\s*(\$|)(\w+)\s*([^\}]*)\s*\}
  128. (?:[*]/|)
  129. (\x0D\x0A|\x0A|\x0D|)
  130. >sx',
  131. array($this, 'assignCallback'),
  132. $code
  133. );
  134. return $code;
  135. }
  136. function assignCallback($matches) {
  137. $result = 'throw new Error("error!")';
  138. $nl = "\x0A";
  139. if ($matches[1] === '$') {
  140. $result = sprintf('<?php echo $this->%s ?>%s%s', $matches[2], $nl, $matches[4]);
  141. } else {
  142. $expr = '';
  143. switch (strtolower($matches[2])) {
  144. case 'if':
  145. $expr = sprintf('if(%s):', $matches[3]);
  146. break;
  147. case 'else':
  148. $expr = sprintf('else:');
  149. break;
  150. case 'elseif':
  151. $expr = sprintf('elseif(%s):', $matches[3]);
  152. break;
  153. case 'end':
  154. case 'endif':
  155. $expr = sprintf('endif;');
  156. break;
  157. case 'code':
  158. $expr = sprintf('echo $this->code');
  159. break;
  160. default:
  161. $expr = sprintf('%s', $matches[3]);
  162. break;
  163. }
  164. $result = sprintf('<?php %s ?>%s%s', $expr, $nl, $matches[4]);
  165. }
  166. return $result;
  167. }
  168. }
  169. function pot_build() {
  170. $pb = new Pot_Builder();
  171. $pb->build();
  172. $pb = null;
  173. unset($pb);
  174. }