+++ /dev/null
-<?php\r
-/**\r
-* Functions used to parse PHPDoc Tags.\r
-* \r
-* @version $Id: PhpdocParserTags.php,v 1.4 2000/12/03 22:37:37 uw Exp $\r
-*/\r
-class PhpdocParserTags extends PhpdocParserRegExp {\r
- \r
- /**\r
- * Extract the value from the given tags and copy the data to the $data array if its an allowed tag\r
- *\r
- * @param array $tags array of tags returned by getTags\r
- * @param array $data array where the allowed tags and their values are copied to\r
- * @param array $allowed array of allowed (recognized) tags\r
- * @return array $data\r
- * @throws PhpdocError\r
- * @see getTags(), analyseVariableParagraphs(), analyseFunctionParagraphs(), analyseClassParagraphs(), analyseSeeTags()\r
- */\r
- function analyseTags($tags, $data, $allowed) {\r
- \r
- if (!is_array($tags) || !is_array($data) || !is_array($allowed)) {\r
- $this->err[] = new PhpdocError("Illegal function call", __FILE__, __LINE__);\r
- return $data;\r
- }\r
-\r
- reset($tags);\r
- while (list($k, $tag) = each($tags)) { \r
- \r
- $tagname = substr( strtolower($tag["tag"]), 1 );\r
- if (!isset($allowed[$tagname])) {\r
- $data["notallowed"][$tagname] = true;\r
- continue;\r
- }\r
- \r
- switch ($tagname) {\r
- \r
- # @tagname description\r
- case "exclude":\r
- case "package":\r
- case "magic":\r
- case "todo":\r
- case "version":\r
- case "since":\r
- case "include":\r
- case "copyright":\r
- \r
- if (isset($data[$tagname])) { \r
- \r
- $tag["msg"] = "This tag must be used only once within a doc comment. First declaration gets used.";\r
- $data["syntaxerror"][] = $tag;\r
- break;\r
- \r
- }\r
- \r
- if ("" == $tag["value"]) {\r
- \r
- $tag["msg"] = "Description is missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- $data[$tagname] = $tag["value"];\r
- \r
- } else \r
- $data[$tagname] = $tag["value"];\r
- \r
- break;\r
- \r
- # @tagname [void] \r
- case "abstract": \r
- case "static": \r
- case "final":\r
- \r
- if (isset($data[$tagname])) {\r
- \r
- $tag["msg"] = "This tag must be used only once within a doc comment. First declaration gets used.";\r
- $data["syntaxerror"][] = $tag;\r
- break;\r
- \r
- }\r
- \r
- if ("" != $tag["value"]) {\r
- \r
- $tag["msg"] = "Description gets ignored, syntax: '".$this->PHPDOC_TAGS["@$tagname"]."'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- $data[$tagname] = true;\r
- break;\r
- \r
- case "var":\r
- case "return":\r
-\r
- if (isset($data[$tagname])) {\r
- \r
- $tag["msg"] = "This tag must be used only once within a doc comment. First declaration gets used.";\r
- $data["syntaxerror"][] = $tag;\r
- break;\r
- \r
- }\r
- \r
- if (preg_match($this->TAGS[$tagname], $tag["value"], $regs)) {\r
-\r
- $desc = "";\r
- \r
- if ("object" == $regs[1]) {\r
- \r
- $type = "object ";\r
- if ( "" == $regs[2] ) {\r
- \r
- $type .= "[unknown]";\r
- $tag["msg"] = "Objectname is missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag; \r
- \r
- } else {\r
- \r
- $type .= $regs[2];\r
- \r
- }\r
- \r
- $desc = $regs[4];\r
- \r
- } else {\r
- \r
- $type = $regs[1];\r
- $desc = $regs[2] . " " . $regs[4];\r
- \r
- }\r
- \r
- $data[$tagname] = array (\r
- "type" => $type,\r
- "name" => $regs[3],\r
- );\r
- \r
- if ("" != trim($desc)) \r
- $data[$tagname]["desc"] = $desc;\r
-\r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $tag["msg"] .= $this->TAGS[$tagname];\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- break;\r
- \r
- case "global":\r
-\r
- if (preg_match($this->TAGS["global"], $tag["value"], $regs)) {\r
- \r
- if ("" == $regs[3]) {\r
- \r
- $tag["msg"] = "Variablename ist missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- \r
- if ("object" == $regs[1]) {\r
- \r
- $type = "object ";\r
- if ( "" == $regs[2] ) {\r
- \r
- $type .= "[unknown]";\r
- $tag["msg"] = "Objectname is missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag; \r
- \r
- } else {\r
- \r
- $type .= $regs[2];\r
- \r
- }\r
- \r
- } else {\r
- \r
- $type = $regs[1];\r
- \r
- }\r
- \r
- if ("" == $regs[4]) {\r
- $data["global"][] = array (\r
- "type" => $type,\r
- "name" => $regs[3]\r
- );\r
- } else {\r
- $data["global"][] = array (\r
- "type" => $type,\r
- "name" => $regs[3],\r
- "desc" => $regs[4]\r
- );\r
- }\r
- \r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- \r
- break;\r
- \r
- case "param":\r
- case "parameter":\r
-\r
- if (preg_match($this->TAGS["var"], $tag["value"], $regs)) {\r
-\r
- if ("object" == $regs[1]) {\r
- \r
- $type = "object ";\r
- if ("" == $regs[2]) {\r
- \r
- $type .= "[unknown]";\r
- $tag["msg"] = "Objectname is missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag; \r
- \r
- } else {\r
- \r
- $type .= $regs[2];\r
- \r
- }\r
- \r
- } else {\r
- \r
- $type = $regs[1];\r
- \r
- } \r
- \r
- if ("" == $regs[4]) {\r
- $data["params"][] = array (\r
- "type" => $type,\r
- "name" => $regs[3]\r
- );\r
- } else {\r
- $data["params"][] = array (\r
- "type" => $type,\r
- "name" => $regs[3],\r
- "desc" => $regs[4]\r
- );\r
- }\r
- \r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: '".$this->PHPDOC_TAGS["@$tagname"]."'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- \r
- break;\r
- \r
- case "see":\r
-\r
- if ("" != $tag["value"]) {\r
- \r
- $error = "";\r
- $references = explode(",", $tag["value"] );\r
- reset($references);\r
- while (list($k, $reference) = each($references)) {\r
- \r
- if (preg_match($this->TAGS["see_var"], $reference, $regs)) {\r
- \r
- list($msg, $entry) = $this->analyseSeeTagRegs($regs);\r
- $error .= $msg;\r
- if (count($entry) > 0)\r
- $data["see"]["var"][] = $entry; \r
- \r
- } else if (preg_match($this->TAGS["see_function"], $reference, $regs)) {\r
- \r
- list($msg, $entry) = $this->analyseSeeTagRegs($regs);\r
- $error .= $msg;\r
- if (count($entry) > 0)\r
- $data["see"]["function"][] = $entry;\r
- \r
- } else if (preg_match($this->TAGS["see_moduleclass"], $reference, $regs)) {\r
-\r
- $name = $regs[1];\r
-\r
- if (substr($name, 0, $this->C_COMPLEX["module_separator_len"]) == $this->C_BASE["module_separator"]) {\r
- \r
- $name = substr($name, $this->C_COMPLEX["module_separator_len"]);\r
- if ("" == $name) {\r
- \r
- $error .= "Element name is missing: '$regs[0]'. Reference gets ignored";\r
- continue;\r
- \r
- } else {\r
- \r
- $error .= "Element name starts with moduleseparator, module name forgotten '$regs[0]'?";\r
- continue;\r
- \r
- }\r
- \r
- } else if (!strstr($name, $this->C_BASE["module_separator"])) {\r
- \r
- $error .= "Use function() to referr to functions and $var to referr to variables - don't know what '$name' referrs to.";\r
- continue;\r
- \r
- }\r
- \r
- $data["see"]["moduleclass"][] = $name;\r
- \r
- } else {\r
- \r
- $error .= "Unknown syntax '$reference'";\r
- \r
- }\r
- \r
- }\r
- \r
- if ( "" != $error) {\r
- \r
- $tag["msg"] = sprintf("Could not understand all references. %s. Syntax: '%s' (function), '%s' (variable), '%s' (module or class).",\r
- $error,\r
- $this->C_COMPLEX["see_function"],\r
- $this->C_COMPLEX["see_var"],\r
- $this->C_COMPLEX["see_moduleclass"]\r
- );\r
- $data["syntaxerror"][] = $tag;\r
-\r
- }\r
- \r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- break;\r
- \r
- case "link":\r
- \r
- if (preg_match($this->TAGS["link"], $tag["value"], $regs)) {\r
-\r
- $desc = trim($regs[2]);\r
- if ("" == $desc) {\r
- \r
- $data["link"][] = array(\r
- "url" => $regs[1]\r
- );\r
- \r
- } else { \r
- \r
- $data["link"][] = array(\r
- "url" => $regs[1],\r
- "desc" => trim($regs[2])\r
- );\r
- \r
- }\r
- \r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- break;\r
- \r
- case "throws":\r
- \r
- if ("" != $tag["value"]) {\r
- \r
- $exceptions = explode(",", $tag["value"]);\r
- reset($exceptions);\r
- while (list($k, $exception) = each($exceptions)) \r
- $data["throws"][] = trim($exception);\r
- \r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- break;\r
- \r
- case "access":\r
- \r
- if (preg_match($this->TAGS["access"], $tag["value"], $regs)) {\r
- \r
- $data["access"] = $regs[1];\r
- \r
- } else {\r
-\r
- $tag["msg"] = ("" == $tag["value"]) ? "General syntax error," : "Access modifier unknown,";\r
- $tag["msg"].= " '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag; \r
- \r
- }\r
- \r
- break;\r
- \r
- case "deprec":\r
- case "deprecated":\r
- \r
- if (isset($data["deprec"])) {\r
- \r
- $tag["msg"] = "This tag must be used only once within a doc comment. First declaration gets used.";\r
- $data["syntaxerror"][] = $tag;\r
- break;\r
- \r
- } \r
- \r
- if ("" != $tag["value"]) {\r
- \r
- $data["deprec"] = $tag["value"];\r
- \r
- } else {\r
- \r
- $tag["msg"] = "Description is missing, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- break;\r
- \r
- case "brother":\r
- case "sister":\r
- \r
- if (isset($data["brother"])) {\r
- \r
- $tag["msg"] = "This tag must be used only once within a doc comment. First declaration gets used.";\r
- $data["syntaxerror"][] = $tag;\r
- break;\r
- \r
- }\r
- \r
- if ("" != $tag["value"]) {\r
- \r
- if (preg_match($this->TAGS["brother"], $tag["value"], $regs)) {\r
- \r
- $data["brother"] = $regs[1];\r
- \r
- } else {\r
- \r
- $tag["msg"] = "Can't find a function name nor a variable name, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- \r
- } else {\r
- \r
- $data["msg"] = "General syntax error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- break;\r
-\r
- case "module":\r
- case "modulegroup":\r
- \r
- if (isset($data[$tagname])) {\r
- \r
- $tag["msg"] = "This tag must be used only once within a doc comment. First declaration gets used.";\r
- $data["syntaxerror"][] = $tag;\r
- break;\r
- \r
- }\r
- \r
- if ("" != $tag["value"]) {\r
- \r
- if (preg_match($this->TAGS["module"], $tag["value"], $regs)) {\r
- \r
- $data[$tagname] = $regs[0];\r
- \r
- } else {\r
-\r
- $tag["msg"] = "Illegal label used, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'."; \r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- \r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- break; \r
- \r
- case "const":\r
- case "constant": \r
- \r
- if (isset($data["const"])) {\r
- \r
- $tag["msg"] = "This tag must be used only once within a doc comment. First declaration gets used.";\r
- $data["syntaxerror"][] = $tag;\r
- break;\r
- \r
- } \r
- \r
- if ("" != $tag["value"]) {\r
- \r
- if (preg_match($this->TAGS["const"], $tag["value"], $regs)) {\r
- \r
- $data["const"] = array(\r
- "name" => $regs[1],\r
- "desc" => trim($regs[2])\r
- );\r
- \r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- \r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: '" . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
-\r
- }\r
- break;\r
- \r
- case "author":\r
- \r
- if ("" != $tag["value"]) {\r
- \r
- $authors = explode(",", $tag["value"]);\r
- reset($authors);\r
- while (list($k, $author) = each($authors)) {\r
-\r
- if (preg_match($this->TAGS["author"], $author, $regs)) {\r
- \r
- $data["author"][] = array(\r
- "name" => trim(substr($author, 0, strpos($author, $regs[0]))),\r
- "mail" => trim($regs[1])\r
- );\r
- } else if (""!=trim($author)) {\r
- \r
- $data["author"][] = array(\r
- "name" => trim($author)\r
- );\r
- \r
- } else {\r
- \r
- $tag["msg"] = "Name is missing in enumeration, syntax: '".$this->PHPDOC_TAGS["@$tagname"]."'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
- \r
- }\r
- \r
- } else {\r
- \r
- $tag["msg"] = "General syntax error, syntax: " . $this->PHPDOC_TAGS["@$tagname"] . "'.";\r
- $data["syntaxerror"][] = $tag;\r
- \r
- }\r
-\r
- break;\r
- \r
- default:\r
- // I'm quite sure this default is obsolete, but I don't feel like checking it.\r
- // Anyway this array index should get used one fine day.\r
- $data["unknown"][] = $tag;\r
- break;\r
- } \r
- \r
- } \r
-\r
- return $data; \r
- } // end func analyseTags\r
- \r
- /**\r
- * Helperfunction to analyse see tags\r
- *\r
- * @param array Array return by preg_match()\r
- * @return array $see[0] = error, $see[1] = data\r
- * @see analyseTags()\r
- */\r
- function analyseSeeTagRegs($regs) {\r
- \r
- $error = "";\r
- $group = trim($regs[1]);\r
- $name = trim($regs[2]);\r
- \r
- if (substr($name, 0, $this->C_COMPLEX["module_separator_len"]) == $this->C_BASE["module_separator"]) {\r
- \r
- $name = substr($name, $this->C_COMPLEX["module_separator_len"]);\r
- if ("" == $name) {\r
- \r
- $error = "Element name is missing '$regs[0]'. Reference gets ignored";\r
- return array($error, array());\r
- \r
- } else {\r
- \r
- $error = "Element name starts with moduleseparator, module name forgotten '$regs[0]'?";\r
- \r
- }\r
- \r
- }\r
- \r
- if ("" != $group && $this->C_BASE["module_separator"] != $group) {\r
- \r
- $group = substr($group, 0, $this->C_COMPLEX["module_separator_len_neg"]);\r
- if ("" == $group) {\r
-\r
- $error = "Groupname missing '$regs[0]'.";\r
- $data = array( "name" => $name );\r
- \r
- } else {\r
- \r
- $data = array ( \r
- "group" => $group,\r
- "name" => $name\r
- );\r
- \r
- }\r
- \r
- } else {\r
- \r
- $data = array ( "name" => $name );\r
- \r
- }\r
- \r
- return array($error, $data);\r
- } // end func analyseSeeTagRegs\r
- \r
- /**\r
- * Extracts PHPDoc tags from a PHPDoc doc comment.\r
- *\r
- * @param string Doc comment.\r
- * @return array List of tags ordered by their appearance containing the \r
- * tag name and it's (unparsed) value.\r
- * @see getTagPos()\r
- */\r
- function getTags($phpdoc) {\r
-\r
- $positions = $this->getTagPos($phpdoc);\r
- \r
- if (0 == count($positions))\r
- return array();\r
- \r
- reset($positions);\r
- list($k, $data) = each($positions);\r
- $lastpos = $data["pos"];\r
- $lasttag = $data["tag"];\r
- \r
- while (list($k, $data) = each($positions)) {\r
- \r
- $line = substr($phpdoc, $lastpos, ($data["pos"] - $lastpos));\r
- $value = trim(substr($line, strlen($lasttag)));\r
- $tags[] = array ("tag" => $lasttag, "value" => $value );\r
- \r
- $lastpos = $data["pos"];\r
- $lasttag = $data["tag"];\r
- \r
- }\r
- \r
- $line = substr($phpdoc, $lastpos);\r
- $value = trim(substr($line, strlen($lasttag)));\r
- $tags[] = array ("tag" => $lasttag, "value" => $value );\r
-\r
- return $tags;\r
- } // end func getTags\r
- \r
- /**\r
- * Find the position of the next phpdoc tag.\r
- *\r
- * @param string $phpdoc \r
- * @param integer $offset\r
- * @return array $tag 0 => tag, 1 => offset\r
- * @access private\r
- * @see findTags()\r
- */\r
- function getTagPos($phpdoc, $offset = 0) {\r
- \r
- $positions = array();\r
- \r
- preg_match_all($this->TAGS["all"], $phpdoc, $regs, PREG_SET_ORDER);\r
- \r
- reset($regs);\r
- while (list($k, $data) = each($regs)) {\r
- \r
- $pos = strpos($phpdoc, $data[0], $offset);\r
- \r
- if ($pos > 0 || $data[0] == substr($phpdoc, 0, strlen($data[0])) ) {\r
- $positions[] = array ("pos" => $pos, "tag" => $data[0]);\r
- $offset = $pos+1;\r
- }\r
- \r
- }\r
-\r
- return $positions;\r
- } // end func getTagPos \r
- \r
- /**\r
- * Takes an array filled by analyseTags() and converts the parse errors into a single error message.\r
- * \r
- * Checks for [syntaxerror], [notallowed] and [unknown] entries in the data hash,\r
- * converts them into an error message and unsets the indizes. The function\r
- * returns a hash containing the aggregates error message and the modified \r
- * data hash.\r
- *\r
- * @param array $data\r
- * @param string $mode Keyword where the data hash comes from eg. function/class...\r
- * @return array array( $error_msg, $data )\r
- */\r
- function checkParserErrors($data, $mode) {\r
- \r
- $msg = "";\r
- // tags with an incorrect syntax\r
- if (isset($data["syntaxerror"])) {\r
-\r
- $msg.= "PHPDoc found " . count($data["syntaxerror"]) . " syntax error(s) in the tag list. ";\r
- \r
- reset($data["syntaxerror"]);\r
- while (list($k, $error) = each($data["syntaxerror"])) \r
- $msg.= sprintf("Tag: '%s %s' - %s.", $error["tag"], $error["value"], $error["msg"]);\r
- \r
- unset($data["syntaxerror"]); \r
- \r
- }\r
- \r
- // tags that are not allowed in this context\r
- if (isset($data["notallowed"])) {\r
- \r
- $msg .= count($data["notallowed"]) . " tag[s] were used that are not allowed in $mode doc comments: ";\r
- \r
- reset($data["notallowed"]);\r
- while (list($tagname, $v) = each($data["notallowed"]))\r
- $msg .= "$tagname, ";\r
- \r
- $msg = substr($msg, 0, -2) . ".";\r
- unset($data["notallowed"]);\r
- }\r
- \r
- // unknown tags\r
- if (isset($data["unknown"])) {\r
- \r
- $msg .= "PHPDoc found " . count($data["unknown"]) . " tag[s] that are unknown: ";\r
- \r
- reset($data["unknown"]);\r
- while (list($k, $error) = each($data["unknown"]))\r
- $msg.= sprintf("%s, ", $error["tag"]);\r
- \r
- $msg = substr($msg, 0, -2) . ".";\r
- unset($data["unknown"]);\r
- }\r
- \r
- return array($msg, $data);\r
- } // end func checkParserErrors\r
- \r
-} // end class PhpdocParserTags\r
-?>
\ No newline at end of file