1356 {
1357 if (!function_exists("token_get_all")) {
1358 return false;
1359 }
1360 if (!defined('T_DOC_COMMENT')) {
1361 define('T_DOC_COMMENT', T_COMMENT);
1362 }
1363 if (!defined('T_INTERFACE')) {
1364 define('T_INTERFACE', -1);
1365 }
1366 if (!defined('T_IMPLEMENTS')) {
1367 define('T_IMPLEMENTS', -1);
1368 }
1369 if (!$fp = @fopen($file, "r")) {
1370 return false;
1371 }
1372 fclose($fp);
1373 $contents = file_get_contents($file);
1374 $tokens = token_get_all($contents);
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386 $look_for = 0;
1387 $paren_level = 0;
1388 $bracket_level = 0;
1389 $brace_level = 0;
1390 $lastphpdoc = '';
1391 $current_class = '';
1392 $current_interface = '';
1393 $current_class_level = -1;
1394 $current_function = '';
1395 $current_function_level = -1;
1396 $declared_classes = array();
1397 $declared_interfaces = array();
1398 $declared_functions = array();
1399 $declared_methods = array();
1400 $used_classes = array();
1401 $used_functions = array();
1402 $extends = array();
1403 $implements = array();
1404 $nodeps = array();
1405 $inquote = false;
1406 $interface = false;
1407 for ($i = 0; $i < sizeof($tokens); $i++) {
1408 if (is_array($tokens[$i])) {
1409 list($token, $data) = $tokens[$i];
1410 } else {
1411 $token = $tokens[$i];
1412 $data = '';
1413 }
1414 if ($inquote) {
1415 if ($token != '"' && $token != T_END_HEREDOC) {
1416 continue;
1417 } else {
1418 $inquote = false;
1419 continue;
1420 }
1421 }
1422 switch ($token) {
1423 case T_WHITESPACE:
1424 break;
1425 case ';':
1426 if ($interface) {
1427 $current_function = '';
1428 $current_function_level = -1;
1429 }
1430 break;
1431 case '"':
1432 case T_START_HEREDOC:
1433 $inquote = true;
1434 break;
1435 case T_CURLY_OPEN:
1436 case T_DOLLAR_OPEN_CURLY_BRACES:
1437 case '{': $brace_level++; continue 2;
1438 case '}':
1439 $brace_level--;
1440 if ($current_class_level == $brace_level) {
1441 $current_class = '';
1442 $current_class_level = -1;
1443 }
1444 if ($current_function_level == $brace_level) {
1445 $current_function = '';
1446 $current_function_level = -1;
1447 }
1448 continue 2;
1449 case '[': $bracket_level++; continue 2;
1450 case ']': $bracket_level--; continue 2;
1451 case '(': $paren_level++; continue 2;
1452 case ')': $paren_level--; continue 2;
1453 case T_INTERFACE:
1454 $interface = true;
1455 case T_CLASS:
1456 if (($current_class_level != -1) || ($current_function_level != -1)) {
1458 array('file' => $file));
1459 return false;
1460 }
1461 case T_FUNCTION:
1462 case T_NEW:
1463 case T_EXTENDS:
1464 case T_IMPLEMENTS:
1465 $look_for = $token;
1466 continue 2;
1467 case T_STRING:
1468 if ($look_for == T_CLASS) {
1469 $current_class = $data;
1470 $current_class_level = $brace_level;
1471 $declared_classes[] = $current_class;
1472 } elseif ($look_for == T_INTERFACE) {
1473 $current_interface = $data;
1474 $current_class_level = $brace_level;
1475 $declared_interfaces[] = $current_interface;
1476 } elseif ($look_for == T_IMPLEMENTS) {
1477 $implements[$current_class] = $data;
1478 } elseif ($look_for == T_EXTENDS) {
1479 $extends[$current_class] = $data;
1480 } elseif ($look_for == T_FUNCTION) {
1481 if ($current_class) {
1482 $current_function = "$current_class::$data";
1483 $declared_methods[$current_class][] = $data;
1484 } elseif ($current_interface) {
1485 $current_function = "$current_interface::$data";
1486 $declared_methods[$current_interface][] = $data;
1487 } else {
1488 $current_function = $data;
1489 $declared_functions[] = $current_function;
1490 }
1491 $current_function_level = $brace_level;
1492 $m = array();
1493 } elseif ($look_for == T_NEW) {
1494 $used_classes[$data] = true;
1495 }
1496 $look_for = 0;
1497 continue 2;
1498 case T_VARIABLE:
1499 $look_for = 0;
1500 continue 2;
1501 case T_DOC_COMMENT:
1502 case T_COMMENT:
1503 if (preg_match('!^/\*\*\s!', $data)) {
1504 $lastphpdoc = $data;
1505 if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
1506 $nodeps = array_merge($nodeps, $m[1]);
1507 }
1508 }
1509 continue 2;
1510 case T_DOUBLE_COLON:
1511 if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
1513 array('file' => $file));
1514 return false;
1515 }
1516 $class = $tokens[$i - 1][1];
1517 if (strtolower($class) != 'parent') {
1518 $used_classes[$class] = true;
1519 }
1520 continue 2;
1521 }
1522 }
1523 return array(
1524 "source_file" => $file,
1525 "declared_classes" => $declared_classes,
1526 "declared_interfaces" => $declared_interfaces,
1527 "declared_methods" => $declared_methods,
1528 "declared_functions" => $declared_functions,
1529 "used_classes" => array_diff(array_keys($used_classes), $nodeps),
1530 "inheritance" => $extends,
1531 "implements" => $implements,
1532 );
1533 }
const PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE