Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Remove some leftover files.

  • Loading branch information...
commit f03714a2ff807006f7bfe23f9027baede8c10f11 1 parent 4966fce
@realityking realityking authored
View
14 CodeGen/PECL/Element/Class.php
@@ -676,5 +676,19 @@ function functionAliasEntries()
return $code;
}
+ /**
+ * Return minimal PHP version required to support the requested features
+ *
+ * @return string version string
+ */
+ function minPhpVersion()
+ {
+ if (!empty($this->namespace)) {
+ return "5.3.0";
+ }
+
+ // default: 5.0
+ return "5.0.0"; // TODO test for real lower bound
+ }
}
View
1,806 CodeGen/PECL/Element/Function.php.orig
@@ -1,1806 +0,0 @@
-<?php
-/**
- * Class describing a function 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_PECL
- * @author Hartmut Holzgraefe <hartmut@php.net>
- * @copyright 2005-2008 Hartmut Holzgraefe
- * @license http://www.php.net/license/3_0.txt PHP License 3.0
- * @version CVS: $Id: Function.php,v 1.46 2007/04/25 13:59:09 hholzgra Exp $
- * @link http://pear.php.net/package/CodeGen
- */
-
-/**
- * includes
- */
-require_once "CodeGen/PECL/Element.php";
-
-require_once "CodeGen/Tools/Tokenizer.php";
-
-require_once "CodeGen/PECL/Tools/ProtoLexer.php";
-require_once "CodeGen/PECL/Tools/ProtoParser.php";
-
-/**
- * Class describing a function within a PECL extension
- *
- * @category Tools and Utilities
- * @package CodeGen_PECL
- * @author Hartmut Holzgraefe <hartmut@php.net>
- * @copyright 2005-2008 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_Function
- extends CodeGen_PECL_Element
-{
- /**
- * The function name
- *
- * @var string
- */
- protected $name = "";
-
- /**
- * name setter
- *
- * @param string
- */
- function setName($name)
- {
- if (!self::isName($name)) {
- return PEAR::raiseError("'$name' is not a valid function name");
- }
-
- switch ($this->role) {
- case "internal":
- if (!$this->isInternalName($name)) {
- return PEAR::raiseError("'$name' is not a valid internal function name");
- }
- break;
-
- case "public":
- // keywords are not allowed as function names
- if (self::isKeyword($name)) {
- return PEAR::raiseError("'$name' is a reserved word which is not valid for function names");
- }
- // you should not redefine standard PHP functions
- foreach (get_extension_funcs("standard") as $stdfunc) {
- if (!strcasecmp($name, $stdfunc)) {
- return PEAR::raiseError("'$name' is already the name of a PHP standard function");
- }
- }
- break;
- }
-
- $this->name = $name;
-
- return true;
- }
-
- /**
- * name getter
- *
- * @return string
- */
- function getName()
- {
- return $this->name;
- }
-
- /**
- * distinguishable name getter
- *
- * here it's just the same as the plain name
- * but e.g. for class methods that wouldn't
- * be enough
- *
- * @return string
- */
- function getFullName()
- {
- return $this->name;
- }
-
- /**
- * A short description
- *
- * @var string
- */
- protected $summary = "";
-
- /**
- * summary getter
- *
- * @param string
- */
- function setSummary($text)
- {
- $this->summary = $text;
- return true;
- }
-
-
-
-
- /**
- * A long description
- *
- * @var string
- */
- protected $description = "";
-
- /**
- * description setter
- *
- * @param string
- */
- function setDescription($text)
- {
- $this->description = $text;
- return true;
- }
-
-
-
-
- /**
- * Type of function: internal, public
- *
- * @var string
- */
- protected $role = "public";
-
- /**
- * role setter
- *
- * @param string
- */
- function setRole($role)
- {
- switch($role) {
- case "internal":
- if (!$this->isInternalName($this->name)) {
- return PEAR::raiseError("'{$this->name}' is not a valid internal function name");
- }
- break;
-
- case "public":
- break;
-
- case "private":
- return PEAR::raiseError("'private' functions are no longer supported, use global <code> sections instead");
- break;
-
- default:
- return PEAR::raiseError("'$role' is not a valid function role");
- }
-
- $this->role = $role;
-
- return true;
- }
-
- function getRole()
- {
- return $this->role;
- }
-
-
- /**
- * Function has variable arguments "..."
- *
- * @var bool
- */
- protected $varargs = false;
-
- function setVarargs($varargs)
- {
- $this->varargs = (bool)$varargs;
- }
-
- function getVarargs()
- {
- return $this->varargs;
- }
-
- protected $varargsType = "mixed";
-
- function setVarargsType($type)
- {
- $type = strtolower($type);
-
- switch ($type) {
- case "bool":
- case "int":
- case "float":
- case "string":
- case "mixed":
- $this->varargsType = $type;
- return true;
- }
-
- return PEAR::raiseError("invalid vararg type '$type', only 'bool', 'int', 'float', 'string' \nand 'mixed' are supported for now");
- }
-
- /**
- * Function prototype
- *
- * @var string
- */
- protected $proto = "void unknown(void)";
-
- /**
- * Function returntype (parsed from proto)
- *
- * @var string
- */
- protected $returns = array();
-
- /**
- * Function parameters (parsed from proto)
- *
- * @var array
- */
- protected $params = array();
-
- /**
- * Does this function have by-reference parameters?
- *
- * @var bool
- */
- protected $hasRefArgs = false;
-
- /**
- * Set parameter and return value information from PHP style prototype
- *
- * @param string PHP style prototype
- * @param object Extension object owning this function
- * @return bool Success status
- */
- function setProto($proto, $extension)
- {
- $this->proto = $proto;
-
- if ($extension->haveVersion("1.1.0")) {
- $stat = $this->newSetProto2($proto, $extension);
- } else if ($extension->haveVersion("0.9.0rc1")) {
- $stat = $this->newSetProto($proto, $extension);
- } else {
- $stat = $this->oldSetProto($proto);
- }
-
- return $stat;
- }
-
- /**
- * Set parameter and return value information from PHP style prototype
- *
- * new (and hopefully final) version using a PHP_LexerGenerator and
- * PHP_ParserGenerator generated prototype parser
- *
- * @param string PHP style prototype
- * @param object Extension object owning this function
- * @return bool Success status
- */
- protected function newSetProto2($proto, $extension)
- {
- try {
- $lex = new CodeGen_PECL_Tools_ProtoLexer($proto);
- $parser = new CodeGen_PECL_Tools_ProtoParser($extension, $this);
- while ($lex->yylex()) {
- $parser->doParse($lex->token, $lex->value);
- }
- $parser->doParse(0, 0);
- } catch (Exception $e) {
- return PEAR::raiseError($e->getMessage());
- }
- }
-
- /**
- * Set parameter and return value information from PHP style prototype
- *
- * @param string PHP style prototype
- * @param object Extension object owning this function
- * @return bool Success status
- */
- protected function newSetProto($proto, $extension)
- {
- $tokenGroups = array();
- $optionals = 0;
- $firstOptional = 0;
- $squareBrackets = 0;
-
- $scanner = new CodeGen_Tools_Tokenizer($proto);
-
- // group #0 -> return type and function name
- $group = array();
- while ($scanner->nextToken()) {
- if ($scanner->type === 'char' && $scanner->token === '(') {
- break;
- }
- $group[] = array($scanner->type, $scanner->token);
- }
- $tokenGroups[] = $group;
-
- // all following groups are parameters delimited by ','
- $group = array();
- while ($scanner->nextToken()) {
- if ($scanner->type === 'char') {
- if ($scanner->token === '[') {
- $squareBrackets++;
- if (!$firstOptional) {
- if (count($group)) {
- $tokenGroups[] = $group;
- $group = array();
- }
- $firstOptional = count($tokenGroups);
- }
- continue;
- }
-
- if ($scanner->token === ',') {
- if (count($group)) {
- $tokenGroups[] = $group;
- $group = array();
- }
- continue;
- }
-
-
- if ($scanner->token === ']') {
- $squareBrackets--;
- continue;
- }
-
- if ($scanner->token === ')') {
- $tokenGroups[] = $group;
- $group = array();
- break;
- }
- }
-
- $group[] = array($scanner->type, $scanner->token);
- }
-
- if ($squareBrackets > 0) {
- return PEAR::raiseError("missing closing ']'");
- }
- if ($squareBrackets < 0) {
- return PEAR::raiseError("to many closing ']'");
- }
-
-
- //
- // get return type and function name
- //
- $tokens = array_shift($tokenGroups);
-
- // first the function name
- list($type, $token) = array_pop($tokens);
- if ($type !== 'char' || $token !== '@') { // @ is allowed as function name placeholder
- if ($type !== 'name' || !self::isName($token)) {
- return PEAR::raiseError("'$token' is not a valid function name");
- }
- if (self::isKeyword($token)) {
- return PEAR::raiseError("keyword '$token' can't be used as function name");
- }
- }
-
- $functionName = $token;
- // function name is not really used, taken from <function> tag instead
- // TODO: add WARNING for mismatch?
- if (! empty($this->name)) {
- $functionName = $this->name;
- } else {
- $this->name = $functionName;
- }
-
- // then the return type
- list($type, $token) = array_shift($tokens);
- if ($type !== 'name' || !self::isType($token)) {
- return PEAR::raiseError("'$token' is not a valid return type");
- }
- $returnType = $token;
-
- // some types may carry a name
- if ($token === "object" || $token == "resource") {
- if (isset($tokens[0][0]) && $tokens[0][0] === 'name') {
- list($type, $token) = array_shift($tokens);
- $returnSubtype = $token;
- }
- }
-
- // return by reference?
- if (count($tokens) && $tokens[0][0] === 'char' && ($tokens[0][1] === '&' || $tokens[0][1] === '@')) {
- list($type, $token) = array_shift($tokens);
- $returnByRef = true;
- }
-
- // any tokens left?
- if (count($tokens)) {
- return PEAR::raiseError("extra token '".$tokens[0][1]."' in function prototype");
- }
-
- //
- // now the parameters one by one
- //
- $params = array();
- $vararg = false;
- while ($tokens = array_shift($tokenGroups)) {
- if ($vararg) {
- return PEAR::raiseError("no further parameters are allowed after '...'");
- }
-
- $param = array();
-
- // check for default value assignment
- $equals = false;
- $default = array();
- foreach ($tokens as $key => $value) {
- if ($value[0] === 'char' && $value[1] === '=') {
- $equals = $key;
- break;
- }
- }
- if ($equals !== false) {
- while (count($tokens) > $equals + 1) {
- array_unshift($default, array_pop($tokens));
- }
- array_pop($tokens);
- }
-
- // get parameter name
- list($type, $token) = array_pop($tokens);
- if ($type !== 'name') {
- return PEAR::raiseError("'$token' is not a valid parameter name (1)");
- }
- $param['name'] = $token;
-
- // then the parameter type
- list($type, $token) = array_shift($tokens);
- if ($type !== 'name' || !self::isType($token)) {
- switch ($param["name"]) {
- case "void":
- if (!empty($params)) {
- return PEAR::raiseError("only the first (and only) paramter can be of type void");
- }
- $param["type"] = $param["name"];
- $param["name"] = "";
- break;
- case "...":
- if ($optionals) { // TODO not set yet ???
- return PEAR::raiseError("'...' varargs can't be combined with optional args");
- }
- $vararg = true;
- $param["type"] = $param["name"];
- $param["name"] = "";
- break;
- default:
- return PEAR::raiseError("'$token' is not a valid type for parameter '".$param['name']."'");
- }
- } else {
- $param['type'] = $token;
- }
-
- if (!empty($param["name"]) && !self::isName($param["name"])) {
- return PEAR::raiseError("'{$param[name]}' is not a valid parameter name (2)");
- }
-
- // some types may carry a name
- if ($token === "object" || $token === "resource") {
- if ($tokens[0][0] === 'name') {
- list($type, $token) = array_shift($tokens);
- $param['subtype'] = $token;
- }
- }
-
- // pass by reference?
- if (count($tokens) && ($tokens[0][0] === 'char') && ($tokens[0][1] === '&' || $tokens[0][1] === '@')) {
- list($type, $token) = array_shift($tokens);
- if ($param['type'] != "array" && $param['type'] != "mixed" && $param['type'] != 'object') {
- return PEAR::raiseError("only 'array', 'object' and 'mixed' arguments may be passed by reference, '$param[name]' is of type '$param[type]'");
- }
- $param['byRef'] = true;
- $this->hasRefArgs = true;
- }
-
- // any tokens left?
- if (count($tokens)) {
- return PEAR::raiseError("extra token '".$tokens[0][1]."' in specification of parameter '$param[name]'");
- }
-
- // do we have a default value?
- switch (count($default)) {
- case 0:
- break;
- case 1:
- list($type, $token) = array_shift($default);
- switch ($type) {
- case 'string':
- case 'char':
- $param['default'] = '"'.str_replace('"', '\"', $token).'"';
- break;
- case 'numeric':
- $param['default'] = $token;
- break;
- case 'name':
- switch (strtolower($token)) {
- // first check for 'known' PHP constants
- case 'true':
- case 'false':
- case 'null':
- case 'array()':
- $param['default'] = $token;
- break;
- default:
- // now see if this is a constand defined by this extension
- $constant = $extension->getConstant($token);
- if ($constant) {
- $param["default"] = $constant->getValue();
- } else {
- return PEAR::raiseError("invalid default value '$token' specification for parameter '$param[name]' ($type)");
- }
- }
- break;
- default:
- return PEAR::raiseError("invalid default value '$token' specification for parameter '$param[name]' ($type)");
- }
- break;
- default:
- return PEAR::raiseError("invalid default value '$token' specification for parameter '$param[name]' ($type)");
- }
-
- if ($firstOptional && count($params)+1 >= $firstOptional) {
- $param['optional'] = true;
- $optionals++;
- }
-
- $params[] = $param;
- }
-
- $this->returns['type'] = $returnType;
-
- if (isset($returnSubtype)) {
- $this->returns['subtype'] = $returnSubtype;
- }
-
- if (isset($returnByRef)) {
- $this->returns["byRef"] = true;
- }
-
- $this->params = $params;
- $this->vararg = $vararg;
-
- return true;
- }
-
-
- function oldSetProto($proto)
- {
- // This is the classic setProto() version, we keep it for now
- // as the new version is not 100% backwards compatible yet
-
- // 'tokenize' it
- $tokens = array();
-
- // we collect valid C names as Strings, any other character for itself, blanks are skipped
- // TODO: this does no longer work if we ever add default values ...
- $len = strlen($proto);
- $name = "";
- for ($n = 0; $n < $len; $n++) {
- $char = $proto{$n};
- if (ctype_alpha($char) || $char == '_' || ($n && ctype_digit($char))) {
- $name .= $char;
- } else if ($char == '.' && $proto{$n+1} == '.' && $proto{$n+2} == '.') {
- $name = "...";
- $n += 2;
- } else {
- if ($name) $tokens[] = $name;
- $name = "";
- if (trim($char)) {
- $tokens[] = $char;
- }
- }
- }
-
- if ($name) {
- $tokens[] = $name;
- }
-
- $n = 0;
- $opts = 0;
- $numopts = 0;
- $params = array();
-
- $returnType = ($this->isType($tokens[$n])) ? $tokens[$n++] : "void";
-
- $functionName = $tokens[$n++];
-
- if ($returnType === "resource" && $tokens[$n] !== "(") {
- $returnSubtype = $functionName;
- $functionName = $tokens[$n++];
- }
-
- // function name is not really used, taken from <function> tag instead
- // TODO: add WARNING for mismatch?
- if (! empty($this->name)) {
- $functionName = $this->name;
- } else {
- $this->name = $functionName;
- }
-
- if ($tokens[$n++] != '(') return PEAR::raiseError("'(' expected instead of '$tokens[$n]'");
-
- if ($tokens[$n] == ')') {
- /* done */
- } else if ($tokens[$n] == '...') {
- $params[0]['type'] = "...";
- $n++;
- } else {
- for ($param = 0; $tokens[$n]; $n++, $param++) {
- if ($tokens[$n] == '[') {
- $params[$param]['optional'] = true;
- $opts++;
- $n++;
- if ($param > 0) {
- if ($tokens[$n] != ',') {
- return PEAR::raiseError("',' expected after '[' instead of '$token[$n]'");
- }
- $n++;
- }
- }
-
- if (!$this->isType($tokens[$n])) {
- return PEAR::raiseError("type name expected instead of '$tokens[$n]'");
- }
-
- $params[$param]['type'] = $tokens[$n];
- $n++;
-
- if ($tokens[$n] == "&" || $token[$n] == "@") {
- $params[$param]['byRef'] = true;
- $n++;
- }
-
- if ($this->isName($tokens[$n])) {
- $params[$param]['name']=$tokens[$n];
- $n++;
- }
-
- if ($tokens[$n] == "&" || $token[$n] == "@") {
- $params[$param]['byRef'] = true;
- $n++;
- }
-
- if ($params[$param]['type'] === "resource" && $this->isName($tokens[$n])) {
- $params[$param]['subtype'] = $params[$param]['name'];
- $params[$param]['name'] = $tokens[$n];
- $n++;
- }
-
- if ($tokens[$n] == '[') {
- $n--;
- continue;
- }
-
- if ($tokens[$n] == ',') continue;
- if ($tokens[$n] == ']') break;
- if ($tokens[$n] == ')') break;
-
- }
-
- $numopts = $opts;
- while ($tokens[$n] == ']') {
- $n++;
- $opts--;
- }
- if ($opts != 0) {
- return PEAR::raiseError("'[' / ']' count mismatch");
- }
- }
-
- if ($tokens[$n] != ')') {
- return PEAR::raiseError("')' expected instead of '$tokens[$n]'");
- }
-
- $this->returns['type'] = $returnType;
-
- if (isset($returnSubtype)) {
- $this->returns['subtype'] = $returnSubtype;
- }
-
- $this->params = $params;
-
- return true;
- }
-
-
- /**
- * Code snippet
- *
- * @var string
- */
- protected $code = "";
-
- /**
- * Source file of code snippet
- *
- * @var string
- */
- protected $codeFile = "";
-
- /**
- * Source line of code snippet
- *
- * @var int
- */
- protected $codeLine = 0;
-
- /**
- * Code setter
- *
- * @param string code snippet
- * @param int source line
- * @param int source filename
- */
- function setCode($code, $line = 0, $file = "")
- {
- $this->code = $code;
- $this->codeFile = $file;
- $this->codeLine = $line;
- return true;
- }
-
- /**
- * Code getter
- *
- * @return string
- */
- function getCode()
- {
- return $this->code;
- }
-
-
-
-
-
- /**
- * test code snippet
- *
- * @var string
- */
- protected $testCode = "echo 'OK'; // no test case for this function yet";
-
- /**
- * testCode setter
- *
- * @param string code snippet
- */
- function setTestCode($code)
- {
- $this->testCode = $code;
- }
-
- /**
- * testCode getter
- *
- * @return string
- */
- function getTestCode()
- {
- return $this->testCode;
- }
-
-
- /**
- * expected test result string
- *
- * @var array
- */
- protected $testResult = array();
-
- /**
- * testResult setter
- *
- * @param string result text
- * @param string test output comparison mode
- */
- function setTestResult($text, $mode = "plain")
- {
- $this->testResult = array("result" => $text, "mode" => $mode);
- }
-
- /**
- * testResult getter
- *
- * @return array
- */
- function getTestResult()
- {
- return $this->testResult;
- }
-
-
- /**
- * test code description
- *
- * @var string
- */
- protected $testDescription = "";
-
- /**
- * testDescritpion setter
- *
- * @param string text
- */
- function setTestDescription($text)
- {
- $this->testDescription = $text;
- }
-
- /**
- * testDescription getter
- *
- * @return string
- */
- function getTestDescription()
- {
- return $this->testDescription;
- }
-
-
- /**
- * test additional skipif condition
- *
- * @var string
- */
- protected $testSkipIf = "";
-
- /**
- * testSkipIf setter
- *
- * @param string code snippet
- */
- function setTestSkipIf($code)
- {
- $this->testSkipIf = $code;
- }
-
- /**
- * testSkipIf getter
- *
- * @return string
- */
- function getTestSkipIf()
- {
- return $this->testSkipIf;
- }
-
-
-
- /**
- * test additional ini condition
- *
- * @var string
- */
- protected $testIni = "";
-
- /**
- * testIni setter
- *
- * @param string code snippet
- */
- function setTestIni($code)
- {
- $this->testIni = $code;
- }
-
- /**
- * testIni getter
- *
- * @return string
- */
- function getTestIni()
- {
- return $this->testIni;
- }
-
-
-
-
-
-
-
-
-
- /**
- * Check whether a function name is already used internally
- *
- * @param string function name
- * @return bool true if function name is already used internally
- */
- function isInternalName($name)
- {
- switch ($name) {
- case "MINIT":
- case "MSHUTDOWN":
- case "RINIT":
- case "RSHUTDOWN":
- case "MINFO":
- return true;
- }
-
- return false;
- }
-
-
- /**
- * Helper for cCode
- *
- * @param string Parameter spec. array
- * @param string default value for type
- * @return string default value
- */
- function defaultval($param, $default)
- {
- if (isset($param["default"])) {
- if (is_object($param["default"])) {
- return $param["default"]->getValue();
- }
- return $param["default"];
- }
-
- return $default;
- }
-
-
- /**
- * Hook for parameter parsing API function
- *
- * @param string Argument string
- * @param array Argument variable pointers
- * @param int Return value for number of arguments
- */
- protected function parseParameterHook($argString, $argPointers, &$count)
- {
- $count = count($this->params);
-
- if ($this->varargs) {
- $argc = sprintf("MIN(ZEND_NUM_ARGS(), %d)", $count);
- } else if ($count > 0) {
- $argc = "ZEND_NUM_ARGS()";
- }
-
- if (isset($argc)) {
- $parse_call = "zend_parse_parameters($argc TSRMLS_CC, \"$argString\", ".join(", ", $argPointers).")";
- } else {
- $parse_call = "zend_parse_parameters_none()";
- }
-
- return "
- if ($parse_call == FAILURE) {
- return;
- }
-";
- }
-
-
- /**
- * Generate local variable declarations
- *
- * @return string C code snippet
- */
- function localVariables($extension)
- {
- $code = "";
-
- // for functions returning a named resource we create payload pointer variable
- if ($this->returns['type'] === "resource") {
- if (isset($this->returns['subtype'])) {
- $resource = $extension->getResource($this->returns['subtype']);
- if ($resource) {
- $payload = $resource->getPayload();
- if ($resource->getAlloc()) {
- $code .= " $payload * return_res = ($payload *)ecalloc(1, sizeof($payload));\n";
- } else {
- $code .= " $payload * return_res;\n";
- }
- } else {
- $code .= " void * return_res;\n";
- }
- } else {
- $code .= " void * return_res;\n";
- }
- $code .= " long return_res_id = -1;\n";
- }
-
- return $code;
- }
-
- /**
- * Create C code implementing the PHP userlevel function
- *
- * @param class Extension extension the function is part of
- * @return string C code implementing the function
- */
- function cCode($extension)
- {
- $code = "\n";
-
- switch ($this->role) {
- case "public":
- $code .= $this->ifConditionStart($extension);
-
- // function prototype comment
- $code .= "/* {{{ proto {$this->proto}\n ";
- if (!empty($this->summary)) {
- $code .= $this->summary;
- }
- $code .= " */\n";
-
- // function declaration
- $code .= $this->cProto()."\n";
- $code .= "{\n";
-
- $code .= $this->localVariables($extension);
-
- $var_decl = "\n";
- $var_code = "\n";
-
- // now we create local variables for all parameters
- // at the same time we put together the parameter parsing string
- if (is_array($this->params) && count($this->params)) {
-
- $argString = "";
- $argPointers = array();
- $optional = false;
- $postProcess = "";
- $zvalType = false;
-
- foreach ($this->params as $param) {
- if ($param["type"] === "void" || $param["type"] === "...") {
- continue;
- }
-
- $name = $param['name'];
-
- if ($param['type'] == "resource" && $extension->haveVersion("1.0.0alpha")) {
- $argPointers[] = "&{$name}_res";
- } else {
- $argPointers[] = "&$name";
- }
-
- if (isset($param['optional']) && !$optional) {
- $optional = true;
- $argString .= "|";
- }
-
- switch ($param['type']) {
- case "bool":
- $argString .= "b";
- $default = $this->defaultval($param, "0");
- $var_decl .= " zend_bool $name = $default;\n";
- break;
-
- case "int":
- $argString .= "l";
- $default = $this->defaultval($param, "0");
- $var_decl .= " long $name = $default;\n";
- break;
-
- case "float":
- $argString .= "d";
- $default = $this->defaultval($param, "0.0");
- $var_decl .= " double $name = $default;\n";
- break;
-
- case "string":
- $argString .= "s";
- $default = $this->defaultval($param, "NULL");
- $var_decl .= " const char * $name = $default;\n";
- $var_decl .= sprintf(" int {$name}_len = %d;\n",
- $default==="NULL" ? 0 : strlen($default) - 2);
- $argPointers[] = "&{$name}_len";
- break;
-
- case "unicode":
- $argString .= "u";
- $default = $this->defaultval($param, "NULL");
- $var_decl .= " const char * $name = $default;\n";
- $var_decl .= sprintf(" int {$name}_len = %d;\n",
- $default==="NULL" ? 0 : strlen($default) - 2);
- $argPointers[] = "&{$name}_len";
- break;
-
- case "text":
- $argString .= "t";
- $default = $this->defaultval($param, "NULL");
- $var_decl .= " const char * $name = $default;\n";
- $var_decl .= sprintf(" int {$name}_len = %d;\n",
- $default==="NULL" ? 0 : strlen($default) - 2);
- $var_decl .= " int {$name}_type = IS_STRING;\n"; // TODO depends on input encoding
- $argPointers[] = "&{$name}_len";
- break;
-
- case "array":
- $zvalType = true;
- $argString .= "a";
- $var_decl .= " zval * $name = NULL;\n";
- $var_decl .= " HashTable * {$name}_hash = NULL;\n";
- $postProcess .= " {$name}_hash = HASH_OF($name);\n";
- break;
-
- case "object":
- $zvalType = true;
- $var_decl.= " zval * $name = NULL;\n";
- if (isset($param['subtype'])) {
- $argString .= "O";
- $argPointers[] = "$param[subtype]_ce_ptr";
- } else {
- $argString .= "o";
- }
- break;
-
- case "resource":
- $zvalType = true;
- $resource = false;
- $argString .= "r";
-
- if ($extension->haveVersion("1.0.0alpha")) {
- $resVar = $name."_res";
- $payloadVar = $name;
- $idVar = $name."_resid";
- } else {
- $resVar = $name;
- $payloadVar = "res_".$name;
- $idVar = $name."_id";
- }
-
- $code .= " zval * $resVar = NULL;\n";
- $code .= " int $idVar = -1;\n";
-
- if (isset($param['subtype'])) {
- $resource = $extension->getResource($param['subtype']);
- }
-
- if ($resource) {
- if ($extension->haveVersion("1.0.0dev")) {
- $varname = $name;
- } else {
- $varname = "res_{$name}";
- }
- $code .= " ".$resource->getPayload()." * $payloadVar;\n";
-
- $postProcess .= " ZEND_FETCH_RESOURCE($payloadVar, ".$resource->getPayload()." *, &$resVar, $idVar, \"$param[subtype]\", le_$param[subtype]);\n";
- } else {
- $postProcess .=" ZEND_FETCH_RESOURCE(???, ???, $resVar, $idVar, \"???\", ???_rsrc_id);\n";
- }
- break;
-
- case "stream":
- $zvalType = true;
- $argString .= "r";
- $var_decl .= " zval * {$name}_zval = NULL;\n";
- $var_decl .= " php_stream * $name = NULL:\n";
- $postProcess .= " php_stream_from_zval($name, &_z$name);\n";
- break;
-
- case "callback":
- $postProcess .= " if (!zend_is_callable({$name}, 0, NULL)) {\n";
- $postProcess .= " php_error(E_WARNING, \"Invalid comparison function.\");\n";
- $postProcess .= " return;";
- $postProcess .= " }\n";
- /* fallthru */
- case "mixed":
- $zvalType = true;
- $argString .= "z";
- $var_decl .= " zval * {$name} = NULL;\n";
- break;
- }
-
- if (empty($param['byRef']) && ($param['type'] == 'mixed' || $param['type'] == 'array')) {
- $argString .= "/";
- } else if ($param['type'] == 'object') {
- // nothing to do as objects are passed by reference anyway
- } else if (!$zvalType) {
- // TODO: pass by ref for 'simple' types requires further thinking
- }
- }
- }
-
- if ($this->varargs) {
- $var_decl .= "\n";
- $var_decl .= " int varargc;\n";
- $var_decl .= " zval ***real_argv;\n";
- switch ($this->varargsType) {
- case "bool":
- $var_decl .= " zend_bool *varargv;\n";
- break;
- case "int":
- $var_decl .= " long *varargv;\n";
- break;
- case "float":
- $var_decl .= " double *varargv;\n";
- break;
- case "string":
- $var_decl .= " char **varargv;\n";
- $var_decl .= " int *varargv_len;\n";
- break;
- case "mixed":
- default:
- $var_decl .= " zval ***varargv;\n";
- break;
- }
- $var_decl .= "\n";
- }
-
- $varargs_offset = 0;
- // now we do the actual parameter parsing
-
- if (empty($argString)) {
- if ((!empty($this->params) && $this->params[0]['type'] == "...") // old parser?
- || $this->varargs) {
- } else {
- $var_code .= " if (ZEND_NUM_ARGS()>0) {\n WRONG_PARAM_COUNT;\n }\n\n";
- }
- } else {
- $var_code .= $this->parseParameterHook($argString, $argPointers, $varargs_offset);
-
- if (!empty($postProcess)) {
- $var_code.= "$postProcess\n\n";
- }
- }
-
-
- $code .= "$var_decl\n";
- $code .= "$var_code\n";
-
- if ($this->varargs) {
- $code .= "\n varargc = ZEND_NUM_ARGS();\n";
- $code .= " real_argv = (zval ***)calloc(sizeof(zval **), varargc);\n";
- $code .= " zend_get_parameters_array_ex(varargc, real_argv);\n";
- $code .= " varargc -= $varargs_offset;\n";
-
- switch ($this->varargsType) {
- case "bool":
- $code .= " varargv = (zend_bool *)calloc(sizeof(zend_bool), varargc);\n";
- $code .= " {\n";
- $code .= " int i;\n";
- $code .= " for (i = 0; i < varargc; i++) {\n";
- $code .= " convert_to_boolean_ex(real_argv[i + $varargs_offset]);\n";
- $code .= " varargv[i] = Z_BVAL_PP(real_argv[i + $varargs_offset]);\n";
- $code .= " }\n";
- $code .= " }\n";
- break;
- case "int":
- $code .= " varargv = (long *)calloc(sizeof(long), varargc);\n";
- $code .= " {\n";
- $code .= " int i;\n";
- $code .= " for (i = 0; i < varargc; i++) {\n";
- $code .= " convert_to_long_ex(real_argv[i + $varargs_offset]);\n";
- $code .= " varargv[i] = Z_LVAL_PP(real_argv[i + $varargs_offset]);\n";
- $code .= " }\n";
- $code .= " }\n";
- break;
- case "float":
- $code .= " varargv = (double *)calloc(sizeof(double), varargc);\n";
- $code .= " {\n";
- $code .= " int i;\n";
- $code .= " for (i = 0; i < varargc; i++) {\n";
- $code .= " convert_to_double_ex(real_argv[i + $varargs_offset]);\n";
- $code .= " varargv[i] = Z_DVAL_PP(real_argv[i + $varargs_offset]);\n";
- $code .= " }\n";
- $code .= " }\n";
- break;
- case "string":
- $code .= " varargv = (char **)calloc(sizeof(char *), varargc);\n";
- $code .= " varargv_len = (int *)calloc(sizeof(int), varargc);\n";
- $code .= " {\n";
- $code .= " int i;\n";
- $code .= " for (i = 0; i < varargc; i++) {\n";
- $code .= " convert_to_string_ex(real_argv[i + $varargs_offset]);\n";
- $code .= " varargv[i] = Z_STRVAL_PP(real_argv[i + $varargs_offset]);\n";
- $code .= " varargv_len[i] = Z_STRLEN_PP(real_argv[i + $varargs_offset]);\n";
- $code .= " }\n";
- $code .= " }\n";
- break;
- case "mixed":
- default:
- $code .= " varargv = real_argv + $varargs_offset;\n";
- break;
- }
- }
-
-
- // for functions returning an array we initialize return_value
- if ($this->returns['type'] === "array") {
- $code.=" array_init(return_value);\n\n";
- }
-
- if ($this->code) {
- if ($extension->getLinespecs()) {
- // generate #line preprocessor directive
- if ($this->codeLine) {
- $linedef = "#line {$this->codeLine}";
- if ($this->codeFile) {
- $linedef.= ' "'.$this->codeFile.'"';
- }
- $linedef.= "\n";
- } else {
- $linedef = "";
- }
- }
-
- $code .= $extension->codegen->varblock($linedef . $this->code);
- // free varargs array if exists
- if ($this->varargs) {
- $code .= "\n free(real_argv);\n";
- switch ($this->varargsType) {
- case "string":
- $code .=" free(varargv_len);\n";
- case "bool":
- case "int":
- case "float":
- $code .=" free(varargv);\n";
- break;
- default:
- break;
- }
- }
-
- // when a function returns a named resource we know what to do
- if ($this->returns['type'] == "resource" && isset($this->returns['subtype'])) {
- $code .= "\n return_res_id = ZEND_REGISTER_RESOURCE(return_value, return_res, le_"
- .$this->returns['subtype'].");\n";
- }
- } else {
- // no code snippet was given so we produce a suggestion for the return statement
- $code .= " php_error(E_WARNING, \"{$this->name}: not yet implemented\"); RETURN_FALSE;\n\n";
-
- switch ($this->returns['type']) {
- case "void":
- break;
-
- case "bool":
- $code .= " RETURN_FALSE;\n";
- break;
-
- case "int":
- $code .= " RETURN_LONG(0);\n";
- break;
-
- case "float":
- $code .= " RETURN_DOUBLE(0.0);\n";
- break;
-
- case "string":
- $code .= " RETURN_STRINGL(\"\", 0, 1);\n";
- break;
-
- case "array":
- $code .= " array_init(return_value);\n";
- break;
-
- case "object":
- $code .= " object_init(return_value)\n";
- break;
-
- case "resource":
- if (isset($this->returns['subtype'])) {
- $code .= " ZEND_REGISTER_RESOURCE(return_value, return_res, le_"
- .$this->returns['subtype'].");\n";
- } else {
- $code .= " /* RETURN_RESOURCE(...); */\n";
- }
- break;
-
- case "stream":
- $code .= " /* php_stream_to_zval(stream, return_value); */\n";
- break;
-
- case "mixed":
- $code .= " /* RETURN_...(...); */\n";
- break;
-
- default:
- $code .= " /* UNKNOWN RETURN TYPE '".$this->returns['type']."' */\n";
- break;
- }
- }
-
- $code .= "}\n/* }}} {$this->name} */\n\n";
-
- $code .= $this->ifConditionEnd($extension);
-
- break;
-
- case "internal":
- if (!empty($this->code)) {
- $code .= $extension->codegen->varblock($this->code."\n");
- }
- break;
- }
- return $code;
- }
-
-
-
- /**
- * Create DocBook reference entry for the function
- *
- * @param string base (currently not used)
- * @return string DocBook XML code
- */
- function docEntry($base)
- {
- $xml =
- '<?xml version="1.0" encoding="iso-8859-1"?>
-<!-- '.'$'.'Revision: 1.0 $ -->
- <refentry id="function.' . strtolower(str_replace("_", "-", $this->name)) . '">
- <refnamediv>
- <refname>' . $this->name . '</refname>
- <refpurpose>' . $this->summary . '</refpurpose>
- </refnamediv>
- <refsect1>
- <title>Description</title>
- <methodsynopsis>
-';
-
- $returns = $this->returns['type'];
- if (isset($this->returns['subtype'])) {
- $returns .= " ".$this->returns['subtype'];
- }
- if (@$this->returns['byref']) {
- $returns .= " &";
- }
-
- $xml .= " <type>$returns</type><methodname>{$this->name}</methodname>\n";
- if (empty($this->params) || $this->params[0]["type"] === "void") {
- $xml .= " <void/>\n";
- } else if ($this->params[0]["type"] === "...") {
- $xml .= " <methodparam choice='opt' rep='repeat'><type>mixed</type><parameter>...</parameter></methodparam>\n";
- } else {
- foreach ($this->params as $key => $param) {
- if (isset($param['optional'])) {
- $xml .= " <methodparam choice='opt'>";
- } else {
- $xml .= " <methodparam>";
- }
- $xml .= "<type>$param[type]</type><parameter>";
- if (isset($param['byRef'])) {
- $xml .= "&amp;";
- }
- $xml .= "$param[name]</parameter>";
- $xml .= "</methodparam>\n";
- }
- }
-
-
- $description = $this->description;
-
- if (!strstr($this->description, "<para>")) {
- $description = " <para>\n$description </para>\n";
- }
-
- $xml .=
- ' </methodsynopsis>
-'.$description.'
- </refsect1>
- </refentry>
-';
-
- return $xml;
- }
-
-
-
- /**
- * write test case for this function
- *
- * @param class Extension extension the function is part of
- */
- function writeTest(CodeGen_PECL_Extension $extension)
- {
- $test = $this->createTest($extension);
-
- if ($test instanceof CodeGen_PECL_Element_Test) {
- $test->writeTest($extension);
- }
- }
-
- /**
- * Create test case for this function
- *
- * @param object extension the function is part of
- * @return object generated test case
- */
- function createTest(CodeGen_PECL_Extension $extension)
- {
- if (!$this->testCode) {
- return false;
- }
-
- $test = new CodeGen_PECL_Element_Test;
-
- $test->setName($this->name);
- $test->setTitle($this->name."() function");
-
- if ($this->testDescription) {
- $test->setDescription($this->testDescription);
- }
-
- if ($this->testIni) {
- $test->addIni($this->testIni);
- }
-
- $test->setSkipIf("!extension_loaded('".$extension->getName()."')");
- if ($this->ifCondition) {
- $test->addSkipIf("!function_exists('{$this->name}')", "not compiled in ($this->ifCondition)");
- }
- if ($this->testSkipIf) {
- $test->addSkipIf($this->testSkipIf);
- }
-
- $test->setCode($this->testCode);
-
- if (!empty($this->testResult)) {
- $test->setOutput($this->testResult['result']);
- if (isset($this->testResult['mode'])) {
- $test->setMode($this->testResult['mode']);
- }
- }
-
- return $test;
- }
-
-
- /**
- * C function signature
- *
- * @return string C snippet
- */
- function cProto()
- {
- return "PHP_FUNCTION({$this->name})";
- }
-
- /**
- * Create C header entry for userlevel function
- *
- * @param class Extension extension the function is part of
- * @return string C header code snippet
- */
- function hCode($extension)
- {
- $code = $this->ifConditionStart();
-
- $code .= $this->cProto();
- if ($code) {
- $code.= ";\n";
- }
-
- $code.= $this->argInfoCode($this->params);
-
- $code.= $this->ifConditionEnd();
-
- return $code;
- }
-
-
- /**
- * Code needed ahead of the function table
- *
- * @param array
- * @return string
- */
- function argInfoCode($params)
- {
- // TODO only generate code for versions actually requested
- // TODO only allow null on objects/arrays with default=NULL ?
-
- $argInfoName = $this->argInfoName();
-
- $code = "";
-
- // generate refargs mask if needed
- $code.= "#if (PHP_MAJOR_VERSION >= 5)\n";
-
- $minArgs = 0;
- foreach ($params as $param) {
- if (isset($param["optional"])) break;
- $minArgs++;
- }
-
- $code.= sprintf("ZEND_BEGIN_ARG_INFO_EX($argInfoName, ZEND_SEND_BY_VAL, ZEND_RETURN_%s, %d)\n",
- isset($this->returns["byRef"]) ? "REFERENCE" : "VALUE",
- $minArgs);
-
- foreach ($params as $param) {
- switch ($param["type"]) {
- case 'object':
- $code.= sprintf(" ZEND_ARG_OBJ_INFO(%d, %s, %s, 1)\n",
- isset($param["byRef"]),
- $param["name"],
- $param["subtype"]);
- break;
- case 'array':
- $code.= "#if (PHP_MINOR_VERSION > 0)\n";
- $code.= sprintf(" ZEND_ARG_ARRAY_INFO(%d, %s, %d)\n",
- isset($param["byRef"]),
- $param["name"],
- 1 /*allow NULL*/);
- $code.= "#else\n";
- $code.= sprintf(" ZEND_ARG_INFO(%d, %s)\n",
- isset($param["byRef"]),
- $param["name"],
- 1 /*allow NULL*/);
- $code.= "#endif\n";
- break;
- default:
- $code.= sprintf(" ZEND_ARG_INFO(%d, %s)\n",
- isset($param["byRef"]),
- $param["name"]);
- break;
- }
- }
-
- $code.= "ZEND_END_ARG_INFO()\n";
-
- $code.= "#else /* PHP 4.x */\n";
-
- if ($this->hasRefArgs) {
- $code.= "static unsigned char {$argInfoName}[] = {".count($params);
- foreach ($params as $param) {
- $code.= ", ". (isset($param["byRef"]) ? "BYREF_FORCE" : "BYREF_NONE");
- }
- $code.="};\n";
- } else {
- $code .= "#define $argInfoName NULL\n";
- }
- $code.= "#endif\n\n";
-
- return $code;
- }
-
- /**
- * Name for ARG_INFO definition
- *
- * @return string
- */
- function argInfoName()
- {
- return $this->name."_arg_info";
- }
-
- /**
- * Generate registration entry for extension function table
- *
- * @return string
- */
- function functionEntry()
- {
- $code = $this->ifConditionStart();
-
- $code .= sprintf(" PHP_FE(%-20s, %s)\n", $this->name, "{$this->name}_arg_info");
-
- $code.= $this->ifConditionEnd();
-
- return $code;
- }
-
- function addParam($param)
- {
- foreach ($this->params as $p) {
- if ($param["name"] == $p["name"]) {
- return PEAR::raiseError("Parameter '".$param['name']."' already declared");
- }
- }
-
- $this->params[] = $param;
- if (@$param['byRef']) {
- $this->hasRefArgs = true;
- }
-
- return true;
- }
-
- function setReturns($returns)
- {
- $this->returns = $returns;
- }
-
- function ifConditionStart($extension = false)
- {
- $code = parent::ifConditionStart();
-
- if ($extension) {
- $params = $this->params;
- $params[] = $this->returns;
-
- foreach ($params as $param) {
- if ($param["type"] == "resource" && isset($param['subtype'])) {
- $obj = $extension->getResource($param['subtype']);
- } else if ($param["type"] == "object" && isset($param['subtype'])) {
- $obj = $extension->getClass($param['subtype']);
- } else if (isset($param["default"]) && is_object($param["default"])) {
- $obj = $param["default"];
- } else {
- continue;
- }
- if (is_object($obj)) {
- $code.= $obj->ifConditionStart();
- }
- }
- }
-
- return $code;
- }
-
- function ifConditionEnd($extension = false)
- {
- $code = "";
-
- if ($extension) {
- $params = $this->params;
- $params[] = $this->returns;
-
- $params = array_reverse($params);
-
- foreach ($params as $param) {
- if ($param["type"] == "resource" && isset($param['subtype'])) {
- $obj = $extension->getResource($param['subtype']);
- } else if ($param["type"] == "object" && isset($param['subtype'])) {
- $obj = $extension->getClass($param['subtype']);
- } else if (isset($param["default"]) && is_object($param["default"])) {
- $obj = $param["default"];
- } else {
- continue;
- }
- if (is_object($obj)) {
- $code.= $obj->ifConditionEnd();
- }
- }
- }
-
- $code .= parent::ifConditionEnd();
-
- return $code;
- }
-
- /**
- * Return minimal PHP version required to support the requested features
- *
- * @return string version string
- */
- function minPhpVersion()
- {
- // return by reference only exist in 5.1 and above
- if (isset($this->returns["byRef"])) {
- return "5.1.0rc1";
- }
-
- // default: 4.0
- return "4.0.0"; // TODO test for real lower bound
- }
-
-}
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * indent-tabs-mode:nil
- * End:
- */
-?>
View
12 CodeGen/PECL/Element/Function.php.rej
@@ -1,12 +0,0 @@
---- /dev/null
-+++ /dev/null
-@@ -1130,7 +1130,8 @@
- case "array":
- $zvalType = true;
- $argString .= "a";
-- $var_decl .= " zval * $name = NULL;\n";
-+ $var_decl .= " zval * $name;\n";
-+ $var_code .= " MAKE_STD_ZVAL($name);\n array_init($name);\n";
- $var_decl .= " HashTable * {$name}_hash = NULL;\n";
- $postProcess .= " {$name}_hash = HASH_OF($name);\n";
- break;
View
15 CodeGen/PECL/Element/Interface.php
@@ -326,5 +326,20 @@ function getPayloadType()
{
return "";
}
+
+ /**
+ * Return minimal PHP version required to support the requested features
+ *
+ * @return string version string
+ */
+ function minPhpVersion()
+ {
+ if (!empty($this->namespace)) {
+ return "5.3.0";
+ }
+
+ // default: 5.0
+ return "5.0.0"; // TODO test for real lower bound
+ }
}
View
10 CodeGen/PECL/Extension.php
@@ -2526,6 +2526,16 @@ function minPhpVersion()
$version = $this->maxVersion($version, $function->minPhpVersion());
}
+ // check class requirements
+ foreach ($this->classes as $class) {
+ $version = $this->maxVersion($version, $class->minPhpVersion());
+ }
+
+ // check interface requirements
+ foreach ($this->interfaces as $interface) {
+ $version = $this->maxVersion($version, $interface->minPhpVersion());
+ }
+
return $version;
}
Please sign in to comment.
Something went wrong with that request. Please try again.