[ Index ] |
PHP Cross Reference of PHK Manager |
[Summary view] [Print] [Text view]
1 <?php 2 //============================================================================= 3 // 4 // Copyright Francois Laupretre <phk@tekwire.net> 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 // 18 //============================================================================= 19 /** 20 * @copyright Francois Laupretre <phk@tekwire.net> 21 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, V 2.0 22 * @category PHK 23 * @package PHK 24 *///========================================================================== 25 26 namespace PHK\Virtual { 27 28 if (!class_exists('PHK\Virtual\File',false)) 29 { 30 //============================================================================= 31 /** 32 * A virtual file 33 * 34 * API status: Private 35 * Included in the PHK PHP runtime: Yes 36 * Implemented in the extension: No 37 *///========================================================================== 38 39 class File extends Node // Regular file 40 { 41 42 private $dc; // Data container 43 44 //--- 45 46 public function type() { return 'file'; } 47 public function mode() { return 0100444; } 48 49 //--- 50 // If a method is unknown, forward to the DC (poor man's multiple inheritance :) 51 52 public function __call($method,$args) 53 { 54 try { return call_user_func_array(array($this->dc,$method),$args); } 55 catch (\Exception $e) 56 { throw new \Exception($this->path.': '.$e->getMessage()); } 57 } 58 59 //--- 60 // Must be defined as __call() is tried after \PHK\Virtual\Node methods, and read() 61 // has a default in \PHK\Virtual\Node. 62 63 public function read() 64 { 65 return $this->dc->read(); 66 } 67 68 //--- 69 70 public function flagString() 71 { 72 $string=parent::flagString().','.$this->dc->flagString(); 73 $string=trim($string,','); 74 75 return $string; 76 } 77 78 //--- 79 80 public function displayPackage($html) 81 { 82 if ($this->flags & self::TN_PKG) $this->display($html); 83 } 84 85 //--- 86 // In HTML, create an hyperlink only for files, not for sections 87 88 public function display($html,$link=false) 89 { 90 $flagString=$this->flagString(); 91 $path=$this->path; 92 93 if ($html) 94 { 95 if ($this->flags & self::TN_PKG) $link=false; 96 $field= ($link ? '<a href="'.\PHK::subpathURL('/view/' 97 .trim($path,'/')).'">'.$path.'</a>' : $path); 98 echo '<tr><td nowrap>F</td><td nowrap>'.$field.'</td><td nowrap>' 99 .$this->size().'</td><td nowrap>'.$flagString.'</td></tr>'; 100 } 101 else 102 { 103 if ($flagString!='') $flagString = ' ('.$flagString.')'; 104 echo 'F '.str_pad($this->size(),11).' '.$path.$flagString."\n"; 105 } 106 } 107 108 //--- 109 110 public function dump($base) 111 { 112 $path=$base.$this->path; 113 if (file_put_contents($path,$this->read())===false) 114 throw new \Exception($path.': cannot dump file'); 115 } 116 117 //--- 118 119 public function __construct($path,$tree) 120 { 121 parent::__construct($path,$tree); 122 123 $this->dc=new DC(); 124 $this->dc->setFspace($tree->fspace); 125 } 126 127 //--- 128 129 public function import($edata) 130 { 131 $this->dc->import(parent::import($edata)); 132 } 133 134 //--- 135 136 public function setFlags($flags) 137 { 138 parent::setFlags($flags); 139 $this->dc->setFlags($flags); 140 } 141 142 //--- 143 // <CREATOR> //--------------- 144 145 // If PHK Package, move required extensions up 146 // Don't umount the package, it will be used later. 147 148 public function getNeededExtensions(\PHK\Build\Creator $phk 149 ,\PHK\Tools\ItemLister $item_lister) 150 { 151 if (\PHK::dataIsPackage($this->read())) 152 { 153 $mnt=require($phk->uri($this->path)); 154 $source_phk=\PHK\Mgr::instance($mnt); 155 if (!is_null($elist=$source_phk->option('required_extensions'))) 156 { 157 foreach ($elist as $ext) $item_lister->add($ext,true); 158 } 159 160 } 161 162 return $this->dc->getNeededExtensions($phk,$item_lister); // Now, ask DC 163 } 164 165 //--------------- 166 // Process PHP scripts (Automap and source stripping) 167 // Register Automap symbols only if $map is non-null 168 // Distinction between files and sections: for files, $map is not null 169 170 public function export(\PHK\Build\Creator $phk,\PHK\Build\DataStacker $stacker,$map) 171 { 172 $path=$this->path; 173 $rpath=substr($path,1); // Remove leading '/'; 174 175 \PHK\Tools\Util::trace('Processing '.$path); 176 177 if (!is_null($map)) // This is a real file 178 { 179 if (getenv('PHK_NO_STRIP')!==false) $this->flags &= ~self::TN_STRIP_SOURCE; 180 181 if (\PHK::dataIsPackage($this->read())) //-- Package ? 182 { 183 //-- Set 'package' flag, clear 'strip source', and keep autoload 184 $this->flags |= self::TN_PKG; 185 $this->flags &= ~self::TN_STRIP_SOURCE; 186 } 187 188 //-- If it is a sub-package and autoload is true, merge its symbols 189 //-- in the current map, but with different values. 190 191 if ($this->flags & self::TN_PKG) 192 { 193 if (!($this->flags & self::TN_NO_AUTOLOAD)) 194 { 195 \PHK\Tools\Util::trace("Registering Automap symbols from PHK package"); 196 $map->registerPhkPkg($phk->uri($path),$rpath); 197 } 198 } 199 elseif ($phk->isPHPSourcePath($path)) 200 { 201 //--- Register in automap 202 if (!($this->flags & self::TN_NO_AUTOLOAD)) 203 { 204 \PHK\Tools\Util::trace(" Registering Automap symbols"); 205 $map->registerScriptFile($phk->uri($path),$rpath); 206 } 207 208 $this->processPHPScript(); //--- Script pre-processor 209 } 210 else 211 { 212 $this->flags = ($this->flags & ~self::TN_STRIP_SOURCE) 213 | self::TN_NO_AUTOLOAD; 214 } 215 } 216 217 return $this->nodeExport($this->dc->export($phk,$stacker)); 218 } 219 220 //--------------- 221 // Called only for PHP scripts. Replaces current data buffer 222 223 const ST_OUT=0; 224 const ST_ADD=1; 225 const ST_IGNORE=2; 226 227 private function processPHPScript() 228 { 229 $buf=$this->read(); 230 231 //--- Normalize line breaks (Unix-style) 232 233 $buf=preg_replace("/\r+\n/","\n",$buf); 234 $buf=str_replace("\r","\n",$buf); 235 236 //--- Process '// <PHK:' directives 237 238 $rbuf=$buf; 239 $buf=''; 240 $lnum=0; 241 $state=self::ST_OUT; 242 $regs=null; 243 foreach(explode("\n",$rbuf) as $line) 244 { 245 $lnum++; 246 if (preg_match(',^\s*//\s*<PHK:(\S+)>,',$line,$regs)) 247 { 248 $keyword=strtolower($regs[1]); 249 switch ($keyword) 250 { 251 case 'end': 252 $state=self::ST_OUT; 253 break; 254 case 'ignore': 255 $state=self::ST_IGNORE; 256 break; 257 case 'add': 258 $state=self::ST_ADD; 259 break; 260 default: 261 throw new \Exception($this->path."($lnum): Unknown preprocessor keyword: $keyword - valid keywords are ignore, add, end - ignoring line"); 262 } 263 continue; 264 } 265 if ($state==self::ST_IGNORE) continue; 266 if ($state==self::ST_ADD) 267 { 268 $line=ltrim($line); 269 if (strlen($line)!=0) // Ignore empty lines 270 { 271 if ((strlen($line)>=2)&&(substr($line,0,2)==='//')) 272 $line=substr($line,2); 273 else throw new \Exception($this->path."($lnum): in an 'add' block, line should start with '//' - copying line as-is"); 274 } 275 } 276 $buf .= $line."\n"; 277 } 278 $buf=substr($buf,0,-1); 279 280 //--- Strip 281 282 if ($this->flags & self::TN_STRIP_SOURCE) 283 { 284 // \PHK\Tools\Util::msg(" Stripping script"); 285 $buf=self::stripWhitespaces($buf); 286 } 287 288 $this->setData($buf); 289 } 290 291 //--------------- 292 293 /** 294 * Removes whitespace from a PHP source string while preserving line numbers. 295 * 296 * Taken from composer 297 * 298 * @param string $source A PHP string 299 * @return string The PHP string with the whitespace removed 300 */ 301 302 public static function stripWhitespaces($source) 303 { 304 $output = ''; 305 306 foreach (token_get_all($source) as $token) 307 { 308 if (is_string($token)) 309 { 310 $output .= $token; 311 } 312 elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) 313 { 314 $output .= str_repeat("\n", substr_count($token[1], "\n")); 315 } 316 elseif (T_WHITESPACE === $token[0]) 317 { 318 // reduce wide spaces 319 $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]); 320 // normalize newlines to \n 321 $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace); 322 // trim leading spaces 323 $whitespace = preg_replace('{\n +}', "\n", $whitespace); 324 $output .= $whitespace; 325 } 326 else 327 { 328 $output .= $token[1]; 329 } 330 } 331 332 return $output; 333 } 334 335 // </CREATOR> //--------------- 336 337 //--- 338 } // End of class 339 //=========================================================================== 340 } // End of class_exists 341 //=========================================================================== 342 } // End of namespace 343 //=========================================================================== 344 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jun 4 18:33:15 2015 | Cross-referenced by PHPXref 0.7.1 |