PageRenderTime 37ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/extensions/MetavidWiki/maintenance/fix_style.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 320 lines | 253 code | 38 blank | 29 comment | 52 complexity | f7a1bb820748297d5d6118acfbb91a07 MD5 | raw file
  1. <?php
  2. /**
  3. * A PHP code beautifier aimed at adding lots of spaces to files that lack them,
  4. * in keeping with MediaWiki's spacey site style.
  5. */
  6. if ( php_sapi_name() != 'cli' ) {
  7. print "This script must be run from the command line\n";
  8. exit( 1 );
  9. }
  10. // recurse all files:
  11. function listdir( $start_dir = '.' ) {
  12. $files = array();
  13. if ( is_dir( $start_dir ) ) {
  14. $fh = opendir( $start_dir );
  15. while ( ( $file = readdir( $fh ) ) !== false ) {
  16. # loop through the files, skipping . and .., and recursing if necessary
  17. if ( strcmp( $file, '.' ) == 0 || strcmp( $file, '..' ) == 0 ) continue;
  18. $filepath = $start_dir . '/' . $file;
  19. if ( is_dir( $filepath ) )
  20. $files = array_merge( $files, listdir( $filepath ) );
  21. else
  22. array_push( $files, $filepath );
  23. }
  24. closedir( $fh );
  25. } else {
  26. # false if the function was called with an invalid non-directory argument
  27. $files = false;
  28. }
  29. return $files;
  30. }
  31. $files = listdir( '.' );
  32. $line_count = 0;
  33. foreach ( $files as $file ) {
  34. if ( substr( $file, - 4 ) == '.php' ) {
  35. print 'do style: ' . $file . "\n";
  36. // stylize_file
  37. stylize_file( $file );
  38. $line_count += count( file( $file ) );
  39. }
  40. }
  41. print "did style on $line_count lines \n";
  42. // print:da
  43. /*array_shift( $argv );
  44. if ( count( $argv ) ) {
  45. foreach ( $argv as $filename ) {
  46. stylize_file( $filename );
  47. }
  48. } else {
  49. stylize_file( '-' );
  50. }*/
  51. function stylize_file( $filename ) {
  52. if ( $filename == '-' ) {
  53. $s = file_get_contents( '/dev/stdin' );
  54. if ( $s === false ) {
  55. return;
  56. }
  57. $stylizer = new Stylizer( $s );
  58. $s = $stylizer->stylize();
  59. echo $s;
  60. } else {
  61. $s = file_get_contents( $filename );
  62. if ( $s === false ) {
  63. return;
  64. }
  65. $stylizer = new Stylizer( $s );
  66. $s = $stylizer->stylize();
  67. rename( $filename, "$filename~" );
  68. file_put_contents( $filename, $s );
  69. }
  70. }
  71. class Stylizer {
  72. var $tokens, $p;
  73. static $tablesInitialised = false;
  74. static $xSpaceBefore, $xSpaceAfter;
  75. static $space = array(
  76. T_WHITESPACE,
  77. 'START',
  78. 'END',
  79. );
  80. static $spaceBothSides = array(
  81. T_AND_EQUAL,
  82. T_AS,
  83. T_BOOLEAN_AND,
  84. T_BOOLEAN_OR,
  85. T_CASE,
  86. T_CATCH,
  87. T_CLONE,
  88. T_CONCAT_EQUAL,
  89. T_DIV_EQUAL,
  90. T_DO,
  91. T_DOUBLE_ARROW,
  92. T_ELSE,
  93. T_ELSEIF,
  94. T_FOR,
  95. T_FOREACH,
  96. T_IF,
  97. T_IS_EQUAL,
  98. T_IS_GREATER_OR_EQUAL,
  99. T_IS_IDENTICAL,
  100. T_IS_NOT_EQUAL,
  101. T_IS_NOT_IDENTICAL,
  102. T_IS_SMALLER_OR_EQUAL,
  103. T_LOGICAL_AND,
  104. T_LOGICAL_OR,
  105. T_LOGICAL_XOR,
  106. T_MOD_EQUAL,
  107. T_MUL_EQUAL,
  108. T_OR_EQUAL,
  109. T_PLUS_EQUAL,
  110. T_SL,
  111. T_SL_EQUAL,
  112. T_SR,
  113. T_SR_EQUAL,
  114. T_TRY,
  115. T_WHILE,
  116. T_XOR_EQUAL,
  117. '{',
  118. '}',
  119. '%',
  120. '^',
  121. // '&', can be unary, we have a special case for =&
  122. '*',
  123. '-',
  124. '=',
  125. '+',
  126. '|',
  127. // ':', can be a case label
  128. '.',
  129. '<',
  130. '>',
  131. '/',
  132. '?',
  133. );
  134. static $spaceBefore = array(
  135. ')'
  136. );
  137. static $spaceAfter = array(
  138. '(',
  139. ';',
  140. ',',
  141. );
  142. static $closePairs = array(
  143. '(' => ')',
  144. '=' => '&',
  145. );
  146. // Tokens that eat spaces after them
  147. static $spaceEaters = array(
  148. T_COMMENT,
  149. T_OPEN_TAG,
  150. T_OPEN_TAG_WITH_ECHO,
  151. );
  152. var $endl = "
  153. ";
  154. function __construct( $s ) {
  155. $s = str_replace( "\r\n", "\n", $s );
  156. $this->tokens = token_get_all( $s );
  157. if ( !self::$tablesInitialised ) {
  158. self::$xSpaceBefore = array_combine(
  159. array_merge( self::$spaceBefore, self::$spaceBothSides ),
  160. array_fill( 0, count( self::$spaceBefore ) + count( self::$spaceBothSides ), true )
  161. );
  162. self::$xSpaceAfter = array_combine(
  163. array_merge( self::$spaceAfter, self::$spaceBothSides ),
  164. array_fill( 0, count( self::$spaceAfter ) + count( self::$spaceBothSides ), true )
  165. );
  166. }
  167. }
  168. function get( $i ) {
  169. if ( $i < 0 ) {
  170. return array( 'START', '' );
  171. } elseif ( $i >= count( $this->tokens ) ) {
  172. return array( 'END', '' );
  173. } else {
  174. $token = $this->tokens[$i];
  175. if ( is_string( $token ) ) {
  176. return array( $token, $token );
  177. } else {
  178. return array( $token[0], $token[1] );
  179. }
  180. }
  181. }
  182. function getCurrent() {
  183. return $this->get( $this->p );
  184. }
  185. function getPrev() {
  186. return $this->get( $this->p - 1 );
  187. }
  188. function getNext() {
  189. return $this->get( $this->p + 1 );
  190. }
  191. function isSpace( $token ) {
  192. if ( in_array( $token[0], self::$space ) ) {
  193. return true;
  194. }
  195. // Some other tokens can eat whitespace
  196. if ( in_array( $token[0], self::$spaceEaters ) && preg_match( '/\s$/', $token[1] ) ) {
  197. return true;
  198. }
  199. return false;
  200. }
  201. function isSpaceBefore( $token ) {
  202. return isset( self::$xSpaceBefore[$token[0]] );
  203. }
  204. function isSpaceAfter( $token ) {
  205. return isset( self::$xSpaceAfter[$token[0]] );
  206. }
  207. function consumeUpTo( $endType ) {
  208. $token = $this->getCurrent();
  209. $out = $token[1];
  210. do {
  211. $this->p++;
  212. $token = $this->getCurrent();
  213. $out .= $token[1];
  214. } while ( $this->p < count( $this->tokens ) && $token[0] != $endType );
  215. return $out;
  216. }
  217. function stylize() {
  218. $out = '';
  219. for ( $this->p = 0; $this->p < count( $this->tokens ); $this->p++ ) {
  220. list( $prevType, $prevText ) = $prevToken = $this->getPrev();
  221. list( $curType, $curText ) = $curToken = $this->getCurrent();
  222. list( $nextType, $nextText ) = $nextToken = $this->getNext();
  223. // Don't format strings
  224. if ( $curType == '"' ) {
  225. $out .= $this->consumeUpTo( '"' );
  226. continue;
  227. } elseif ( $curType == T_START_HEREDOC ) {
  228. $out .= $this->consumeUpTo( T_END_HEREDOC );
  229. continue;
  230. } elseif ( $curType == "'" ) {
  231. // For completeness
  232. $out .= $this->consumeUpTo( "'" );
  233. continue;
  234. }
  235. // Detect close pairs like ()
  236. $closePairBefore = isset( self::$closePairs[$prevType] )
  237. && $curType == self::$closePairs[$prevType];
  238. $closePairAfter = isset( self::$closePairs[$curType] )
  239. && $nextType == self::$closePairs[$curType];
  240. // Add space before
  241. if ( $this->isSpaceBefore( $curToken )
  242. && !$this->isSpace( $prevToken )
  243. && !$closePairBefore
  244. ) {
  245. $out .= ' ';
  246. }
  247. // Add the token contents
  248. if ( $curType == T_COMMENT ) {
  249. $curText = $this->fixComment( $curText );
  250. } elseif ( $curType == T_WHITESPACE ) {
  251. $curText = $this->fixWhitespace( $curText );
  252. }
  253. $out .= $curText;
  254. $wantSpaceAfter = $this->isSpaceAfter( $curToken );
  255. // Special case: space after =&
  256. if ( $prevType == '=' && $curType == '&' ) {
  257. $wantSpaceAfter = true;
  258. }
  259. // Add space after
  260. if ( $wantSpaceAfter
  261. && !$closePairAfter
  262. && !$this->isSpace( $nextToken )
  263. && !$this->isSpaceBefore( $nextToken )
  264. ) {
  265. $out .= ' ';
  266. }
  267. }
  268. $out = str_replace( "\n", $this->endl, $out );
  269. return $out;
  270. }
  271. function fixComment( $s ) {
  272. // Fix single-line comments with no leading whitespace
  273. if ( preg_match( '!^(#|//)(\S.*)$!s', $s, $m ) ) {
  274. $s = $m[1] . ' ' . $m[2];
  275. }
  276. return $s;
  277. }
  278. function fixWhitespace( $s ) {
  279. // Fix whitespace at the line end
  280. return preg_replace( '!^([\t ]+)(\n.*)$!s', '\2', $s, 1 );
  281. }
  282. }