[ 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\Build\PSF { 27 28 if (!class_exists('PHK\Build\PSF\Parser',false)) 29 { 30 //============================================================================= 31 /** 32 * The PSF parser 33 * 34 * API status: Private 35 * Included in the PHK PHP runtime: No 36 * Implemented in the extension: No 37 *///========================================================================== 38 39 class Parser 40 { 41 private $path; // PSF absolute path 42 43 private $vars; // Variables 44 45 private $line_nb; 46 47 //--------- 48 49 private function __construct($path,$vars) 50 { 51 $this->path=$path; 52 $this->vars=$vars; 53 } 54 55 //---- \Exception with file name and line number 56 // Can be called recursively. So, we decorate the message only once 57 58 private function sendError($msg) 59 { 60 if (($msg!='') && ($msg{0}=='>')) throw new \Exception($msg); 61 else throw new \Exception('> '.$this->path.'(line '.$this->line_nb.') : '.$msg); 62 } 63 64 //---- Read a line with continuation '\' and strip comments (#) + trim() 65 //---- Returns false on EOF 66 67 private function getLine($fp) 68 { 69 $line=''; 70 71 while (true) 72 { 73 $this->line_nb++; 74 if (($line1=fgets($fp))===false) // EOF 75 { 76 if ($line=='') return null; 77 else $this->sendError('Unexpected EOF'); // If it was a continuation 78 } 79 if (($pos=strpos($line1,'#'))!==false) // Remove comments 80 $line1=substr($line1,0,$pos); 81 $line1=trim($line1); 82 if ($line1=='') continue; 83 84 if ($line1[strlen($line1)-1]=='\\') // Continued on next line 85 { 86 $cont=true; 87 $line1=substr($line1,0,-1); // Remove \ at EOL 88 $line .=' '; // As we trim every line, add a space for continuation 89 } 90 else $cont=false; 91 $line .= $line1; 92 if ($cont) continue; 93 //-- Variables substitution 94 95 while (($pos=strpos($line,'$('))!==false) // always search the whole line 96 { 97 $pos2=strpos($line,')',$pos); 98 if ($pos2==($pos+2)) $this->sendError('Empty variable'); 99 if ($pos2===false) $this->sendError('No variable end'); 100 $var=substr($line,$pos+2,$pos2-($pos+2)); 101 $val=$this->getVar($var); 102 $line=substr_replace($line,$val,$pos,$pos2+1-$pos); 103 } 104 105 //-- Convert tabs to space, Remove leading/trailing blanks, and suppress 106 //-- multiple spaces 107 108 $line=preg_replace('/\s+/',' ',str_replace(' ',' ',trim($line))); 109 110 if ($line!='') break; // Skip empty lines 111 } 112 return $line; 113 } 114 115 //--------- 116 117 private function getVar($name) 118 { 119 if (isset($this->vars[$name])) return $this->vars[$name]; 120 if (($val=getenv($name))!==false) return $val; 121 $this->sendError($name.': reference to undefined variable'); 122 } 123 124 //--------- 125 126 private function setVar($name,$value) 127 { 128 $this->vars[$name]=$value; 129 } 130 131 //--------- 132 // On entry, $phk is a \PHK\Build\Creator object 133 134 public function applyTo($phk) 135 { 136 if (!($phk instanceof \PHK\Build\Creator)) 137 throw new \Exception('Object must be \PHK\Build\Creator'); 138 139 if (!($fp=fopen($this->path,'rb',false))) 140 throw new \Exception($this->path.': Cannot open'); 141 142 $this->line_nb=0; 143 144 try { 145 while (!is_null($line=$this->getLine($fp))) 146 { 147 if ($line{0}==='%') break; // Next block found 148 $op=new CmdOptions; 149 $words=explode(' ',$line); 150 if (!count($words)) throw new \Exception('No command'); 151 $command=strtolower(array_shift($words)); 152 switch($command) 153 { 154 case 'add': // add [-t <target-path>] [-b <target-base>] [-C <dir>] 155 // [-c <compression-scheme>] <source1> [<source2>...] 156 157 $op->parseAll($words); 158 if (count($words)==0) 159 throw new \Exception('Usage: add [options] <path1> [<path2> ...]'); 160 $base_dir=\Phool\File::combinePath(dirname($this->path) 161 ,$op->option('directory')); 162 foreach($words as $spath) 163 { 164 $spath=rtrim($spath,'/'); // Beware of trailing '/' 165 if (is_null($target=$op->option('target-path'))) 166 { 167 if (\Phool\File::isAbsolutePath($spath)) 168 throw new \Exception("$spath: Arg must be a relative path"); 169 $tbase=$op->option('target-base'); 170 if (is_null($tbase)) $tbase=''; 171 $target=$tbase.'/'.$spath; 172 } 173 $sapath=\Phool\File::combinePath($base_dir,$spath); 174 $phk->ftree()->mergeIntoFileTree($target,$sapath,$op->options()); 175 } 176 break; 177 178 case 'modify': 179 $op->parseAll($words); 180 if (count($words)==0) 181 throw new \Exception('Usage: modify [options] <path1> [<path2> ...]'); 182 foreach($words as $tpath) 183 $phk->ftree()->modify($tpath,$op->options()); 184 break; 185 186 case 'mount': 187 if (count($words)!=2) 188 throw new \Exception('Usage: mount <phk-path> <var-name>'); 189 list($path,$mnt_var)=$words; 190 $mnt=\PHK\Mgr::mount($path,\PHK::NO_MOUNT_SCRIPT); 191 $this->setVar($mnt_var,'phk://'.$mnt); 192 break; 193 194 case 'remove': // remove <path> [<path>...] 195 if (count($words)==0) 196 throw new \Exception('Usage: remove <path1> [<path2> ...]'); 197 foreach($words as $tpath) $phk->ftree()->remove(trim($tpath,'/')); 198 break; 199 200 case 'set': 201 if (count($words) < 1) 202 throw new \Exception('Usage: set <var-name> [value]'); 203 $var=array_shift($words); 204 $this->setVar($var,implode(' ',$words)); 205 break; 206 207 case 'section': //-- Undocumented 208 $op->parseAll($words); 209 if (count($words)!=2) 210 throw new \Exception('Usage: section [-C <dir>] <name> <path>'); 211 list($name,$path)=$words; 212 $phk->addSection($name,\Phool\File::readFile($path)); 213 break; 214 215 default: 216 $this->sendError($command.': Unknown command'); 217 } 218 } 219 } catch (\Exception $e) { $this->sendError($e->getMessage()); } 220 221 if (!is_null($line)) // If we met a '%' 222 { 223 // Get package options (metainfo) 224 // Default syntax: YAML 225 226 $op=new MetaOptions; 227 228 $args=explode(' ',$line); 229 $op->parseAll($args); 230 231 $data=''; 232 while (($line=fgets($fp))!==false) $data .= $line; 233 234 switch(strtolower($op->option('syntax'))) 235 { 236 case 'yaml': 237 $options=\Symfony\Component\Yaml\Yaml::parse($data); 238 break; 239 240 case 'json': 241 $json=new Services_JSON(); 242 $options=$json->decode($data); 243 unset($json); 244 break; 245 246 case 'php': 247 $options=\PHK\Stream\Backend::_includeString("<?php\n".$data."\n?>"); 248 break; 249 250 default: 251 throw new \Exception("$syntax: Unknown options syntax"); 252 } 253 254 if (!(is_array($options))) 255 throw new \Exception('Options block should define an array'); 256 $phk->setOptions($options); 257 } 258 259 fclose($fp); 260 } 261 262 //--------- 263 // Build a new PHK package from a PSF file 264 265 public static function build($phk_path,$psf_path,$vars) 266 { 267 //-- Create empty output object 268 269 $phk_path=\Phool\File::mkAbsolutePath($phk_path); 270 $mnt=\PHK\Mgr::mount($phk_path,\PHK::IS_CREATOR); 271 $phk=\PHK\Mgr::instance($mnt); 272 273 if (is_null($psf_path)) // Compute PSF path from PHK path 274 { 275 $base=basename($phk_path); 276 $dotpos=strrpos($base,'.'); 277 if ($dotpos===false) $base=$base.'.psf'; 278 else $base=substr_replace($base,'.psf',$dotpos); 279 $psf_path=dirname($phk_path).'/'.$base; 280 } 281 else // Make PSF path absolute 282 { 283 $psf_path=\Phool\File::mkAbsolutePath($psf_path); 284 } 285 286 //-- Interpret PSF 287 288 $psf=new self($psf_path,$vars); 289 $psf->applyTo($phk); 290 291 //-- Dump to file 292 293 $phk->dump(); 294 } 295 296 //--- 297 } // End of class 298 //=========================================================================== 299 } // End of class_exists 300 //=========================================================================== 301 } // End of namespace 302 //=========================================================================== 303 ?>
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 |