changed git call from https to git readonly
[atutor.git] / mods / phpdoc / PHPDoc / parser / PhpdocParserCore.php
1 <?php\r
2 /**\r
3 * Provides basic parser functions.\r
4 *\r
5 * Provides basic parser functions to extract doc comments, analyse tags and variable\r
6 * declarations.\r
7 *\r
8 * @version  $Id: PhpdocParserCore.php,v 1.3 2000/12/03 22:37:37 uw Exp $\r
9 */\r
10 class PhpdocParserCore extends PhpdocParserTags {\r
11                                         \r
12         /**\r
13         * Scans code for documented and undocumented phpdoc keywords (classes, functions, class variables, uses, constants).\r
14         *\r
15         * This method is somewhat the heart of the phpdoc parser. It takes a string of \r
16         * phpcode and extracts all classes, functions, class variables, uses (include and friends), \r
17         * and constants (define) from it. Extract does not mean that the whole class or another element\r
18         * gets extracted. It does not take the code from the class definition and it's opening \r
19         * curly brace to the closing one. PHPDoc just extracts the class definition itself and \r
20         * if available a trailing doc comment. This has some drawbacks: phpdoc can't handle \r
21         * files that contain more than one class it wouldn't know which method/class variable belongs to \r
22         * a certain class. It's possible to provide a workaround but phpdoc would slow down dramatically.\r
23         * As PHPDoc does not have a real parser but does a simple grep using a bunch of regular expressions\r
24         * there're indeed more limitations. Nevertheless I doubt that you'll have problems with "normal" code.\r
25         *\r
26         * The search algorithm looks pretty strange but belive me it's fast. I have tried several other ways\r
27         * (really complex regexps >500 chars, preg_match_all + looking backwards for comments, ...) but none was\r
28         * faster. This one takes 13s on my machine to scan the current (14/08/2000) code (7130 lines), the \r
29         * big RegExp way took more than 5 Minutes, the preg_match_all + looking backwards 52s.\r
30         *\r
31         * @param        string  PHP code to scan.\r
32         * @param        mixed           String of one keyword or array of keywords not to scan for. Known keywords are:\r
33         *                                                                       "classes", "functions", "variables", "uses", "consts".\r
34         * @return       array   Hash of phpdoc elements found, indexed by "variables", "functions", "classes", "consts", "uses".\r
35         * @see          $PHP_BASE, $PHP_COMPLEX, $C_BASE, $C_COMPLEX, extractPhpdoc(), getModuleDoc()\r
36         */                                      \r
37         function getPhpdocParagraphs($phpcode, $keywords="none") {\r
38 \r
39                 // what are we not looking for?         \r
40                 if ( !is_array($keywords) ) {\r
41                         if ("none" == $keywords) \r
42                                 $keywords = array ();\r
43                         else\r
44                                 $keywords = array ( $keywords => true );\r
45                 }\r
46                 \r
47                 $start                          = 0;\r
48                 $paragraphs     = array(\r
49                                                                                                         "classes"               => array(),\r
50                                                                                                         "functions"     => array(),\r
51                                                                                                         "variables"     => array(),\r
52                                                                                                         "consts"                => array(),\r
53                                                                                                         "uses"                  => array(),\r
54                                                                                                         "modules"               => array()\r
55                                                                                         );\r
56 \r
57 \r
58                 // remember the documented elements to be able to compare with the list of all elements                                                                                                 \r
59                 $variables = array();\r
60                 $functions = array();\r
61                 $variables = array();\r
62                 $constants = array();\r
63                 $uses            = array();\r
64                 \r
65                 //\r
66                 // Module docs are somewhat more difficult to grep. Always\r
67                 // use this function.\r
68                 //\r
69                 if (!isset($keywords["modules"]))\r
70                         list($paragraphs["modules"], $phpcode) = $this->getModuleDoc($phpcode);\r
71                 else\r
72                         list( , $phpcode) = $this->getModuleDoc($phpcode);\r
73                         \r
74                 //\r
75                 // Find documented elements\r
76                 //\r
77 \r
78                 while (true) {\r
79                         \r
80                         $start = strpos($phpcode, "/**", $start);\r
81                         if (0==(int)$start && "integer" != gettype($start) ) \r
82                                 break;\r
83 \r
84       $end                              = strpos($phpcode, "*/", $start);\r
85                         $remaining      = trim(substr($phpcode, $end+2));\r
86                         \r
87                         if ( !isset($keywords["classes"]) && preg_match($this->PHP_COMPLEX["class"], $remaining, $regs) || preg_match($this->PHP_COMPLEX["class_extends"], $remaining, $regs)) {\r
88                                 \r
89                                 $paragraphs["classes"][] = array(\r
90                                                                                                                                                                         "name"          => $regs[1],\r
91                                                                                                                                                                         "extends"       => (isset($regs[2])) ? $regs[2] : "",\r
92                                                                                                                                                                         "doc"                   => $this->extractPhpdoc(substr($phpcode, $start+3, ($end-$start)-2))\r
93                                                                                                                                                         );\r
94                                 $classes[$regs[1]] = true;                                              \r
95                         \r
96                         } else if ( !isset($keywords["functions"]) &&   preg_match($this->PHP_COMPLEX["function"], $remaining, $regs)) {\r
97 \r
98                                 $head = substr($remaining, strpos($remaining, $regs[0])+strlen($regs[0]));\r
99                                 $head = substr( trim($this->getValue($head, array( "{" => true) )), 0, -1);\r
100                                 $paragraphs["functions"][] = array(\r
101                                                                                                                                                                                 "name"  => $regs[1],\r
102                                                                                                                                                                                 "doc"           => $this->extractPhpdoc( substr($phpcode, $start+3, ($end-$start)-2) ),\r
103                                                                                                                                                                                 "head"  => $head\r
104                                                                                                                                                                 );\r
105                                 $functions[$regs[1]] = true;                                                                                                                                                            \r
106                                                                                 \r
107                         } else if ( !isset($keywords["variables"]) && preg_match($this->PHP_COMPLEX["var"], $remaining, $regs)) {\r
108 \r
109                                 if ("=" == $regs[2]) \r
110                                         $value = trim($this->getValue( substr($remaining, strpos($remaining, $regs[0])+strlen($regs[0]) ), array( ";" => true)));\r
111                                 else\r
112                                         $value = "";                                    \r
113                                 \r
114                                 $paragraphs["variables"][] = array(\r
115                                                                                                                                                                                 "name"  => $regs[1],\r
116                                                                                                                                                                                 "value" => $value,\r
117                                                                                                                                                                                 "doc"           => $this->extractPhpdoc(substr($phpcode, $start+3, ($end-$start)-2))\r
118                                                                                                                                                                 );\r
119                                 $variables[$regs[1]] = true;\r
120                                 \r
121                         } else if ( !isset($keywords["consts"]) && preg_match($this->PHP_COMPLEX["const"], $remaining, $regs) ) {\r
122                         \r
123                                 $name = (""!=$regs[2]) ? substr($regs[1], 1, -1) : $regs[1];\r
124                                 \r
125                                 if (isset($regs[5])) {\r
126                                         if ($regs[5])\r
127                                                 $case = "case insensitive, userdefined: '$regs[5]'";\r
128                                         else\r
129                                                 $case = "case sensitive, userdefined: '$regs[5]'";\r
130                                 } else {\r
131                                         $case = "default: case sensitive";\r
132                                 }\r
133                                 \r
134                                 $paragraphs["consts"][] = array(\r
135                                                                                                                                                                         "name"  => $name,\r
136                                                                                                                                                                         "value" => (""!=$regs[4]) ? substr($regs[3], 1, -1) : $regs[3],\r
137                                                                                                                                                                         "case"  => $case,\r
138                                                                                                                                                                         "doc"           => $this->extractPhpdoc(substr($phpcode, $start+3, ($end-$start)-2))\r
139                                                                                                                                                 );\r
140                                 $constants[$name] = true;\r
141                                                                                                                                                                                 \r
142                         } else if ( !isset($keywords["uses"]) && preg_match($this->PHP_COMPLEX["use"], $remaining, $regs)) {\r
143 \r
144                                 $filename = isset($regs[5]) ? $regs[5] : $regs[4];\r
145                                 $paragraphs["uses"][] = array(\r
146                                                                                                                                                                 "type"  => $regs[1],\r
147                                                                                                                                                                 "file"  => $filename,\r
148                                                                                                                                                                 "doc"           => $this->extractPhpdoc(substr($phpcode, $start+3, ($end-$start)-2))\r
149                                                                                                                                                 );\r
150                                 $uses[$filename] = true;                                                                                                                                                \r
151                                 \r
152                         } \r
153                         \r
154                         $start++;\r
155                 } \r
156 \r
157                 //\r
158                 // Find undocumented elements\r
159                 //\r
160                 if (!isset($keywords["classes"])) {\r
161                 \r
162                         preg_match_all($this->PHP_COMPLEX["undoc_class"], $phpcode, $regs, PREG_SET_ORDER);\r
163                         reset($regs);\r
164                         while (list($k, $data)=each($regs))\r
165                                 if (!isset($classes[$data[1]]))\r
166                                         $paragraphs["classes"][] = array(\r
167                                                                                                                                                                                 "name"          => $data[1],\r
168                                                                                                                                                                                 "extends"       => "",\r
169                                                                                                                                                                                 "doc"                   => ""\r
170                                                                                                                                                                         );\r
171 \r
172                         preg_match_all($this->PHP_COMPLEX["undoc_class_extends"], $phpcode, $regs, PREG_SET_ORDER);\r
173                         reset($regs);\r
174                         while (list($k, $data)=each($regs))\r
175                                 if (!isset($classes[$data[1]]))\r
176                                         $paragraphs["classes"][] = array(\r
177                                                                                                                                                                                 "name"          => $data[1],\r
178                                                                                                                                                                                 "extends"       => $data[2],\r
179                                                                                                                                                                                 "doc"                   => ""\r
180                                                                                                                                                                 );                                                                                                                                                                      \r
181                                 \r
182                 }\r
183 \r
184                 if (!isset($keywords["functions"])) {\r
185                         \r
186                         preg_match_all($this->PHP_COMPLEX["undoc_function"], $phpcode, $regs, PREG_SET_ORDER);\r
187                         reset($regs);\r
188                         while (list($k, $data)=each($regs)) \r
189                                 if (!isset($functions[$data[1]])) {\r
190                                                                         \r
191                                         $head = substr($phpcode, strpos($phpcode, $data[0])+strlen($data[0]));\r
192                                         $head = substr( trim( $this->getValue($head, array( "{" => true) )), 0, -1);\r
193                                         $paragraphs["functions"][] = array(\r
194                                                                                                                                                                                 "name"  => $data[1],\r
195                                                                                                                                                                                 "doc"           => "",\r
196                                                                                                                                                                                 "head"  => $head\r
197                                                                                                                                                                 );\r
198                                 }\r
199                         \r
200                 }\r
201                 \r
202 \r
203                 if (!isset($keywords["variables"])) {\r
204 \r
205                         preg_match_all($this->PHP_COMPLEX["undoc_var"], $phpcode, $regs, PREG_SET_ORDER);\r
206                         reset($regs);\r
207                         while (list($k, $data)=each($regs)) \r
208                                 if (!isset($variables[$data[1]])) {\r
209                                         \r
210                                         if ("=" == $data[2])\r
211                                                 $value = trim($this->getValue( substr($phpcode, strpos($phpcode, $data[0])+strlen($data[0]) ), array( ";" => true)));\r
212                                 else \r
213                                                 $value = "";\r
214                                 \r
215                                         $paragraphs["variables"][] = array(\r
216                                                                                                                                                                                 "name"  => $data[1],\r
217                                                                                                                                                                                 "value" => $value,\r
218                                                                                                                                                                                 "doc"           => ""\r
219                                                                                                                                                                 );\r
220                         }                       \r
221                 }\r
222                 \r
223                 if (!isset($keywords["consts"])) {\r
224 \r
225                         preg_match_all($this->PHP_COMPLEX["undoc_const"], $phpcode, $regs, PREG_SET_ORDER);\r
226                         reset($regs);\r
227                         while (list($k, $data)=each($regs)) {\r
228                         \r
229                                 $name = (""!=$data[2]) ? substr($data[1], 1, -1) : $data[1];\r
230                                 if (!isset($constants[$name])) {\r
231                                         \r
232                                         if (isset($data[5])) {\r
233                                                 if ($data[5])\r
234                                                         $case = "case insensitive, userdefined: '$data[5]'";\r
235                                                 else\r
236                                                         $case = "case sensitive, userdefined: '$data[5]'";\r
237                                         } else {\r
238                                                 $case = "default: case sensitive";\r
239                                         }\r
240                                         \r
241                                         $paragraphs["consts"][] = array(\r
242                                                                                                                                                                         "name"  => $name,\r
243                                                                                                                                                                         "value" => (""!=$data[4]) ? substr($data[3], 1, -1) : $data[3],\r
244                                                                                                                                                                         "case"  => $case,\r
245                                                                                                                                                                         "doc"           => ""\r
246                                                                                                                                                         );\r
247                                 }\r
248                         }\r
249                 }\r
250                 \r
251                 if (!isset($keywords["uses"])) {\r
252 \r
253                         preg_match_all($this->PHP_COMPLEX["undoc_use"], $phpcode, $regs, PREG_SET_ORDER);\r
254 \r
255                         reset($regs);\r
256                         while (list($k, $data)=each($regs)) {\r
257                         \r
258                                 $filename = isset($data[5]) ? $data[5] : $data[4];\r
259                                 if (!isset($uses[$filename])) {\r
260                                         \r
261                                         $paragraphs["uses"][] = array(\r
262                                                                                                                                                                         "type"  => $data[1],\r
263                                                                                                                                                                         "file"  => $filename,\r
264                                                                                                                                                                         "doc"           => ""\r
265                                                                                                                                                                 );\r
266                                         \r
267                                 }\r
268                         }\r
269                         \r
270                 }\r
271 \r
272                 return $paragraphs;\r
273         }       // end func getPhpdocParagraphs\r
274         \r
275         /**\r
276         * Does a quick prescan to find modules an classes.\r
277         * @param        string  Code to scan\r
278         * @return       array           Hash of modules and classes found in the given code\r
279         * @access       public\r
280         * @see  getPhpdocParagraphs()\r
281         */\r
282         function getModulesAndClasses($phpcode) {\r
283                 \r
284                 $para = array();\r
285                 list( $para["modules"], $phpdcode) = $this->getModuleDoc($phpcode);\r
286                 $para["classes"] = $this->getClasses($phpcode);\r
287                 \r
288                 return $para;\r
289         } // end func getModulesAndClasses\r
290 \r
291         /**\r
292         * Tries to extract a module doc.\r
293         * \r
294         * The syntax for modules is not final yet. The implementation and meaning of "module" \r
295         * might change at every time! Please do not ask for implementation details.\r
296         *\r
297         * @param        string  PHP Code to scan\r
298         * @return       array   $module         $module[0] = array with module data, \r
299         *                                                                                                               $module[1] = php code without the leading module doc\r
300         */      \r
301         function getModuleDoc($phpcode) {\r
302                 \r
303                 $module = array();\r
304                 \r
305                 if (preg_match($this->C_COMPLEX["module_doc"], $phpcode, $regs) ) {\r
306                 \r
307                         $start                  = strlen($regs[0]);\r
308       $end                              = strpos($phpcode, "*/", $start);\r
309                         $remaining      = substr($phpcode, $end+2);\r
310                         $doc_comment= substr($phpcode, $start, $end-$start);\r
311                         \r
312                         // Do we have OO Code? If not, continue.\r
313                         if ( !preg_match($this->PHP_COMPLEX["class"], $remaining) && !preg_match($this->PHP_COMPLEX["class_extends"], $remaining) ) {\r
314 \r
315                                 // Is there a module tag?\r
316                                 if ( preg_match($this->C_COMPLEX["module_tags"], $doc_comment) ) {\r
317                                 \r
318                                         $doc_comment = $this->extractPhpDoc($doc_comment);\r
319                                         $tags = $this->getTags( $doc_comment);\r
320                                         $allowed = array (\r
321                                                                                                                         "module"        => true,\r
322                                                                                                                         "modulegroup"   => true\r
323                                                                                                                         \r
324                                                                                                         );\r
325                                         $tags = $this->analyseTags( $tags, array(), array( "module" => true, "modulegroup" => true) );\r
326                                         \r
327                                         $module = array (\r
328                                                                                                                 "doc"                   => $doc_comment,\r
329                                                                                                                 "status"        => "ok",\r
330                                                                                                                 "name"          => (isset($tags["module"])) ? $tags["module"] : "",\r
331                                                                                                                 "group"         => (isset($tags["modulegroup"])) ? $tags["modulegroup"] : ""\r
332                                                                                                         );\r
333                                 \r
334                                 } else {\r
335                         \r
336                                         // No module tag. \r
337                                         // Try the remaining keywords. If one matches it's not a module doc \r
338                                         // assume that the module doc is missing. If none matches assume that\r
339                                         // it's a module doc which lacks the module tags.\r
340                                         if (    preg_match($this->PHP_COMPLEX["function"], $remaining) ||\r
341                                                                 preg_match($this->PHP_COMPLEX["use"], $remaining) ||\r
342                                                                 preg_match($this->PHP_COMPLEX["const"], $remaining) ||\r
343                                                                 preg_match($this->PHP_COMPLEX["var"], $remaining) \r
344                                                         ) {\r
345 \r
346                                                         $module = array(\r
347                                                                                                                         "doc"                   => "",\r
348                                                                                                                         "status"        => "missing",\r
349                                                                                                                         "name"          => "",\r
350                                                                                                                         "group"         => ""\r
351                                                                                                         );      \r
352                                                         $remaining = $phpcode;\r
353                                                         \r
354                                         } else {\r
355 \r
356                                                 $module = array (\r
357                                                                                                                                 "doc"                   => $doc_comment,\r
358                                                                                                                                 "status"        => "tags missing",\r
359                                                                                                                                 "name"          => "",\r
360                                                                                                                                 "group"         => ""\r
361                                                                                                                         );      \r
362                                                 \r
363                                         }\r
364                                         \r
365                                 } // end if module_tags\r
366                                 \r
367                         } else {\r
368                                 \r
369                                 $remaining = $phpcode;\r
370                                 \r
371                         } // end if class\r
372                                                         \r
373                 } else {\r
374                         \r
375                         $remaining = $phpcode;\r
376                                         \r
377                 }\r
378                 \r
379                 return array($module, $remaining);\r
380         } // end func getModuleDoc\r
381         \r
382         /**\r
383         * Returns a list of classes found in the given code.\r
384         *\r
385         * In early versions PHPdoc parsed all the code at once which restulted in huge\r
386         * memory intensive hashes. Now it scans for classes, builds a classtree and \r
387         * does the parsing step by step, writing information to the destination \r
388         * (renderer, exporter) as soon as possible. This reduces the memory consumption \r
389         * dramatically. getPhpdocParagraphs() could be used to extract the class definitions\r
390         * as well but this specialized function is somewhat faster.\r
391         *\r
392         * @param        string  PHP code to scan.\r
393         * @return       array           $classes        Array of classes found in the code. $classes[classname] = extends\r
394         */\r
395         function getClasses($phpcode) {\r
396                 \r
397                 $classes = array();\r
398                 \r
399                 preg_match_all($this->PHP_COMPLEX["undoc_class"], $phpcode, $regs, PREG_SET_ORDER);\r
400                 reset($regs);\r
401                 while (list($k, $data)=each($regs))\r
402                         $classes[] = array(\r
403                                                                                                         "name"          => $data[1],\r
404                                                                                                         "extends" => ""\r
405                                                                                                 );\r
406                 \r
407                 preg_match_all($this->PHP_COMPLEX["undoc_class_extends"], $phpcode, $regs, PREG_SET_ORDER);\r
408                 reset($regs);\r
409                 while (list($k, $data)=each($regs)) \r
410                         $classes[] = array(\r
411                                                                                                         "name"          => $data[1],\r
412                                                                                                         "extends"       => $data[2]\r
413                                                                                                 );\r
414                 \r
415                 return $classes;\r
416         } // end func getClasses\r
417         \r
418         /**\r
419         * Strips "/xx", "x/" and x from doc comments (x means asterix).\r
420         * @param        string  Doc comment to clean up.\r
421         * @return       string  $phpdoc\r
422         */\r
423         function extractPhpdoc($paragraph) {\r
424 \r
425                 $lines = split( $this->PHP_BASE["break"], $paragraph);\r
426                 $phpdoc = "";\r
427 \r
428                 reset($lines);\r
429                 while (list($k, $line)=each($lines)) {\r
430                 \r
431                         $line = trim($line);\r
432                         if (""==$line)\r
433                                 continue;\r
434                                 \r
435                         if ("*" == $line[0])\r
436                                 $phpdoc.= trim(substr($line, 1))."\n";\r
437                         else \r
438                                 $phpdoc.= $line."\n";\r
439                                 \r
440                 }\r
441                 \r
442                 return substr($phpdoc, 0, -1);\r
443         } // end func extractPhpdoc\r
444         \r
445         /**\r
446         * Extract the description from a PHPDoc doc comment.\r
447         *\r
448         * Every PHPDoc doc comment has the same syntax: /xx[break][x]short description\r
449         * [break][[x]multiple line long description[break]][[x]@list of tags[. This function\r
450         * returns an array of the short description and long description.\r
451         *\r
452         * @param        string  Doc comment to examine.\r
453         * @return       array           $description    $description[0] = short description (first line),\r
454         *                                                                                                                       $description[1] = long description (second line upto the first tag)\r
455         */\r
456         function getDescription($phpdoc) {\r
457         \r
458                 // find the position of the first doc tag\r
459                 $positions = $this->getTagPos($phpdoc);\r
460 \r
461                 if (0 == count($positions))\r
462                         $desc = trim($phpdoc); // no doc tags\r
463                 else\r
464                         $desc = trim(substr($phpdoc, 0, $positions[0]["pos"])); // strip tags\r
465 \r
466                 $lines = split($this->PHP_BASE["break"], $desc);\r
467                         \r
468                 if (1 == count($lines) || "" == $desc) {\r
469                 \r
470                         // only a short description but no long description - or even none of both\r
471                         $description = array ($desc, "");\r
472                 \r
473                 } else {\r
474                 \r
475                         $sdesc = trim($lines[0]);\r
476                         unset($lines[0]);\r
477                         \r
478                         $description = array ( $sdesc, implode("", $lines)      );\r
479                         \r
480                 }\r
481         \r
482                 return $description;\r
483         } // end func getDescription\r
484         \r
485         /**\r
486         * Scans a code passage for a value.\r
487         *\r
488         * There some cases where you can hardly use a regex to grep a value\r
489         * because the value might contain unescaped charaters that end the value.\r
490         * Value means something like "array ( ";", '\;' );" or "'phpdoc; ';" where\r
491         * the delimiter would be ";".\r
492         *\r
493         * @param        string  The php code to examine.\r
494         * @param        mixed           String of one delimiter or array of delimiters.\r
495         * @return       string  Value found in the code\r
496         * @todo         Racecondition: comments\r
497         */\r
498         function getValue($code, $delimiter) {\r
499                 if (""==$code)\r
500                         return "";\r
501         \r
502                 if (!is_array($delimiter)) \r
503                         $delimiter = array( $delimiter => true );\r
504                         \r
505                 $code                           = trim($code);\r
506                 $len                                    = strlen($code);\r
507                 $enclosed               = false;\r
508                 $enclosed_by    = "";\r
509                 \r
510                 if ( isset($delimiter[$code[0]]) ) {\r
511                 \r
512                         $i = 1;\r
513                         \r
514                 } else {\r
515                 \r
516                         for ($i=0; $i<$len; $i++) {\r
517                         \r
518                                 $char = $code[$i];\r
519 \r
520                                 if (('"'==$char || "'"==$char) && ($char == $enclosed_by || ""==$enclosed_by) && (0==$i || ($i>0 && "\\"!=$code[$i-1]))) {\r
521                                 \r
522                                         if (!$enclosed)\r
523                                                 $enclosed_by = $char;\r
524                                         else \r
525                                                 $enclosed_by = "";\r
526                                                 \r
527                                         $enclosed = !$enclosed;\r
528                                         \r
529                                 }\r
530                                 if (!$enclosed && isset($delimiter[$char]))\r
531                                         break;                                  \r
532                                         \r
533                         }\r
534                 \r
535                 }\r
536   \r
537                 return substr($code, 0, $i);\r
538         } // end func getValue\r
539         \r
540         /**\r
541         * Analyses a code snipped and returns the type and value of the first variable found.\r
542         *\r
543         * With version 0.3 PHPDoc tries to analyse variable declarations to find \r
544         * type and value. This is used to analyse class variable declarations and \r
545         * optional function arguments.\r
546         * \r
547         * Note that all regular expressions in this function start with "^". That means\r
548         * you have to do some preparations to the code snippet you're passing to this\r
549         * function.\r
550         *\r
551         * @param        string  PHP code to analyse\r
552         * @param        boolean Flag indicating the "type" of code to analyse. Optional \r
553         *                                                               function parameters and class variables have a slightly \r
554         *                                                               different syntax for arrays. By default function parameters\r
555                                                                                 are expected.\r
556         * @return array         $vartype $vartype[0] = type, $vartype[1] = value, $vartype[2] = raw value\r
557         */\r
558         function getVariableTypeAndValue($code, $flag_args = true) {\r
559         \r
560                 $type                   = "unknown";\r
561                 $value                  = "unknown";\r
562                 $raw_value      = $code;\r
563 \r
564                 //\r
565                 // Do not change the order the function tries to find out the type.\r
566                 //\r
567                 \r
568                 if (preg_match( $this->PHP_COMPLEX["type_boolean"], $code, $regs)) {\r
569 \r
570                         $type                                   =       "boolean";\r
571                         $raw_value              = $regs[0];\r
572                         $value                          = $regs[0];\r
573         \r
574                 } else if (preg_match( $this->PHP_COMPLEX["type_string_enclosed"], $code, $regs)) {\r
575 \r
576                         $type                           = "string";\r
577                         $raw_value              = $regs[0];\r
578                         $value                          = $regs[0];\r
579                         \r
580                 }       else if (preg_match( $this->PHP_COMPLEX["type_int_oct"], $code, $regs)) {\r
581         \r
582                         $type                           = "integer (octal)";\r
583                         $raw_value              = $regs[0];\r
584                         $value                          = preg_replace("@\s@", "", $regs[0]);\r
585                         if ( (int)$value != $value )\r
586                                 $type.= " [warning: out of integer range, possible overflow trouble]";\r
587                         $value                          = octdec($value)." ($value)";\r
588                         \r
589         \r
590                 } else if (preg_match( $this->PHP_COMPLEX["type_int_hex"], $code, $regs)) {\r
591 \r
592                         $type                                   = "integer (hexadecimal)";\r
593                         $raw_value              = $regs[0];\r
594                         $value                          = preg_replace("@\s@", "", $regs[0]);\r
595                         if ( (int)$value != $value ) \r
596                                 $type.= " [warning: out of integer range, possible overflow trouble]";\r
597                         $value                          = hexdec($value)." ($value)";\r
598 \r
599                 } else if (preg_match( $this->PHP_COMPLEX["type_float_exponent"], $code, $regs)) {\r
600                 \r
601                         $type                           = "float";\r
602                         $raw_value              = $regs[0];\r
603                         $value                          = (string)preg_replace("@\s@", "", $regs[0]);\r
604                         if ( (float)$value != $value ) \r
605                                 $type.= " [warning: out of float range]";\r
606                         $value                          = (float)$value;\r
607         \r
608                 } else if (preg_match( $this->PHP_COMPLEX["type_float"], $code, $regs)) {\r
609 \r
610                         $type                                   = "float";\r
611                         $raw_value              = $regs[0];\r
612                         $value                          = preg_replace("@\s@", "", $regs[0]);\r
613                         if ( (float)$value != $value ) \r
614                                 $type.= " [warning: out of float range]";\r
615                         $value = (float)$value;\r
616         \r
617                 } else if (preg_match( $this->PHP_COMPLEX["type_number"], $code, $regs)) {\r
618         \r
619                         $value                          = preg_replace("@\s@", "", $regs[0]);\r
620                         $raw_value              = $regs[0];\r
621                         \r
622                         if ( (int)$value == $value ) {\r
623 \r
624                                 $type   = "integer";\r
625                                 $value = (int)$value;\r
626 \r
627                         } else {\r
628 \r
629                                 $type = "float";\r
630                                 if ( (float)$value != $value )\r
631                                         $type.=" [warning: out of float range]";\r
632                                 $value = (float)$value;\r
633 \r
634                         }\r
635         \r
636                 } else if ($flag_args && preg_match( $this->PHP_COMPLEX["type_empty_array"], $code, $regs)) {\r
637                         \r
638                         $value                  = "array()";\r
639                         $raw_value      = $regs[0];\r
640                         $type                   = "array";\r
641                         \r
642                 } else if (!$flag_args && preg_match( $this->PHP_COMPLEX["type_array"], $code, $regs)) {\r
643                 \r
644                         $value = $this->getValue( $code, array(";" => true));\r
645                         // strpos() is twice as fast as substr()\r
646                         if ( 0 == strpos($value, "array")) \r
647                                 $type = "array";\r
648                         $raw_value == $value;\r
649                 \r
650                 } else if (preg_match( $this->PHP_COMPLEX["type_string"], $code, $regs)) {\r
651 \r
652                         $type                                   = "string";\r
653                         $raw_value              = $regs[0];\r
654                         $value                          = $regs[0];\r
655                 } \r
656 \r
657                 return array($type, $value, $raw_value);\r
658         } // end func getVariableTypeAndValue\r
659         \r
660 } // end class PhpdocParserObject\r
661 ?>