1<?php 2/** 3 * Parser for XML based extension desription files 4 * 5 * PHP versions 5 6 * 7 * LICENSE: This source file is subject to version 3.0 of the PHP license 8 * that is available through the world-wide-web at the following URI: 9 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 10 * the PHP License and are unable to obtain it through the web, please 11 * send a note to license@php.net so we can mail you a copy immediately. 12 * 13 * @category Tools and Utilities 14 * @package CodeGen 15 * @author Hartmut Holzgraefe <hartmut@php.net> 16 * @copyright 2005-2008 Hartmut Holzgraefe 17 * @license http://www.php.net/license/3_0.txt PHP License 3.0 18 * @version CVS: $Id: ExtensionParser.php,v 1.19 2007/05/06 08:11:57 hholzgra Exp $ 19 * @link http://pear.php.net/package/CodeGen 20 */ 21 22 23/** 24 * includes 25 */ 26require_once "CodeGen/XmlParser.php"; 27require_once "CodeGen/Tools/Indent.php"; 28require_once "CodeGen/Tools/Group.php"; 29 30/** 31 * Parser for XML based extension desription files 32 * 33 * @category Tools and Utilities 34 * @package CodeGen 35 * @author Hartmut Holzgraefe <hartmut@php.net> 36 * @copyright 2005-2008 Hartmut Holzgraefe 37 * @license http://www.php.net/license/3_0.txt PHP License 3.0 38 * @version Release: @package_version@ 39 * @link http://pear.php.net/package/CodeGen 40 */ 41abstract class CodeGen_ExtensionParser 42 extends CodeGen_XmlParser 43{ 44 /** 45 * The extension to parse specs into 46 * 47 * @access private 48 * @var object 49 */ 50 protected $extension; 51 52 /** 53 * Group stack 54 * 55 * @var array 56 */ 57 protected $groups = array(); 58 59 function pushGroup(CodeGen_Tools_Group $group) 60 { 61 $currentGroup = end($this->groups); 62 if ($currentGroup) { 63 $group->setParent($currentGroup); 64 } 65 array_push($this->groups, $group); 66 67 return true; 68 } 69 70 function popGroup() 71 { 72 array_pop($this->groups); 73 } 74 75 function getGroupAttribute($name) 76 { 77 $currentGroup = end($this->groups); 78 if ($currentGroup) { 79 return $currentGroup->getAttribute($name); 80 } else { 81 return false; 82 } 83 } 84 85 function getGroupAttributeStack($name) 86 { 87 $currentGroup = end($this->groups); 88 if ($currentGroup) { 89 return $currentGroup->getAttributeStack($name); 90 } else { 91 return false; 92 } 93 } 94 95 function tagstart_extension_group($attr) 96 { 97 $group = new CodeGen_Tools_Group(); 98 $group->setAttributes($attr); 99 100 return $this->pushGroup($group); 101 } 102 103 function tagstart_group_group($attr) 104 { 105 return $this->tagstart_extension_group($attr); 106 } 107 108 function tagend_extension_group($attr, $data) 109 { 110 $this->popGroup(); 111 112 return true; 113 } 114 115 function tagend_group_group($attr, $data) 116 { 117 return $this->tagend_extension_group($attr, $data); 118 } 119 120 /** 121 * Constructor 122 * 123 * @access public 124 * @param object the extension to parse specs into 125 */ 126 function __construct($extension) 127 { 128 parent::__construct(); 129 $this->extension = $extension; 130 } 131 132 /** 133 * Handle <extension> 134 * 135 * @access private 136 * @param array attribute/value pairs 137 * @return bool success status 138 */ 139 function tagstart_extension($attr) 140 { 141 $err = $this->checkAttributes($attr, array("name", "prefix", "version")); 142 if (PEAR::isError($err)) { 143 return $err; 144 } 145 146 if (!isset($attr["name"])) { 147 return PEAR::raiseError("needed attribute 'name' for <extension> not given"); 148 } 149 $err = $this->extension->setName(trim($attr["name"])); 150 if (PEAR::isError($err)) { 151 return $err; 152 } 153 154 if (isset($attr["prefix"])) { 155 $err = $this->extension->setPrefix(trim($attr["prefix"])); 156 if (PEAR::isError($err)) { 157 return $err; 158 } 159 } 160 161 if (isset($attr["version"])) { 162 $err = $this->extension->setVersion($attr["version"]); 163 if (PEAR::isError($err)) { 164 return $err; 165 } 166 } else { 167 error_log("Warning: no 'version' attribute given for <extension>, assuming ".$this->extension->version()."\n". 168 " this may lead to compile errors if your spec file was created for an older version"); 169 } 170 171 return true; 172 } 173 174 /** 175 * Handle <extension><name> 176 * 177 * @access private 178 * @param array attribute/value pairs 179 * @return bool success status 180 */ 181 function tagstart_extension_name($attr) 182 { 183 return PEAR::raiseError("extension <name> tag is no longer supported, use <extension>s 'name=...' attribute instead"); 184 } 185 186 187 /** 188 * Handle <extension><summary> 189 * 190 * @access private 191 * @param array attribute/value pairs 192 * @return bool success status 193 */ 194 function tagstart_extension_summary($attr) 195 { 196 return $this->noAttributes($attr); 197 } 198 199 /** 200 * Handle <extension></summary> 201 * 202 * @access private 203 * @param array attribute/value pairs 204 * @param array tag data content 205 * @return bool success status 206 */ 207 function tagend_extension_summary($attr, $data) 208 { 209 return $this->extension->setSummary(CodeGen_Tools_Indent::linetrim($data)); 210 } 211 212 /** 213 * Handle <extension><description> 214 * 215 * @access private 216 * @param array attribute/value pairs 217 * @return bool success status 218 */ 219 function tagstart_extension_description($attr) 220 { 221 return $this->noAttributes($attr); 222 } 223 224 /** 225 * Handle <extension></description> 226 * 227 * @access private 228 * @param array attribute/value pairs 229 * @param array tag data content 230 * @return bool success status 231 */ 232 function tagend_extension_description($attr, $data) 233 { 234 return $this->extension->setDescription(CodeGen_Tools_Indent::linetrim($data)); 235 } 236 237 function tagstart_extension_maintainer($attr) 238 { 239 $this->pushHelper(new CodeGen_Maintainer); 240 return $this->noAttributes($attr);; 241 } 242 243 function tagstart_maintainers_maintainer($attr) 244 { 245 return $this->tagstart_extension_maintainer($attr); 246 } 247 248 function tagstart_group_maintainer($attr) 249 { 250 return $this->tagstart_extension_maintainer($attr); 251 } 252 253 function tagstart_maintainer_user($attr) 254 { 255 return $this->noAttributes($attr);; 256 } 257 258 function tagend_maintainer_user($attr, $data) 259 { 260 return $this->helper->setUser(trim($data)); 261 } 262 263 function tagstart_maintainer_name($attr) 264 { 265 return $this->noAttributes($attr);; 266 } 267 268 function tagend_maintainer_name($attr, $data) 269 { 270 return $this->helper->setName(trim($data)); 271 } 272 273 function tagstart_maintainer_email($attr) 274 { 275 return $this->noAttributes($attr);; 276 } 277 278 function tagend_maintainer_email($attr, $data) 279 { 280 return $this->helper->setEmail(trim($data)); 281 } 282 283 function tagstart_maintainer_role($attr) 284 { 285 return $this->noAttributes($attr);; 286 } 287 288 function tagend_maintainer_role($attr, $data) 289 { 290 return $this->helper->setRole(trim($data)); 291 } 292 293 function tagend_maintainer($attr, $data) 294 { 295 $err = $this->extension->addAuthor($this->helper); 296 $this->popHelper(); 297 return $err; 298 } 299 300 function tagend_maintainers($attr, $data) 301 { 302 return true; 303 } 304 305 function tagstart_extension_release($attr) 306 { 307 $this->pushHelper(new CodeGen_Release); 308 return $this->noAttributes($attr);; 309 } 310 311 function tagstart_group_release($attr) 312 { 313 $this->tagstart_extension_release($attr); 314 } 315 316 function tagstart_release_version($attr) 317 { 318 return $this->noAttributes($attr);; 319 } 320 321 function tagend_release_version($attr, $data) 322 { 323 return $this->helper->setVersion(trim($data)); 324 } 325 326 function tagstart_release_date($attr) 327 { 328 return $this->noAttributes($attr);; 329 } 330 331 function tagend_release_date($attr, $data) 332 { 333 return $this->helper->setDate(trim($data)); 334 } 335 336 function tagstart_release_state($attr) 337 { 338 return $this->noAttributes($attr);; 339 } 340 341 function tagend_release_state($attr, $data) 342 { 343 return $this->helper->setState(trim($data)); 344 } 345 346 function tagstart_release_notes($attr) 347 { 348 return $this->noAttributes($attr);; 349 } 350 351 function tagend_release_notes($attr, $data) 352 { 353 return $this->helper->setNotes(CodeGen_Tools_Indent::linetrim($data)); 354 } 355 356 function tagend_release($attr, $data) 357 { 358 $err = $this->extension->setRelease($this->helper); 359 $this->popHelper(new CodeGen_Release); 360 return $err; 361 } 362 363 function tagstart_extension_changelog($attr) 364 { 365 $this->verbatim(); 366 return $this->noAttributes($attr);; 367 } 368 369 function tagstart_group_changelog($attr) 370 { 371 $this->tagstart_extension_changelog($attr); 372 } 373 374 function tagend_changelog($attr, $data) 375 { 376 return $this->extension->setChangelog(CodeGen_Tools_Indent::linetrim($data)); 377 } 378 379 380 function tagend_extension_license($attr, $data) 381 { 382 $license = CodeGen_License::factory(trim($data)); 383 384 if (PEAR::isError($license)) { 385 return $license; 386 } 387 388 return $this->extension->setLicense($license); 389 } 390 391 function tagend_group_license($attr, $data) 392 { 393 return $this->tagend_extension_license($attr, $data); 394 } 395 396 function tagend_extension_code($attr, $data) 397 { 398 $err = $this->checkAttributes($attr, array("role", "position")); 399 if (PEAR::isError($err)) { 400 return $err; 401 } 402 403 $role = isset($attr["role"]) ? $attr["role"] : "code"; 404 $position = isset($attr["position"]) ? $attr["position"] : "bottom"; 405 406 if (isset($attr["src"])) { 407 return $this->extension->addCode($role, $position, CodeGen_Tools_Indent::linetrim(file_get_contents($attr["src"]))); 408 } else { 409 return $this->extension->addCode($role, $position, CodeGen_Tools_Indent::linetrim($data)); 410 } 411 } 412 413 function tagend_group_code($attr, $data) 414 { 415 return $this->tagend_extension_code($attr, $data); 416 } 417 418 function tagstart_extension_deps($attr) 419 { 420 $err = $this->checkAttributes($attr, array("platform", "language")); 421 if (PEAR::isError($err)) { 422 return $err; 423 } 424 425 if (isset($attr["platform"])) { 426 $err = $this->extension->setPlatform($attr["platform"]); 427 if (PEAR::isError($err)) { 428 return $err; 429 } 430 } 431 432 if (isset($attr["language"])) { 433 $err = $this->extension->setLanguage($attr["language"]); 434 if (PEAR::isError($err)) { 435 return $err; 436 } 437 } 438 439 } 440 441 function tagstart_group_deps($attr) 442 { 443 return $this->tagstart_extension_deps($attr); 444 } 445 446 function tagstart_deps_file($attr) 447 { 448 $err = $this->checkAttributes($attr, array("name", "dir")); 449 if (PEAR::isError($err)) { 450 return $err; 451 } 452 453 if (!isset($attr['name'])) { 454 return PEAR::raiseError("name attribut for file missing"); 455 } 456 457 if (isset($attr["dir"])) { 458 return $this->extension->addSourceFile($attr['name'], $attr['dir']); 459 } else { 460 return $this->extension->addSourceFile($attr['name']); 461 } 462 } 463 464 function tagstart_deps_lib($attr) 465 { 466 $err = $this->checkAttributes($attr, array("name", "platform", "function")); 467 if (PEAR::isError($err)) { 468 return $err; 469 } 470 471 if (!isset($attr['name'])) { 472 return PEAR::raiseError("name attribut for lib missing"); 473 } 474 475 // TODO need to use addLibs(), libs[] is protected 476 $this->extension->libs[$attr['name']] = $attr; 477 if (isset($attr['platform'])) { 478 $platform = new CodeGen_Tools_Platform($attr["platform"]); 479 } else { 480 $platform = new CodeGen_Tools_Platform("all"); 481 } 482 483 if (PEAR::isError($platform)) { 484 return $platform; 485 } 486 487 $this->extension->libs[$attr['name']]['platform'] = $platform; 488 return true; 489 } 490 491 function tagstart_deps_header($attr) 492 { 493 $err = $this->checkAttributes($attr, array("name", "prepend", "path")); 494 if (PEAR::isError($err)) { 495 return $err; 496 } 497 498 // TODO check name 499 $header = new CodeGen_Dependency_Header($attr["name"]); 500 501 if (isset($attr['path'])) { 502 $header->setPath($attr["path"]); 503 } 504 505 if (isset($attr['prepend'])) { 506 $header->setPrepend($attr["prepend"]); 507 } 508 509 $this->extension->addHeader($header); 510 } 511 512 function tagstart_deps_define($attr) { 513 if (!isset($attr["name"])) { 514 return PEAR::raiseError("name attribut for define missing"); 515 } 516 517 return $this->extension->addDefine($attr['name'], @$attr['value'], @$attr['comment']); 518 } 519 520 function tagend_extension_makefile($attr, $data) { 521 return $this->extension->addMakeFragment(CodeGen_Tools_IndentC::linetrim($data)); 522 } 523 524 function tagend_group_makefile($attr, $data) 525 { 526 return $this->tagend_extension_makefile($attr, $data); 527 } 528 529 function tagend_extension_acinclude($attr, $data) { 530 $position = isset($attr["position"]) ? $attr["position"] : "bottom"; 531 return $this->extension->addAcIncludeFragment($data, $position); 532 } 533 534 function tagend_group_acinclude($attr, $data) 535 { 536 return $this->tagend_extension_acinclude($attr, $data); 537 } 538 539 function tagend_deps_configm4($attr, $data) { 540 return $this->extension->addConfigFragment(CodeGen_Tools_IndentC::linetrim($data), 541 isset($attr['position']) ? $attr['position'] : "top"); 542 } 543 544 function tagend_group_configm4($attr, $data) 545 { 546 return $this->tagend_extension_configm4($attr, $data); 547 } 548} 549 550 551/* 552 * Local variables: 553 * tab-width: 4 554 * c-basic-offset: 4 555 * indent-tabs-mode:nil 556 * End: 557 */ 558?> 559