Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Revert "This project is no longer maintained within PEAR CVS,"

This reverts commit 3579cec.
  • Loading branch information...
commit d1498dac431edfb234af2629cc563bc3d353de46 1 parent 3579cec
@CloCkWeRX CloCkWeRX authored
Showing with 22,292 additions and 4 deletions.
  1. +68 −0 LICENSE
  2. +265 −0 PECL/Command.php
  3. +267 −0 PECL/Dependency/Extension.php
  4. +73 −0 PECL/Dependency/Header.php
  5. +123 −0 PECL/Dependency/Lib.php
  6. +84 −0 PECL/Dependency/Platform.php
  7. +425 −0 PECL/Dependency/With.php
  8. +158 −0 PECL/Element.php
  9. +669 −0 PECL/Element/Class.php
  10. +244 −0 PECL/Element/ClassConstant.php
  11. +353 −0 PECL/Element/Constant.php
  12. +1,660 −0 PECL/Element/Function.php
  13. +294 −0 PECL/Element/Global.php
  14. +451 −0 PECL/Element/Ini.php
  15. +307 −0 PECL/Element/Interface.php
  16. +261 −0 PECL/Element/Logo.php
  17. +466 −0 PECL/Element/Method.php
  18. +9 −0 PECL/Element/ObjectInterface.php
  19. +232 −0 PECL/Element/Property.php
  20. +356 −0 PECL/Element/Resource.php
  21. +241 −0 PECL/Element/Stream.php
  22. +464 −0 PECL/Element/Test.php
  23. +2,566 −0 PECL/Extension.php
  24. +1,369 −0 PECL/ExtensionParser.php
  25. +125 −0 PECL/Maintainer.php
  26. +127 −0 PECL/Release.php
  27. +279 −0 PECL/Tools/ProtoLexer.php
  28. +139 −0 PECL/Tools/ProtoLexer.plex
  29. +1,292 −0 PECL/Tools/ProtoParser.php
  30. +105 −0 PECL/Tools/ProtoParser.y
  31. +8 −4 README
  32. +90 −0 TODO
  33. +8 −0 docs/Makefile
  34. +44 −0 docs/RFC_proto.txt
  35. +4 −0 docs/examples/Makefile
  36. +73 −0 docs/examples/README
  37. +45 −0 docs/examples/api_functions.xml
  38. +275 −0 docs/examples/cairo.xml
  39. +24 −0 docs/examples/class_abstract.xml
  40. +25 −0 docs/examples/class_constant.xml
  41. +18 −0 docs/examples/class_extends.xml
  42. +80 −0 docs/examples/class_methods.xml
  43. +69 −0 docs/examples/class_methods_abstract.xml
  44. +26 −0 docs/examples/class_methods_final.xml
  45. +9 −0 docs/examples/class_minimal.xml
  46. +77 −0 docs/examples/class_payload.xml
  47. +232 −0 docs/examples/class_properties.xml
  48. +47 −0 docs/examples/class_type_hints.xml
  49. +9 −0 docs/examples/code_pi.xml
  50. +21 −0 docs/examples/constants.xml
  51. +11 −0 docs/examples/crossext.xml
  52. +70 −0 docs/examples/function_by_ref.xml
  53. +41 −0 docs/examples/function_type_hints.xml
  54. +31 −0 docs/examples/globals.xml
  55. +82 −0 docs/examples/interface.xml
  56. +53 −0 docs/examples/interface_simple.xml
  57. +5 −0 docs/examples/license.xml
  58. +3 −0  docs/examples/minimal.xml
  59. +20 −0 docs/examples/parsing.xml
  60. +1 −0  docs/examples/parsing_1.inc
  61. +3 −0  docs/examples/parsing_2.inc
  62. +17 −0 docs/examples/phpini.xml
  63. +57 −0 docs/examples/release.xml
  64. +56 −0 docs/examples/resource.xml
  65. +48 −0 docs/examples/resource_cpp.xml
  66. +56 −0 docs/examples/resource_old.xml
  67. +3 −0  docs/examples/snippet.c
  68. +3 −0  docs/examples/snippet1.c
  69. +3 −0  docs/examples/snippet2.c
  70. +29 −0 docs/examples/test.sh
  71. +37 −0 docs/examples/testcase.xml
  72. +8 −0 docs/examples/with_1.xml
  73. +194 −0 docs/extension.dtd
  74. +4,331 −0 docs/manual.html
  75. BIN  docs/manual.pdf
  76. +1,922 −0 docs/manual.xml
  77. +504 −0 package2.xml
  78. +48 −0 pecl-gen
View
68 LICENSE
@@ -0,0 +1,68 @@
+--------------------------------------------------------------------
+ The PHP License, Version 3.0
+Copyright (c) 1999 - 2003 The PHP Group. All rights reserved.
+--------------------------------------------------------------------
+
+Redistribution and use in source and binary forms, with or without
+modification, is permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ 3. The name "PHP" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact group@php.net.
+
+ 4. Products derived from this software may not be called "PHP", nor
+ may "PHP" appear in their name, without prior written permission
+ from group@php.net. You may indicate that your software works in
+ conjunction with PHP by saying "Foo for PHP" instead of calling
+ it "PHP Foo" or "phpfoo"
+
+ 5. The PHP Group may publish revised and/or new versions of the
+ license from time to time. Each version will be given a
+ distinguishing version number.
+ Once covered code has been published under a particular version
+ of the license, you may always continue to use it under the terms
+ of that version. You may also choose to use such covered code
+ under the terms of any subsequent version of the license
+ published by the PHP Group. No one other than the PHP Group has
+ the right to modify the terms applicable to covered code created
+ under this License.
+
+ 6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes PHP, freely available from
+ <http://www.php.net/>".
+
+THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
+ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
+DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--------------------------------------------------------------------
+
+This software consists of voluntary contributions made by many
+individuals on behalf of the PHP Group.
+
+The PHP Group can be contacted via Email at group@php.net.
+
+For more information on the PHP Group and the PHP project,
+please see <http://www.php.net>.
+
+This product includes the Zend Engine, freely available at
+<http://www.zend.com>.
View
265 PECL/Command.php
@@ -0,0 +1,265 @@
+<?php
+/**
+ * Command wrapper class
+ *
+ * PHP versions 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/CodeGen
+ */
+
+/**
+ * includes
+ */
+require_once "CodeGen/Command.php";
+
+require_once "CodeGen/PECL/Extension.php";
+require_once "CodeGen/PECL/ExtensionParser.php";
+
+
+/**
+ * Command wrapper class
+ *
+ * This class wraps up the functionality needed for the
+ * command line script.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/CodeGen
+ */
+class CodeGen_PECL_Command
+ extends CodeGen_Command
+{
+ /**
+ * Command constructor
+ *
+ * @param object Extension to work on
+ */
+ function __construct(CodeGen_Extension $extension)
+ {
+ parent::__construct($extension);
+
+ if ($this->options->have("linespecs")) {
+ $this->extension->setLinespecs(true);
+ }
+ }
+
+ /**
+ * Add pecl-gen specific command line options
+ *
+ * @return array extended options
+ */
+ function commandOptions()
+ {
+ list($shortOptions, $longOptions) = parent::commandOptions();
+
+ $longOptions= array_merge($longOptions, array("extname=",
+ "full-xml",
+ "function=",
+ "linespecs",
+ "no-help",
+ "proto=",
+ "skel=",
+ "stubs=",
+ "xml=="));
+
+ return array($shortOptions, $longOptions);
+ }
+
+ /**
+ * Show usage/help information
+ *
+ * @param string otpional additional message
+ */
+ function showUsage($message = false)
+ {
+ $fp = fopen("php://stderr", "w");
+
+ if ($message) fputs($fp, "$message\n\n");
+
+ fputs($fp, "Usage:
+
+pecl-gen [-h] [--force] [--experimental] [--version]
+ [--extname=name] [--proto=file] [--skel=dir] [--stubs=file]
+ [--no-help] [--xml[=file]] [--full-xml] [--function=proto] [specfile.xml]
+
+ -h|--help this message
+ -f|--force overwrite existing directories
+ -d|--dir output directory (defaults to extension name)
+ -l|--lint check syntax only, don't create output
+ --linespecs generate #line specs
+ -x|--experimental deprecated
+ --function create a function skeleton from a proto right away
+ --version show version info
+
+ the following options are inherited from ext_skel:
+ --extname=module module is the name of your extension
+ --proto=file file contains prototypes of functions to create
+ --xml generate xml documentation to be added to phpdoc-cvs
+
+ these wait for functionality to be implemented and are ignored for now ...
+ --stubs=file generate only function stubs in file
+ --no-help don't try to be nice and create comments in the code
+ and helper functions to test if the module compiled
+
+ these are accepted for backwards compatibility reasons but not used ...
+ --full-xml generate xml documentation for a self-contained extension
+ (this was also a no-op in ext_skel)
+ --skel=dir path to the skeleton directory
+ (skeleton stuff is now self-contained)
+");
+
+ fclose($fp);
+ }
+
+
+ /**
+ * Generate just a single function stub file
+ *
+ */
+ function singleFunction()
+ {
+ $func = new CodeGen_PECL_Element_Function;
+
+ $func->setRole("public");
+
+ $err = $func->setProto(trim($this->options->value("function")), $this->extension);
+ if (PEAR::isError($err)) {
+ $this->terminate($err->getMessage());
+ }
+
+ $err = $this->extension->addFunction($func);
+ if (PEAR::isError($err)) {
+ $this->terminate($err->getMessage());
+ }
+
+ echo $this->extension->publicFunctionsC();
+
+ echo "\n\n/*----------------------------------------------------------------------*/\n\n";
+
+ foreach ($this->extension->getFunctions() as $name => $function) {
+ echo sprintf("\tPHP_FE(%-20s, NULL)\n", $name);
+ }
+
+ echo "\n\n/*----------------------------------------------------------------------*/\n\n";
+
+ foreach ($this->extension->getFunctions() as $name => $function) {
+ echo "PHP_FUNCTION($name);\n";
+ }
+ }
+
+ /**
+ * ext-skel compatibility mode
+ *
+ */
+ function extSkelCompat()
+ {
+ $extname = $this->options->value("extname");
+
+ $err = $this->extension->setName($extname);
+ if (PEAR::isError($err)) {
+ $this->terminate($err->getMessage());
+ }
+
+ if ($this->options->have("proto")) {
+ $proto_file = $this->options->value("proto");
+
+ if (!file_exists($proto_file) || !is_readable($proto_file)) {
+ $this->terminate("cannot open proto file");
+ }
+
+ foreach (file($proto_file) as $line) {
+ $func = new CodeGen_PECL_Element_Function;
+ $func->setRole("public");
+ $err = $func->setProto(trim($line));
+ if (PEAR::isError($err)) {
+ $this->terminate($err->getMessage());
+ }
+
+ $err = $this->extension->addFunction($func);
+ if (PEAR::isError($err)) {
+ $this->terminate($err->getMessage());
+ }
+ }
+ }
+
+ if ($this->options->have("stubs")) {
+ $stubname = $this->options->value("stubs");
+
+ if (file_exists("$stubname") && !$this->options->have("f", "force")) {
+ $this->terminate("'$stubname' already exists (use '--force' to overwrite)");
+ }
+
+ $fp = fopen($stubname, "w");
+ fputs($fp, $this->extension->publicFunctionsC());
+
+ fputs($fp, "\n\n/*----------------------------------------------------------------------*/\n\n");
+
+ foreach ($this->extension->functions as $name => $function) {
+ fputs($fp, sprintf("\tPHP_FE(%-20s, NULL)\n", $name));
+ }
+
+ fputs($fp, "\n\n/*----------------------------------------------------------------------*/\n\n");
+
+ foreach ($this->extension->functions as $name => $function) {
+ fputs($fp, "PHP_FUNCTION($name);\n");
+ }
+
+ fclose($fp);
+
+ echo "$stubname successfully written\n";
+ } else {
+ if (file_exists("./$extname") && !$this->options->have("f", "force")) {
+ $this->terminate("'$extname' already exists, can't create directory (use '--force' to override)");
+ }
+
+ $err = System::mkdir($extname);
+ if (PEAR::isError($err)) {
+ $this->terminate($err->getMessage());
+ }
+
+ $this->extension->dirpath = realpath("./$extname");
+
+ $err = $this->extension->generateSource("./$extname");
+ if (PEAR::isError($err)) {
+ $this->terminate($err->getMessage());
+ }
+
+ if ($this->options->have("xml")) {
+ $manpath = "$extname/manual/". str_replace('_', '-', $extname);
+
+ $err = System::mkdir("-p $manpath");
+ if (PEAR::isError($err)) {
+ $this->terminate($err->getMessage());
+ }
+
+ $err = $this->extension->generateDocumentation($manpath);
+ if (PEAR::isError($err)) {
+ $this->terminate($err->getMessage());
+ }
+ }
+
+ $this->extension->writeReadme("./$extname");
+
+ if (!$this->options->have("quiet")) {
+ echo $this->extension->successMsg();
+ }
+ }
+
+ }
+}
View
267 PECL/Dependency/Extension.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * Class representing a cross-extension dependency
+ *
+ * PHP versions 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/CodeGen
+ */
+
+/**
+ * include
+ */
+require_once "CodeGen/PECL/Element.php";
+
+/**
+ * Class representing a cross-extension dependency
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/CodeGen
+ */
+class CodeGen_PECL_Dependency_Extension
+ extends CodeGen_Element
+{
+ /**
+ * Extension name
+ *
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * name getter
+ *
+ * @return string
+ */
+ function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * name setter
+ *
+ * @param string
+ */
+ function setName($name)
+ {
+ if (!$this->isName($name)) {
+ PEAR::raiseError("'$name' is not a valid extension name ");
+ }
+
+ $this->name = $name;
+ }
+
+
+ /**
+ * Extension version relation
+ *
+ * @var array
+ */
+ protected $version = array();
+
+ /**
+ * version setter
+ *
+ * @param string
+ */
+ function setVersion($version, $relation = "ge")
+ {
+ switch ($relation) {
+ case "ge":
+ case "le":
+ case "gt":
+ case "lt":
+ case "eq":
+ break;
+
+ case ">=":
+ $relation = "ge";
+ break;
+
+ case ">":
+ $relation = "gt";
+ break;
+
+ case "<=":
+ $relation = "le";
+ break;
+
+ case "<":
+ $relation = "lt";
+ break;
+
+ case "=":
+ case "==":
+ $relation = "eq";
+ break;
+
+ default:
+ return PEAR::raiseError("'$relation' is not a valid version relation ");
+ }
+
+ // TODO check version string
+
+ $this->version = array("version" => $version, "relation" => $relation);
+ }
+
+
+ /**
+ * Extension name
+ *
+ * @var string
+ */
+ protected $type = "REQUIRED";
+
+ /**
+ * type setter
+ *
+ * @param string
+ */
+ function setType($type)
+ {
+ $type = strtoupper($type);
+
+ switch ($type) {
+ case "REQUIRED":
+ case "OPTIONAL":
+ case "CONFLICTS":
+ $this->type = $type;
+ break;
+ default:
+ return PEAR::raiseError("'$type' is not a valid dependency type ");
+ }
+ }
+
+ /**
+ * Generate extension C code snippet
+ *
+ * @param object extension
+ * @return string code snippet
+ */
+ function cCode($extension)
+ {
+ if (!empty($this->version)) {
+ return sprintf(' ZEND_MOD_%s_EX("%s", "%s", "%s")', $this->type, $this->name, $this->version["relation"], $this->version["version"])."\n";
+ } else {
+ return sprintf(' ZEND_MOD_%s("%s")', $this->type, $this->name)."\n";
+ }
+ }
+
+ /**
+ * Generate extension C code header
+ *
+ * @param object extension
+ * @return string code snippet
+ */
+ static function cCodeHeader($extension)
+ {
+ return "/* {{{ cross-extension dependencies */\n
+#if ZEND_EXTENSION_API_NO >= 220050617
+static zend_module_dep ".$extension->getName()."_deps[] = {
+";
+ }
+
+ /**
+ * Generate extension C code footer
+ *
+ * @param object extension
+ * @return string code snippet
+ */
+ static function cCodeFooter($extension)
+ {
+ return " {NULL, NULL, NULL, 0}
+};
+#endif
+/* }}} */
+";
+ }
+
+
+ /**
+ * package.xml dependencie entry
+ *
+ * @return string XML snippet
+ */
+ function packageXML()
+ {
+ $xml = ' <dep type="ext"';
+ if (!empty($this->version)) {
+ $xml.= sprintf(' rel="%s" version="%s"', $this->version["relation"], $this->version["version"]);
+ }
+ $xml.= ">{$this->name}</dep>\n";
+
+ return $xml;
+ }
+
+
+
+ /**
+ * package.xml 2.0 dependencie entry
+ *
+ * @param mixed requested type(s), either string or array
+ * @return string XML snippet
+ */
+ function packageXML2($types = false)
+ {
+ $xml = " <extension><name>{$this->name}</name>";
+
+ if (!empty($types)) {
+ $types = (array)$types;
+ if (!in_array($this->type, $types)) {
+ return "";
+ }
+ }
+
+ switch ($this->type ) {
+ case 'REQUIRED':
+ case 'OPTIONAL':
+ if (!empty($this->version)) {
+ $version = $this->version["version"];
+ switch ($this->version["relation"]) {
+ case 'gt':
+ $xml.= "<exclude>$version</exclude>";
+ /* fallthru */
+ case 'ge':
+ $xml.= "<min>$version</min>";
+ break;
+ case 'lt':
+ $xml.= "<exclude>$version</exclude>";
+ /* fallthru */
+ case 'le':
+ $xml.= "<max>$version</max>";
+ break;
+ case 'eq':
+ $xml.= "<min>$version</min>";
+ $xml.= "<max>$version</max>";
+ break;
+ }
+ }
+ break;
+
+ case 'CONFLICTS':
+ $xml.= "<conflicts/>";
+ break;
+ }
+ $xml.= "<extension>\n";
+
+ return $xml;
+ }
+}
View
73 PECL/Dependency/Header.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Class representing a header file dependency
+ *
+ * PHP versions 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen_PECL
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/CodeGen_PECL
+ */
+
+/**
+ * include
+ */
+require_once "CodeGen/Dependency/Header.php";
+
+/**
+ * Class representing a header file dependency
+ *
+ * @category Tools and Utilities
+ * @package CodeGen_PECL
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/CodeGen
+ */
+class CodeGen_PECL_Dependency_Header
+ extends CodeGen_Dependency_Header
+{
+ /**
+ * return config.m4 code snippet for unix builds
+ *
+ * @param string Extension name
+ * @param string --with option name
+ * @return string
+ */
+ function configm4($extname, $withname)
+ {
+ $upname = strtoupper($extname);
+ $withUpname = strtoupper($withname);
+ return " AC_CHECK_HEADER([{$this->name}], [], AC_MSG_ERROR('{$this->name}' header not found))\n";
+ }
+
+ /**
+ * return config.w32 code snippet for windows builds
+ *
+ * @param string Extension name
+ * @param string --with option name
+ * @return string
+ */
+ function configw32($extname, $withname)
+ {
+ $upname = strtoupper($extname);
+ echo "
+ if (!CHECK_HEADER_ADD_INCLUDE(\"{$this->name}\", \"CFLAGS_$upname\")) {
+ ERROR(\"{$extname}: header '{$this->name}' not found\");
+ }
+";
+ }
+}
+
+?>
View
123 PECL/Dependency/Lib.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Class representing a library dependency
+ *
+ * PHP versions 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen_PECL
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/CodeGen
+ */
+
+/**
+ * include
+ */
+require_once "CodeGen/Dependency/Lib.php";
+require_once "CodeGen/PECL/Dependency/Platform.php";
+
+/**
+ * Class representing a library dependencyp
+ *
+ * @category Tools and Utilities
+ * @package CodeGen_PECL
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/CodeGen
+ */
+class CodeGen_PECL_Dependency_Lib
+ extends CodeGen_Dependency_Lib
+{
+ /**
+ * Constructor
+ *
+ * @param string library basename
+ * @param string platform name
+ */
+ function __construct($name, $platform = "all")
+ {
+ // TODO check name
+ $this->name = $name;
+
+ $this->platform = new CodeGen_PECL_Dependency_Platform($platform);
+ }
+
+ /**
+ * write config.m4 code snippet for unix builds
+ *
+ * @param string Extension name
+ * @param string --with option name
+ * @return string code snippet
+ */
+ function configm4($extName, $withName)
+ {
+ static $first = true;
+
+ $extUpname = strtoupper($extName);
+ $withUpname = str_replace("-", "_", strtoupper($withName));
+
+ if (!$this->platform->test("unix")) {
+ return "";
+ }
+
+ $ret = "";
+
+ if ($first) {
+ $ret.= " PHP_SUBST({$extUpname}_SHARED_LIBADD)\n\n";
+ $first = false;
+ }
+
+ if ($this->function) {
+ $ret.= "
+ PHP_CHECK_LIBRARY({$this->name}, {$this->function},
+ [
+ PHP_ADD_LIBRARY_WITH_PATH({$this->name}, \$PHP_{$withUpname}_DIR/{$this->path}, {$extUpname}_SHARED_LIBADD)
+ ],[
+ AC_MSG_ERROR([wrong {$this->name} lib version or lib not found])
+ ],[
+ -L\$PHP_{$withUpname}_DIR/{$this->path}
+ ])
+";
+ } else {
+ $ret.= " PHP_ADD_LIBRARY_WITH_PATH({$this->name}, \$PHP_{$withUpname}_DIR/{$this->path}, {$extUpname}_SHARED_LIBADD)\n";
+
+ }
+
+ return $ret;
+ }
+
+ /**
+ * write config.w32 code snippet for windows builds
+ *
+ * @param string Extension name
+ * @param string --with option name
+ * @return string code snippet
+ */
+ function configw32($extName, $withName)
+ {
+ if (!$this->platform->test("windows")) {
+ return "";
+ }
+
+ $extUpname = strtoupper($extName);
+
+ return "
+ if (!CHECK_LIB(\"{$this->name}.lib\", \"{$extName}\", PHP_$extUpname)) {
+ ERROR(\"{$extName}: library '{$this->name}' not found\");
+ }
+";
+ }
+}
+
+?>
View
84 PECL/Dependency/Platform.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Class representing a platform dependency
+ *
+ * PHP versions 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen_PECL
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/CodeGen_PECL
+ */
+
+/**
+ * include
+ */
+require_once "CodeGen/Tools/Platform.php";
+
+/**
+ * Class representing a platform dependency
+ *
+ * @category Tools and Utilities
+ * @package CodeGen_PECL
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/CodeGen_PECL
+ */
+class CodeGen_PECL_Dependency_Platform
+ extends CodeGen_Tools_Platform
+{
+ /**
+ * package.xml dependencie entry
+ *
+ * @return string XML snippet
+ */
+ function packageXML()
+ {
+ if ($this->test("all")) return "";
+
+ $xml = "";
+
+ if ($this->test("windows")) {
+ $xml.= " <dep type='os' rel='has' name='windows'/>\n";
+ }
+
+ if ($this->test("unix")) {
+ $xml.= " <dep type='os' rel='has' name='unix'/>\n";
+ }
+
+ return $xml;
+ }
+
+ /**
+ * package.xml 2.0 dependencie entry
+ *
+ * @return string XML snippet
+ */
+ function packageXML2()
+ {
+ if ($this->test("all")) return "";
+
+ $xml = "";
+
+ if ($this->test("windows")) {
+ $xml.= " <os><name>windows</name></os>\n";
+ }
+
+ if ($this->test("unix")) {
+ $xml.= " <os><name>unix</name></os>\n";
+ }
+
+ return $xml;
+ }
+}
View
425 PECL/Dependency/With.php
@@ -0,0 +1,425 @@
+<?php
+/**
+ * Class representing a --with configure option
+ *
+ * PHP versions 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/CodeGen
+ */
+
+/**
+ * include
+ */
+require_once "CodeGen/PECL/Element.php";
+
+/**
+ * Class representing a --with configure option
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/CodeGen
+ */
+class CodeGen_PECL_Dependency_With
+ extends CodeGen_Element
+{
+ /**
+ * Set option name
+ *
+ * @var name
+ * @access private
+ */
+ protected $name = false;
+
+ /**
+ * Short Summary
+ *
+ * @var string
+ * @access private
+ */
+ protected $summary = "";
+
+ /**
+ * Long Description
+ *
+ * @var string
+ * @access private
+ */
+ protected $description = "";
+
+ /**
+ * A file to test for to check a given argument path
+ *
+ * @var string
+ * @access private
+ */
+ protected $testfile = false;
+
+ /**
+ * Default search path
+ *
+ * @var string
+ * @access private
+ */
+ protected $defaults = "/usr:/usr/local";
+
+ /**
+ * dependant libraries
+ *
+ * @var string
+ * @access private
+ */
+ protected $libs = array();
+
+
+ /**
+ * dependant header files
+ *
+ * @var string
+ * @access private
+ */
+ protected $headers = array();
+
+ /**
+ * operation mode
+ *
+ * @var string
+ */
+ protected $mode = "default";
+
+ /**
+ * required version
+ *
+ * @var string
+ */
+ protected $version = "";
+
+ /**
+ * name getter
+ *
+ * @param string
+ */
+ function getName()
+ {
+ return $this->name;
+ }
+
+
+ /**
+ * name setter
+ *
+ * @param string
+ */
+ function setName($name)
+ {
+ if (!preg_match('|^[a-z][a-z0-9_-]*$|i', $name)) {
+ return PEAR::raiseError("'$name' is not a valid --with option name");
+ }
+
+ $this->name = $name;
+
+ return true;
+ }
+
+ /**
+ * summary setter
+ *
+ * @param string
+ */
+ function setSummary($text)
+ {
+ $this->summary = trim($text);
+
+ return true;
+ }
+
+ /**
+ * summary getter
+ *
+ * @return string
+ */
+ function getSummary()
+ {
+ return $this->summary ? $this->summary : "whether {$this->name} is available";
+ }
+
+ /**
+ * description setter
+ *
+ * @param string
+ */
+ function setDescription($text)
+ {
+ $this->description = $text;
+
+ return true;
+ }
+
+ /**
+ * testfile setter
+ *
+ * @param string
+ */
+ function setTestfile($path)
+ {
+ $this->testfile = $path;
+ }
+
+ /**
+ * testfile getter
+ *
+ * @return string
+ */
+ function getTestfile()
+ {
+ return $this->testfile;
+ }
+
+ /**
+ * default searchpath setter
+ *
+ * @param string
+ */
+ function setDefaults($defaults)
+ {
+ $this->defaults = $defaults;
+ }
+
+ /**
+ * default searchpath getter
+ *
+ * @return string
+ */
+ function getDefaults()
+ {
+ return $this->defaults;
+ }
+
+ /**
+ * mode setter
+ *
+ * @param string
+ */
+ function setMode($mode)
+ {
+ switch ($mode) {
+ case "default":
+ case "pkg-config":
+ $this->mode = $mode;
+ return true;
+
+ default:
+ return PEAR::raiseError("'$mode' is not a valid <with> mode");
+ }
+ }
+
+ /**
+ * version setter
+ *
+ * @param string
+ */
+ function setVersion($version)
+ {
+ $this->version = $version;
+ }
+
+ /**
+ * add library dependency
+ *
+ * @param object
+ */
+ function addLib(CodeGen_PECL_Dependency_Lib $lib)
+ {
+ $name = $lib->getName();
+
+ if (isset($this->libs[$name])) {
+ return PEAR::raiseError("library '$name' specified twice");
+ }
+
+ $this->libs[$name] = $lib;
+
+ return true;
+ }
+
+ /**
+ * libraries getter
+ *
+ * @return array
+ */
+ function getLibs()
+ {
+ return $this->libs;
+ }
+
+ /**
+ * add header dependency
+ *
+ * @param object
+ */
+ function addHeader(CodeGen_PECL_Dependency_Header $header)
+ {
+ $name = $header->getName();
+
+ if (isset($this->headers[$name])) {
+ return PEAR::raiseError("header '$name' specified twice");
+ }
+
+ $this->headers[$name] = $header;
+
+ return true;
+ }
+
+ /**
+ * headers getter
+ *
+ * @return array
+ */
+ function getHeaders()
+ {
+ return $this->headers;
+ }
+
+ /**
+ * m4 PHP_ARG_WITH line
+ *
+ * @parameter string optional help text
+ * @return string
+ */
+ function m4Line()
+ {
+ $optname = str_replace("_", "-", $this->name);
+
+ return sprintf("PHP_ARG_WITH(%s, %s,[ %-20s With %s support])\n",
+ $optname,
+ $this->getSummary(),
+ sprintf("--with-%s[=DIR]", $optname),
+ $this->name);
+ }
+
+
+ /**
+ * config.m4 code snippet
+ *
+ * @return string
+ */
+ function configm4(CodeGen_PECL_Extension $extension)
+ {
+ $code = "\n";
+
+ $withName = str_replace("-", "_", $this->getName());
+ $withUpname = strtoupper($withName);
+ $extName = $extension->getName();
+ $extUpname = strtoupper($extName);
+
+ if ($withName != $extName) {
+ $code.= $this->m4Line()."\n\n";
+ }
+
+ switch ($this->mode) {
+ case "pkg-config":
+ $code.= "
+ if test -z \"\$PKG_CONFIG\"
+ then
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+ fi
+ if test \"\$PKG_CONFIG\" = \"no\"
+ then
+ AC_MSG_ERROR([required utility 'pkg-config' not found])
+ fi
+
+ if ! \$PKG_CONFIG --exists $withName
+ then
+ AC_MSG_ERROR(['$withName' not known to pkg-config])
+ fi
+";
+
+ if ($this->version) {
+ $code .= "
+ if ! \$PKG_CONFIG --atleast-version {$this->version} $withName
+ then
+ PKG_VERSION=`\$PKG_CONFIG --modversion $withName`
+ AC_MSG_ERROR(['$withName'\ is version \$PKG_VERSION, {$this->version} required])
+ fi
+";
+ }
+
+ $code .= "
+ PHP_EVAL_INCLINE(`\$PKG_CONFIG --cflags-only-I $withName`)
+ PHP_EVAL_LIBLINE(`\$PKG_CONFIG --libs $withName`, {$extUpname}_SHARED_LIBADD)
+";
+ break;
+
+ default:
+ if ($this->testfile) {
+ $code.= "
+ if test -r \"\$PHP_$withUpname/".$this->testfile."\"; then
+ PHP_{$withUpname}_DIR=\"\$PHP_$withUpname\"
+ else
+ AC_MSG_CHECKING(for ".$this->name." in default path)
+ for i in ".str_replace(":", " ", $this->getDefaults())."; do
+ if test -r \"\$i/".$this->testfile."\"; then
+ PHP_{$withUpname}_DIR=\$i
+ AC_MSG_RESULT(found in \$i)
+ break
+ fi
+ done
+ if test \"x\" = \"x\$PHP_{$withUpname}_DIR\"; then
+ AC_MSG_ERROR(not found)
+ fi
+ fi
+
+";
+ }
+
+ $pathes = array();
+ foreach ($this->getHeaders() as $header) {
+ $pathes[$header->getPath()] = true;
+ }
+ foreach (array_keys($pathes) as $path) {
+ $code .=" PHP_ADD_INCLUDE(\$PHP_{$withUpname}_DIR/$path)\n";
+ }
+ break;
+ }
+
+ $code.= "\n";
+ $code.= " export OLD_CPPFLAGS=\"\$CPPFLAGS\"\n";
+ $code.= " export CPPFLAGS=\"\$CPPFLAGS \$INCLUDES -DHAVE_$withUpname\"\n";
+
+ foreach ($this->headers as $header) {
+ $code.= $header->configm4($extName, $this->name);
+ }
+
+ foreach ($this->getLibs() as $lib) {
+ $code.= $lib->configm4($extName, $this->name);
+ }
+
+ $code.= " export CPPFLAGS=\"\$OLD_CPPFLAGS\"\n";
+
+ return $code."\n";
+ }
+
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode:nil
+ * End:
+ */
+?>
View
158 PECL/Element.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ * Abstract base class for all PHP code elements
+ *
+ * PHP versions 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/CodeGen
+ */
+
+/**
+ * include
+ */
+require_once "CodeGen/Element.php";
+
+/**
+ * Abstract base class for all PHP code elements
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/CodeGen
+ */
+abstract class CodeGen_PECL_Element
+ extends CodeGen_Element
+{
+
+ /**
+ * Checks whether a string is a valid PHP type name and returns the official name
+ *
+ * @access public
+ * @param string Type name
+ * @return string The official type name or boolean false if not a type
+ */
+ function isType($name)
+ {
+ static $types = array("void" => "void",
+ "bool" => "bool",
+ "boolean" => "bool",
+ "int" => "int",
+ "integer" => "int",
+ "float" => "float",
+ "double" => "float",
+ "real" => "float",
+ "string" => "string",
+ "array" => "array",
+ "object" => "object",
+ "resource" => "resource",
+ "mixed" => "mixed",
+ "callback" => "callback",
+ "stream" => "stream"
+ );
+
+ if (isset($types[$name])) {
+ return $types[$name];
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Checks whether a string is a reserved name
+ *
+ * @access public
+ * @param string name
+ * @return bool true if reserved
+ */
+ function isKeyword($name)
+ {
+ // these are taken from zend_language_scanner.l
+ static $reserved = array(
+ "abstract",
+ "and",
+ "array",
+ "as",
+ "break",
+ "case",
+ "catch",
+ "class",
+ "const",
+ "continue",
+ "declare",
+ "default",
+ "die",
+ "do",
+ "echo",
+ "else",
+ "elseif",
+ "empty",
+ "enddeclare",
+ "endfor",
+ "endforeach",
+ "endif",
+ "endwhile",
+ "eval",
+ "exit",
+ "extends",
+ "final",
+ "for",
+ "foreach",
+ "function",
+ "global",
+ "if",
+ "implements",
+ "include",
+ "include_once",
+ "instanceof",
+ "interface",
+ "isset",
+ "list",
+ "new",
+ "or",
+ "print",
+ "private",
+ "protected",
+ "public",
+ "require",
+ "require_once",
+ "return",
+ "static",
+ "throw",
+ "try",
+ "unset",
+ "unset",
+ "use",
+ "var",
+ "while",
+ "xor",
+ );
+
+ foreach ($reserved as $keyword) {
+ if (!strcasecmp($keyword, $name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+}
+
+?>
View
669 PECL/Element/Class.php
@@ -0,0 +1,669 @@
+<?php
+/**
+ * Class describing a PHP class within a PECL extension
+ *
+ * PHP versions 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/CodeGen
+ */
+
+/**
+ * includes
+ */
+require_once "CodeGen/PECL/Element.php";
+require_once "CodeGen/PECL/Element/Property.php";
+require_once "CodeGen/PECL/Element/ClassConstant.php";
+require_once "CodeGen/PECL/Element/Method.php";
+require_once "CodeGen/PECL/Element/ObjectInterface.php";
+
+/**
+ * Class describing a PHP class within a PECL extension
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/CodeGen
+ */
+
+class CodeGen_PECL_Element_Class
+ extends CodeGen_PECL_Element
+ implements CodeGen_PECL_Element_ObjectInterface
+{
+ /**
+ * The class name
+ *
+ * @var string
+ */
+ protected $name = "unknown";
+
+ /**
+ * class name setter
+ *
+ * @param string Classname
+ */
+ function setName($name)
+ {
+ if (!self::isName($name)) {
+ return PEAR::raiseError("'$name' is not a valid class name");
+ }
+
+ $this->name = $name;
+
+ return true;
+ }
+
+ /**
+ * class name getter
+ *
+ * @return string Classname
+ */
+ function getName()
+ {
+ return $this->name;
+ }
+
+
+
+ /**
+ * A short description
+ *
+ * @var string
+ */
+ protected $summary = "";
+
+ /**
+ * Description summary setter
+ *
+ * @param string Description summary
+ */
+ function setSummary($text)
+ {
+ $this->summary = $text;
+ return true;
+ }
+
+
+
+
+ /**
+ * A long description
+ *
+ * @var string
+ */
+ protected $description = "";
+
+ /**
+ * Class description setter
+ *
+ * @param string Class description
+ */
+ function setDescription($text)
+ {
+ $this->description = $text;
+ return true;
+ }
+
+
+
+ /**
+ * Documentation
+ *
+ * TODO: isn't this in Element base class already?
+ *
+ * @var string
+ */
+ protected $documentation = "";
+
+ /**
+ * Class documentation setter
+ *
+ * @param string Class documentation
+ */
+ function setDocumentation($text)
+ {
+ $this->documentation = $text;
+ }
+
+
+
+ /**
+ * Extents which class?
+ *
+ * @var string
+ */
+ protected $extends = "";
+
+ /**
+ * Set parent class that this class inherits from
+ *
+ * @param string parent class name
+ */
+ function setExtends($parent)
+ {
+ if (!self::isName($parent)) {
+ return PEAR::raiseError("'$parent' is not a valid parent class name");
+ }
+
+ $this->extends = $parent;
+ }
+
+
+ /**
+ * Implemented Interfaces
+ *
+ * @var array
+ */
+ protected $implements = array();
+
+ /**
+ * Add an interface that this class implements
+ *
+ * @param string interface name
+ */
+ function addInterface($interface)
+ {
+ if (!self::isName($interface)) {
+ return PEAR::raiseError("'$interface' is not a valid interface name");
+ }
+
+ if (isset($this->implements[$interface])) {
+ return PEAR::raiseError("interface '$interface' added twice");
+ }
+
+ $this->implements[$interface] = $interface;
+ }
+
+
+ /**
+ * Properties
+ *
+ * @var array
+ */
+ protected $properties = array();
+
+ /**
+ * Add a class property
+ *
+ * @param object a class property object
+ */
+ function addProperty(CodeGen_PECL_Element_Property $property)
+ {
+ $name = $property->getName();
+
+ if (isset($this->properties[$name])) {
+ return PEAR::raiseError("property '$name' already exists");
+ }
+
+ $this->properties[$name] = $property;
+ }
+
+
+ /**
+ * Constants
+ *
+ * @var array
+ */
+ protected $constants = array();
+
+ /**
+ * Add a constant to a class
+ *
+ * @param object a class constant object
+ */
+ function addConstant(CodeGen_PECL_Element_ClassConstant $constant)
+ {
+ $name = $constant->getName();
+
+ if (isset($this->constants[$name])) {
+ return PEAR::raiseError("constant '$name' already exists");
+ }
+
+ $this->constants[$name] = $constant;
+ }
+
+
+ /**
+ * Member Functions
+ *
+ * @var array
+ */
+ protected $methods = array();
+
+ /**
+ * Add a method definition to the class
+ *
+ * @param object class method object
+ */
+ function addMethod(CodeGen_PECL_Element_Method $method)
+ {
+ $name = $method->getName();
+
+ if (isset($this->functions[$name])) {
+ return PEAR::raiseError("method '$name' already exists");
+ }
+
+ $this->methods[$name] = $method;
+
+ return true;
+ }
+
+
+
+ /**
+ * Is this an abstract class?
+ *
+ * @var bool
+ */
+ protected $isAbstract = false;
+
+ /**
+ * Make class abstract
+ */
+ function isAbstract()
+ {
+ $this->isAbstract = true;
+ }
+
+
+
+ /**
+ * Is this class final?
+ *
+ * @var bool
+ */
+ protected $isFinal = false;
+
+ /**
+ * Make class final
+ */
+ function isFinal()
+ {
+ $this->isFinal = true;
+ }
+
+
+
+ /**
+ * Is this an interface?
+ *
+ * @var bool
+ */
+ protected $isInterface = false;
+
+ /**
+ * Make class an interface
+ */
+ function isInterface()
+ {
+ // TODO: check for already added non-abstract stuff
+
+ $this->isInterface = true;
+ }
+
+
+ /**
+ * Class payload data type
+ *
+ * @var string C type name class payload data
+ */
+ protected $payloadType = "";
+
+ /**
+ * Payload type setter
+ *
+ * @param string
+ */
+ function setPayloadType($type)
+ {
+ // TODO check
+ $this->payloadType = $type;
+ }
+
+ /**
+ * Payload type getter
+ *
+ * @return string
+ */
+ function getPayloadType()
+ {
+ return $this->payloadType;
+ }
+
+
+ /**
+ * Allocate storage space for payload data?
+ *
+ * @var bool
+ */
+ protected $payloadAlloc = true;
+
+ /**
+ * Payload alloc setter
+ *
+ * @param string
+ */
+ function setPayloadAlloc($alloc)
+ {
+ $this->payloadAlloc = (bool)$alloc;
+ }
+
+ /**
+ * Payload init code snippet
+ *
+ * @param string
+ */
+ protected $payloadCtor = "";
+
+ /**
+ * Payload init code setter
+ *
+ * @param string code snippet
+ */
+ function setPayloadCtor($code)
+ {
+ $this->payloadCtor = $code;
+ }
+
+ /**
+ * Payload init code getter
+ *
+ * @return string code snippet
+ */
+ function getPayloadCtor($extension)
+ {
+ $code = "";
+
+ if ($this->payloadAlloc) {
+ $code.= " payload->data = ({$this->payloadType} *)malloc(sizeof({$this->payloadType}));\n";
+ }
+
+ $code .= $extension->codegen->varblock($this->payloadCtor);
+
+ return $code;
+ }
+
+
+ /**
+ * Payload dtor code snippet
+ *
+ * @param string
+ */
+ protected $payloadDtor = "";
+
+ /**
+ * Payload dtor code setter
+ *
+ * @param string code snippet
+ */
+ function setPayloadDtor($code)
+ {
+ $this->payloadDtor = $code;
+ }
+
+ /**
+ * Payload dtor code getter
+ *
+ * @return string code snippet
+ */
+ function getPayloadDtor($extension)
+ {
+ $code = $extension->codegen->varblock($this->payloadDtor);
+
+ if ($this->payloadAlloc) {
+ $code.= " free(payload->data);\n";
+ }
+
+ return $code;
+ }
+ /**
+ * Create C header entry for clas
+ *
+ * @access public
+ * @param class Extension extension the function is part of
+ * @return string C header code snippet
+ */
+ function hCode($extension)
+ {
+ $code = "";
+
+ if ($this->payloadType) {
+ $upname = strtoupper($this->name);
+ echo "
+typedef struct _php_obj_{$this->name} {
+ zend_object obj;
+ {$this->payloadType} *data;
+} php_obj_{$this->name};
+";
+ }
+
+ foreach ($this->methods as $method) {
+ $code.= $method->hCode($extension);
+ }
+
+ if ($code) {
+ $code = $this->ifConditionStart() . $code . $this->ifConditionEnd();
+ }
+
+ return $code;
+ }
+
+
+ /**
+ * Generate global scope code
+ *
+ * @access public
+ * @return string
+ */
+ function globalCode($extension)
+ {
+ $upname = strtoupper($this->name);
+
+ ob_start();
+
+
+ echo "/* {{{ Class {$this->name} */\n\n";
+
+ echo $this->ifConditionStart();
+
+ echo "static zend_class_entry * {$this->name}_ce_ptr = NULL;\n\n";
+
+ echo "/* {{{ Methods */\n\n";
+ foreach ($this->methods as $method) {
+ echo $method->cCode($extension);
+ echo "\n";
+ }
+
+ echo "static zend_function_entry {$this->name}_methods[] = {\n";
+
+ foreach ($this->methods as $method) {
+ echo " ".$method->methodEntry()."\n";
+ }
+
+ echo " { NULL, NULL, NULL }\n";
+ echo "};\n\n";
+
+ echo "/* }}} Methods */\n\n";
+
+ if ($this->payloadType) {
+ echo "
+static zend_object_handlers {$this->name}_obj_handlers;
+
+static void {$this->name}_obj_free(void *object TSRMLS_DC)
+{
+ php_obj_{$this->name} *payload = (php_obj_{$this->name} *)object;
+
+ {$this->payloadType} *data = payload->data;
+".$this->getPayloadDtor($extension)."
+ efree(object);
+}
+
+static zend_object_value {$this->name}_obj_create(zend_class_entry *class_type TSRMLS_DC)
+{
+ php_obj_{$this->name} *payload;
+ zval *tmp;
+ zend_object_value retval;
+
+ payload = (php_obj_{$this->name} *)emalloc(sizeof(php_obj_{$this->name}));
+ memset(payload, 0, sizeof(php_obj_{$this->name}));
+ payload->obj.ce = class_type;
+".$this->getPayloadCtor($extension)."
+ retval.handle = zend_objects_store_put(payload, NULL, (zend_objects_free_object_storage_t) {$this->name}_obj_free, NULL TSRMLS_CC);
+ retval.handlers = &{$this->name}_obj_handlers;
+
+ return retval;
+}
+
+";
+ }
+
+ echo "static void class_init_{$this->name}(void)\n{\n";
+
+ echo " zend_class_entry ce;\n\n";
+
+ echo " INIT_CLASS_ENTRY(ce, \"{$this->name}\", {$this->name}_methods);\n";
+
+ if ($this->payloadType) {
+ echo " ce.create_object = {$this->name}_obj_create;\n";
+ }
+
+ if ($this->extends) {
+ echo " {$this->name}_ce_ptr = zend_register_internal_class_ex(&ce, NULL, \"{$this->extends}\" TSRMLS_CC);\n";
+ } else {
+ echo " {$this->name}_ce_ptr = zend_register_internal_class(&ce);\n";
+ }
+
+ if ($this->payloadType) {
+ echo " memcpy(&{$this->name}_obj_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));\n";
+ echo " {$this->name}_obj_handlers.clone_obj = NULL;\n";
+ }
+
+ if ($this->isFinal) {
+ echo " {$this->name}_ce_ptr->ce_flags |= ZEND_ACC_FINAL_CLASS;\n";
+ }
+
+ if ($this->isAbstract) {
+ echo " {$this->name}_ce_ptr->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n";
+ }
+
+ if (!empty($this->properties)) {
+ echo "\n /* {{{ Property registration */\n\n";
+ foreach ($this->properties as $property) {
+ echo $property->minitCode($this->name."_ce_ptr");
+ }
+ echo " /* }}} Property registration */\n\n";
+ }
+
+ if (!empty($this->constants)) {
+ echo "\n";
+ echo CodeGen_PECL_Element_ClassConstant::minitHeader();
+ foreach ($this->constants as $constant) {
+ echo $constant->minitCode($this->name."_ce_ptr");
+ }
+ echo CodeGen_PECL_Element_ClassConstant::minitFooter();
+ }
+
+ if (count($this->implements)) {
+ ob_start();
+
+ echo "zend_class_entry **tmp;\n";
+
+ $interfaces = array();
+ foreach ($this->implements as $interface) {
+ echo sprintf("if (SUCCESS == zend_hash_find(CG(class_table), \"%s\", %d, (void **)&tmp)) {\n",
+ strtolower($interface), strlen($interface) + 1);
+ echo " zend_class_implements({$this->name}_ce_ptr TSRMLS_CC, 1, *tmp);\n";
+ echo "} else {\n";
+ echo " php_error(E_WARNING, \"Couldn't find interface '$interface' while setting up class '{$this->name}', skipped\");\n";
+ echo "}\n";
+ }
+
+ echo $extension->codegen->varblock(ob_get_clean());
+ }
+
+
+ echo "}\n\n";
+
+ echo $this->ifConditionEnd();
+
+ echo "/* }}} Class {$this->name} */\n\n";
+
+ return ob_get_clean();
+ }
+
+
+ /**
+ * MINIT code fragment
+ *
+ * @access public
+ * @return string
+ */
+ function minitCode($extension)
+ {
+ return $this->ifConditionStart()
+ . "class_init_{$this->name}();\n"
+ . $this->ifConditionEnd();
+ }
+
+
+ /**
+ * DocBook documentation fragment
+ *
+ * @access public
+ * @return string
+ */
+ function docEntry($base)
+ {
+ $xml = "";
+
+ return $xml;
+ }
+
+ /**
+ * Write method test cases
+ *
+ * @param object Extension to write tests for
+ */
+ function writeTests(CodeGen_PECL_Extension $extension)
+ {
+ foreach ($this->methods as $method) {
+ $method->writeTest($extension);
+ }
+ }
+
+ /**
+ * Return function alias entries for all methods
+ *
+ */
+ function functionAliasEntries()
+ {
+ $code = "";
+
+ foreach ($this->methods as $method) {
+ $code.= $method->functionAliasEntry();
+ }
+
+ if ($code) {
+ $code = $this->ifConditionStart() . $code . $this->ifConditionEnd();
+ }
+
+ return $code;
+ }
+
+}
+
+?>
View
244 PECL/Element/ClassConstant.php
@@ -0,0 +1,244 @@
+<?php
+/**
+ * Class describing a PHP class constant within a PECL extension
+ *
+ * PHP versions 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt. If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/CodeGen
+ */
+
+/**
+ * includes
+ */
+require_once "CodeGen/PECL/Element.php";
+
+/**
+ * Class describing a PHP class constant within a PECL extension
+ *
+ * @category Tools and Utilities
+ * @package CodeGen
+ * @author Hartmut Holzgraefe <hartmut@php.net>
+ * @copyright 2005, 2006 Hartmut Holzgraefe
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version Release: @package_version@
+ * @link http://pear.php.net/package/CodeGen
+ */
+
+class CodeGen_PECL_Element_ClassConstant
+ extends CodeGen_PECL_Element
+{
+ /**
+ * The constants name
+ *
+ * @access private
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * The constants PHP data type
+ *
+ * @access private
+ * @var string
+ */
+ protected $type = "string";
+
+ /**
+ * The constants value
+ *
+ * @access private
+ * @var string
+ */
+ protected $value;
+
+ /**
+ * The constants description text
+ *
+ * @access private
+ * @var string
+ */
+ protected $desc;
+
+
+ /**
+ * Set constant name
+ *
+ * @access public
+ * @param string the name
+ * @return bool true on success
+ */
+ function setName($name)
+ {
+ if (!self::isName($name)) {
+ return PEAR::raiseError("'$name'is not a valid constant name");
+ }
+
+ if (self::isKeyword($name)) {
+ return PEAR::raiseError("'$name' is a reserved word which is not valid for constant names");
+ }
+
+ $this->name = $name;
+
+ return true;
+ }
+
+ /**
+ * Get constant name
+ *
+ * @access public
+ * @return string
+ */
+ function getName()
+ {
+ return $this->name;
+ }
+
+
+ /**
+ * Set constant type
+ *
+ * @access public
+ * @param string the type
+ * @return bool true on success
+ */
+ function setType($type)
+ {
+ if (!in_array($type, array('int', 'float', 'string'))) {
+ return PEAR::raiseError("'$type' is not a valid constant type, only int, float and string");
+ }
+
+ $this->type = $type;
+
+ return true;
+ }
+
+ /**
+ * Set constant value
+ *
+ * @access public
+ * @param string the value
+ * @return bool true on success
+ */
+ function setValue($value)
+ {
+ $this->value = $value;
+
+ if ($this->value == $this->name) {
+ $this->deinfe = false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Set constant descriptive text
+ *
+ * @access public
+ * @param string the name
+ * @return bool true on success
+ */
+ function setDesc($desc)
+ {
+ $this->desc = $desc;
+
+ return true;
+ }
+
+
+ /**
+ * MINIT code fragment
+ *
+ * @access public
+ * @return string
+ */
+ function minitCode($classptr)
+ {
+ switch ($this->type) {
+ case "string":
+ $value = 'ZVAL_STRING(tmp, "'.$this->value.'", 1);';
+ break;
+ case "int":
+ $value = 'ZVAL_LONG(tmp, '.$this->value.');';
+ break;
+ case "float":
+ $value = 'ZVAL_DOUBLE(tmp, '.$this->value.');';
+ break;
+ default:
+ return "";
+ }
+
+ $key = '"'.$this->name.'"';
+ $key_len = strlen($this->name) + 1;
+
+
+ $code = $this->ifConditionStart();
+
+ $code.= "
+ tmp = (zval *) malloc(sizeof(zval));
+ INIT_PZVAL(tmp);
+ $value
+ zend_symtable_update(&({$classptr}->constants_table), $key, $key_len, (void *) &tmp, sizeof(zval *), NULL);
+";
+
+ $code.= $this->ifConditionEnd();
+
+ return $code;
+ }
+
+
+ /**
+ * MINIT code header
+ *
+ * @access public
+ * @return string
+