#!/usr/bin/php -q
<?php

// a quick and dirty tool

require_once 'Console/Getopt.php';

function 
printUsage() {
?>Usage: ./scanrefret.php [OPTION]...
  -d  --dir=NAME          specify a test case directory to run
  -h, --help              display this help and exit
<?php
}

function 
scanFiles($directory) {
    
$retCount 0;
    
$dh opendir($directory);
    if (! 
is_resource($dh)) {
        
trigger_error("Couldn't open {$directory}"E_USER_ERROR);
    }
    while (
$file readdir($dh)) {
        if (
$file == '.' || $file == '..') {
            continue;
        }
        
$file_path $directory DIRECTORY_SEPARATOR $file;
        if (
is_dir($file_path)) {
            
$retCount += scanFiles($file_path);
        } else if (
strcasecmp(substr($file_path, -44), '.php') != 0) {
            continue;
        } else {
            
$originalFile file_get_contents($file_path);
            if (
preg_match_all(
                
'/function\s+&([a-zA-Z_][a-zA-Z0-9]*).+?{.+?}(?=[^{}]*(function|\Z))/sm'
                
$originalFile,
                
$funcmatches,
                
PREG_SET_ORDER PREG_OFFSET_CAPTURE)) {

                
$isFileShown FALSE;

                foreach(
$funcmatches as $funcmatch) {
                    
$originalFunction $funcmatch[0][0];
                    
                    
// need multiline?
                    
if (preg_match_all(
                        
'/(\s+)(return((\s*|[^a-z0-9A-Z_]).+?);)/',
                        
$originalFunction,
                        
$retmatches,
                        
PREG_SET_ORDER PREG_OFFSET_CAPTURE)) {

                        foreach(
$retmatches as $retmatch) {
                            if (
preg_match('/^\s*\$[a-z0-9A-Z_]+\s*$/'$retmatch[3][0])) {
                                continue;
                            }

                            if (
preg_match('/^\s*\$[a-z0-9A-Z_]+\s*->\s*[a-z0-9A-Z_]+\s*$/'$retmatch[3][0])) {
                                continue;
                            }

                            if (!
$isFileShown) {
                                
$isFileShown TRUE;
                                echo 
"\n$file_path:\n";
                            }

                            
$offset $funcmatch[0][1] + $retmatch[0][1];
                            
$line substr_count(substr($originalFile0$offset), "\n") + 
                                
substr_count($retmatch[1][0], "\n");
                            echo 
"{$line}:{$funcmatch[2][0]}:    {$retmatch[2][0]}\n";
                            
$retCount++;
                        }
                    }
                }
            }
        } 
    }
    
closedir($dh);
    return 
$retCount;
}

function 
start() {
    
$argv Console_Getopt::readPHPArgv();
    if (
PEAR::isError($argv)) {
        die(
'Fatal Error: ' $argv->getMessage()) . "\n";
    }

    
$short_opts 'd:h';
    
$long_opts  = array('dir=''help');
    
$options Console_Getopt::getopt($argv$short_opts$long_opts);
    if (
PEAR::isError($options)) {
        
printUsage();
        exit(
0);            
    }

    
$isUpdate FALSE;
    
$directory NULL;
    foreach (
$options[0] as $option) {
        switch (
$option[0]) {
            case 
'h':
            case 
'--help':
                
printUsage();
                exit(
0);
                break;
            case 
'd':
            case 
'--dir':
                
$directory realpath($option[1]);
                break;
        }

    }
    
    if (
$directory) {
        
$retCount scanFiles($directory);
        echo 
"Suspicious return statements: "$retCount"\n";
 } else {
        
printUsage();
    }

}
    
start();

?>