git-svn-id: svn://svn.lighttpd.net/xcache/trunk@33 c26eb9a1-5813-0410-bd6c-c2e55f420ca71.1
parent
6df60fffb6
commit
791ec85409
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
// should be named as config.php
|
||||
|
||||
$charset = "UTF-8";
|
||||
// $include_paths = array("/www/my-php-project/");
|
||||
// $exclude_paths = array("/www/my-php-project/tmp/");
|
||||
$syntaxhiglight = true;
|
||||
$usecache = false;
|
||||
//// $datadir is default to ini_get("xcache.coveragedump_directory")
|
||||
// $datadir = '';
|
||||
|
||||
function ob_filter_path_nicer($o)
|
||||
{
|
||||
$o = str_replace("/home/", "{H}/", $o);
|
||||
return $o;
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,57 @@
|
||||
input, table { font-family: monospace; font-size: 11px; }
|
||||
table.cycles { border: 1px solid black; background: white; margin-top: 5px; margin-bottom: 5px; }
|
||||
table.cycles .col1 { background-color: #f5f5f5; }
|
||||
table.cycles .col2 { background-color: #e0e0e0; }
|
||||
table.cycles th { background-color: #707090; color: white; font-weight: bold; height: 20px; line-height: 16px; font-family: serif; }
|
||||
th a { color: white; font-weight: bold; display: block; width: 100%; height: 100%; }
|
||||
|
||||
.coverFile {
|
||||
text-align: left;
|
||||
color: gray;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.coverBar {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.coverBarOutline {
|
||||
border: 1px solid black;
|
||||
background-color: #ffffff;
|
||||
width: 100px;
|
||||
font-size: 11px; line-height: 11px;
|
||||
font-family: tahoma;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.coverPerHi, .coverPerMed, .coverPerLo {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
left: 0px; top: 2px;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
.coverBarHi, .coverBarMed, .coverBarLo { left: 1px; top: 1px; }
|
||||
.coverBarHi { background-color: #A7FC9D; }
|
||||
.coverBarMed { background-color: #FFEA20; }
|
||||
.coverBarLo { background-color: #FF0000; }
|
||||
|
||||
|
||||
.coverNumHi, .coverNumMed, .coverNumLo {
|
||||
text-align: right;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.coverNumHi { /*background-color: #A7FC9D;*/ }
|
||||
.coverNumMed { /*background-color: #FFEA20;*/ }
|
||||
.coverNumLo { background-color: #FF0000; }
|
||||
|
||||
.lineCov { background-color: #F0F0F0; }
|
||||
.lineNoCov { background-color: #ffe0e0; }
|
||||
pre.code {
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
border: 1px solid gray;
|
||||
}
|
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
error_reporting(E_ALL);
|
||||
define('REQUEST_TIME', time());
|
||||
|
||||
class Cycle
|
||||
{
|
||||
var $values;
|
||||
var $i;
|
||||
var $count;
|
||||
|
||||
function Cycle($v)
|
||||
{
|
||||
$this->values = func_get_args();
|
||||
$this->i = -1;
|
||||
$this->count = count($this->values);
|
||||
}
|
||||
|
||||
function next()
|
||||
{
|
||||
$this->i = ($this->i + 1) % $this->count;
|
||||
return $this->values[$this->i];
|
||||
}
|
||||
|
||||
function cur()
|
||||
{
|
||||
return $this->values[$this->i];
|
||||
}
|
||||
|
||||
function reset()
|
||||
{
|
||||
$this->i = -1;
|
||||
}
|
||||
}
|
||||
|
||||
class XcacheCoverageViewer
|
||||
{
|
||||
var $syntaxhiglight = true;
|
||||
var $usecache = false;
|
||||
var $include_paths = array();
|
||||
var $exclude_paths = array();
|
||||
var $charset = 'UTF-8';
|
||||
|
||||
function XcacheCoverageViewer()
|
||||
{
|
||||
$this->datadir = ini_get('xcache.coveragedump_directory');
|
||||
|
||||
// copy config
|
||||
foreach (array('charset', 'include_paths', 'exclude_paths', 'syntaxhiglight', 'usecache', 'datadir') as $k) {
|
||||
if (isset($GLOBALS['usecache'])) {
|
||||
$this->{$k} = $GLOBALS['usecache'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->datadir = preg_replace('!/$!', '', $this->datadir);
|
||||
$this->datadir_len = strlen($this->datadir);
|
||||
|
||||
$this->path = isset($_GET['path']) ? $_GET['path'] : '';
|
||||
$this->path = preg_replace('!\.{2,}!', '.', $this->path);
|
||||
$this->path = preg_replace('![\\\\/]{2,}!', '/', $this->path);
|
||||
if ($this->path == '/') {
|
||||
$this->path = '';
|
||||
}
|
||||
$this->outpath = $this->datadir . $this->path;
|
||||
}
|
||||
|
||||
function main()
|
||||
{
|
||||
$path = $this->path;
|
||||
|
||||
if (is_dir($this->outpath)) {
|
||||
$action = 'dir';
|
||||
$prefix_len = strlen($path) + 1;
|
||||
$dirinfo = $this->loadDir($this->outpath);
|
||||
if (!$this->usecache) {
|
||||
ksort($dirinfo['subdirs']);
|
||||
ksort($dirinfo['files']);
|
||||
}
|
||||
}
|
||||
else if (is_file($this->outpath . ".pcov")) {
|
||||
$action = 'file';
|
||||
|
||||
$dir = dirname($path);
|
||||
$filename = basename($path);
|
||||
|
||||
$fileinfo = $this->loadCov($this->outpath . ".pcov");
|
||||
|
||||
$lines = file($path);
|
||||
// fix the tabs not in the middle
|
||||
foreach ($lines as $l => $line) {
|
||||
if (preg_match('!^(\\t*)([^\\t]+\\t.*)$!s', $line, $m)) {
|
||||
$lines[$l] = $m[1];
|
||||
$chunks = explode("\t", $m[2]);
|
||||
for ($i = 0, $c = count($chunks) - 1; $i < $c; $i ++) {
|
||||
$lines[$l] .= $chunks[$i] . str_repeat(" ", 4 - (strlen($chunks[$i]) % 4));
|
||||
}
|
||||
$lines[$l] .= $chunks[$c];
|
||||
}
|
||||
}
|
||||
if ($this->syntaxhiglight) {
|
||||
$source = implode('', $lines);
|
||||
ob_start();
|
||||
highlight_string($source);
|
||||
$lines = explode('<br />', str_replace("\n", "", ob_get_clean()));
|
||||
$last = array_pop($lines);
|
||||
$filecov = sprint_cov($fileinfo['cov'], $lines, false);
|
||||
$filecov .= $last;
|
||||
unset($source);
|
||||
}
|
||||
else {
|
||||
$filecov = sprint_cov($fileinfo['cov'], $lines);
|
||||
}
|
||||
|
||||
list($tplfile, $tpllines, $tplcov) = $this->loadTplCov($fileinfo['cov'], substr($this->outpath, $this->datadir_len));
|
||||
if ($tplfile) {
|
||||
$tplcov = sprint_cov($tplinfo['tplcov'], $tpllines);
|
||||
unset($tpllines);
|
||||
}
|
||||
}
|
||||
else if (!$this->datadir) {
|
||||
$action = 'require xcache.coveragedump_directory';
|
||||
}
|
||||
else {
|
||||
$action = "no data";
|
||||
}
|
||||
|
||||
include("coverager.tpl.php");
|
||||
}
|
||||
|
||||
function loadDir($outdir, $addtodo = null)
|
||||
{
|
||||
if ($this->usecache) {
|
||||
$cachefile = $outdir . "/.pcovcache";
|
||||
if (file_exists($cachefile)) {
|
||||
return unserialize(file_get_contents($cachefile));
|
||||
}
|
||||
}
|
||||
$srcdir = substr($outdir, $this->datadir_len);
|
||||
|
||||
$total = $hits = $todos = 0;
|
||||
$files = array();
|
||||
$subdirs = array();
|
||||
if (!isset($addtodo)) {
|
||||
if ($this->include_paths) {
|
||||
foreach ($this->include_paths as $p) {
|
||||
if (strncmp($p, $srcdir, strlen($p)) == 0) {
|
||||
$addtodo = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($addtodo) {
|
||||
if ($this->exclude_paths) {
|
||||
foreach ($this->exclude_paths as $p) {
|
||||
if (strncmp($p, $srcdir, strlen($p)) == 0) {
|
||||
$addtodo = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (glob($outdir . "/*") as $outfile) {
|
||||
if (is_dir($outfile)) {
|
||||
$info = $this->loadDir($outfile, $addtodo);
|
||||
$srcfile = substr($outfile, $this->datadir_len);
|
||||
$subdirs += $info['subdirs'];
|
||||
$total += $info['total'];
|
||||
$hits += $info['hits'];
|
||||
$todos += $info['todos'];
|
||||
unset($info['subdirs']);
|
||||
$subdirs[$srcfile] = $info;
|
||||
}
|
||||
else if (substr($outfile, -5) == ".pcov") {
|
||||
// pass
|
||||
$info = $this->loadFile($outfile);
|
||||
$total += $info['total'];
|
||||
$hits += $info['hits'];
|
||||
$srcfile = substr($outfile, $this->datadir_len, -5);
|
||||
$files[$srcfile] = $info;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ($addtodo === true) {
|
||||
foreach (glob($srcdir . "/*") as $srcfile) {
|
||||
if (!isset($files[$srcfile]) && is_file($srcfile)) {
|
||||
$files[$srcfile] = array('total' => 0, 'hits' => 0);
|
||||
$todos ++;
|
||||
}
|
||||
else if (!isset($subdirs[$srcfile]) && is_dir($srcfile)) {
|
||||
$subdirs[$srcfile] = array('total' => 0, 'hits' => 0, 'todos' => 1, 'files' => 0, 'subdirs' => array());
|
||||
$todos ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->usecache) {
|
||||
ksort($subdirs);
|
||||
ksort($files);
|
||||
}
|
||||
|
||||
$info = array(
|
||||
'total' => $total,
|
||||
'hits' => $hits,
|
||||
'todos' => $todos,
|
||||
'files' => $files,
|
||||
'subdirs' => $subdirs,
|
||||
);
|
||||
|
||||
if ($this->usecache) {
|
||||
$fp = fopen($cachefile, "wb");
|
||||
fwrite($fp, serialize($info));
|
||||
fclose($fp);
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
function loadFile($file)
|
||||
{
|
||||
if ($this->usecache) {
|
||||
$cachefile = $file . "cache";
|
||||
if (file_exists($cachefile)) {
|
||||
return unserialize(file_get_contents($cachefile));
|
||||
}
|
||||
}
|
||||
|
||||
$info = $this->loadCov($file); //, $lines);
|
||||
unset($info['cov']);
|
||||
|
||||
if ($this->usecache) {
|
||||
$fp = fopen($cachefile, "wb");
|
||||
fwrite($fp, serialize($info));
|
||||
fclose($fp);
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
function loadCov($file)//, $lines)
|
||||
{
|
||||
$total = $hits = 0;
|
||||
|
||||
$cov = xcache_coverager_decode(file_get_contents($file));
|
||||
|
||||
return array('total' => count($cov) - 1, 'hits' => $cov[0], 'cov' => $cov);
|
||||
}
|
||||
|
||||
function loadTplCov($cov, $ctpl)
|
||||
{
|
||||
$tplinfofile = $ctpl . '.phpinfo';
|
||||
|
||||
if (!file_exists($tplinfofile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tplinfo = unserialize(file_get_contents($tplinfofile));
|
||||
|
||||
if (!isset($tplinfo['sourceFile'])) {
|
||||
return;
|
||||
}
|
||||
$tplfile = $tplinfo['sourceFile'];
|
||||
if (!isset($tplinfo['lineMap']) || !count($tplinfo['lineMap'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tpllines = file($tplfile);
|
||||
|
||||
$dline = 0;
|
||||
$sline = 0;
|
||||
$tplcov = array();
|
||||
foreach ($cov as $line => $times) {
|
||||
// find nearest line
|
||||
while ($dline < $line) {
|
||||
if ((list($dline, $sline) = each($tplinfo['lineMap'])) === false) {
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
|
||||
$tplcov[$sline] = $times;
|
||||
}
|
||||
return array($tplfile, $tpllines, $tplcov);
|
||||
}
|
||||
}
|
||||
|
||||
function sprint_cov($cov, $lines, $encode = true)
|
||||
{
|
||||
foreach ($lines as $l => $line) {
|
||||
$offs = $l + 1;
|
||||
if ($encode) {
|
||||
$line = str_replace("\n", "", htmlspecialchars($line));
|
||||
}
|
||||
if (isset($cov[$offs])) {
|
||||
$lines[$l] = sprintf("<li class=\"line%sCov\"> %s\t%s</li>\n"
|
||||
, $cov[$offs] ? '' : 'No'
|
||||
, $cov[$offs]
|
||||
, $line);
|
||||
}
|
||||
else {
|
||||
$lines[$l] = "<li>\t$line</li>\n";
|
||||
}
|
||||
}
|
||||
return implode('', $lines);
|
||||
}
|
||||
|
||||
if (file_exists("config.php")) {
|
||||
include("config.php");
|
||||
}
|
||||
|
||||
$app = new XcacheCoverageViewer();
|
||||
$app->main();
|
||||
|
||||
?>
|
@ -0,0 +1,212 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us" />
|
||||
<?php
|
||||
echo <<<HEAD
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=$this->charset" />
|
||||
<script type="text/javascript" src="tablesort.js" charset="$this->charset"></script>
|
||||
HEAD;
|
||||
?>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="coverager.css" />
|
||||
<title>XCache Coverage Viewer</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?php
|
||||
function calc_percent($info, &$percent, &$class)
|
||||
{
|
||||
if (!$info['total']) {
|
||||
$percent = 0;
|
||||
}
|
||||
else {
|
||||
$percent = (int) ($info['hits'] / $info['total'] * 100);
|
||||
}
|
||||
if ($percent < 15) {
|
||||
$class = "Lo";
|
||||
}
|
||||
else if ($percent < 50) {
|
||||
$class = "Med";
|
||||
}
|
||||
else {
|
||||
$class = "Hi";
|
||||
}
|
||||
}
|
||||
|
||||
function bar($percent, $class)
|
||||
{
|
||||
return <<<EOS
|
||||
<div class="coverBarOutline">
|
||||
<div class="coverBar{$class}" style="width:{$percent}%"></div>
|
||||
<div class="coverPer{$class}">{$percent}</div>
|
||||
</div>
|
||||
EOS;
|
||||
}
|
||||
|
||||
function dir_head()
|
||||
{
|
||||
global $cycle;
|
||||
$cycle = new Cycle('class="col1"', 'class="col2"');
|
||||
return <<<EOS
|
||||
<table align="center" cellpadding="2" cellspacing="1" border="0" class="cycles">
|
||||
<tr>
|
||||
<th>Directory</th><th>Percent</th><th>Hits</th><th>Lines</th><th>TODO</th>
|
||||
</tr>
|
||||
EOS;
|
||||
}
|
||||
|
||||
function dir_row($info, $srcdir)
|
||||
{
|
||||
global $cycle;
|
||||
if ($info['files'] || $info['todos']) {
|
||||
$c = $cycle->next();
|
||||
$srcdir_html = htmlspecialchars($srcdir);
|
||||
$todos = number_format($info['todos']);
|
||||
if ($info['total']) {
|
||||
$srcdir_url = urlencode($srcdir);
|
||||
$hits = number_format($info['hits']);
|
||||
$total = number_format($info['total']);
|
||||
calc_percent($info, $percent, $class);
|
||||
$bar = bar($percent, $class);
|
||||
return <<<EOS
|
||||
<tr $c>
|
||||
<td class="coverFile"><a href="?path={$srcdir_url}">{$srcdir_html}</a></td>
|
||||
<td class="coverBar">$bar</td>
|
||||
<td class="coverNum{$class}">{$hits}</td>
|
||||
<td class="coverNum{$class}">{$total}</td>
|
||||
<td class="coverNum{$class}">{$todos}</td>
|
||||
</tr>
|
||||
EOS;
|
||||
}
|
||||
else {
|
||||
return <<<EOS
|
||||
<tr $c>
|
||||
<td class="coverFile">{$srcdir_html}</td>
|
||||
<td class="coverBar"></td>
|
||||
<td class="coverNumLo"></td>
|
||||
<td class="coverNumLo"></td>
|
||||
<td class="coverNumLo">{$todos}</td>
|
||||
</tr>
|
||||
EOS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dir_foot()
|
||||
{
|
||||
return <<<EOS
|
||||
</table>
|
||||
EOS;
|
||||
}
|
||||
|
||||
function file_head()
|
||||
{
|
||||
global $cycle;
|
||||
$cycle = new Cycle('class="col1"', 'class="col2"');
|
||||
return <<<EOS
|
||||
<br>
|
||||
<table align="center" cellpadding="2" cellspacing="1" border="0" class="cycles">
|
||||
<tr>
|
||||
<th>File</th><th>Percent</th><th>Hits</th><th>Lines</th>
|
||||
</tr>
|
||||
EOS;
|
||||
}
|
||||
|
||||
function file_row($info, $srcfile)
|
||||
{
|
||||
global $cycle;
|
||||
|
||||
$c = $cycle->next();
|
||||
$srcfile_html = htmlspecialchars($srcfile);
|
||||
$total = number_format($info['total']);
|
||||
if ($info['total']) {
|
||||
$hits = number_format($info['hits']);
|
||||
$srcfile_url = urlencode($srcfile);
|
||||
calc_percent($info, $percent, $class);
|
||||
$bar = bar($percent, $class);
|
||||
return <<<EOS
|
||||
<tr $c>
|
||||
<td class="coverFile"><a href="?path={$srcfile_url}">{$srcfile_html}</a></td>
|
||||
<td class="coverBar">$bar</td>
|
||||
<td class="coverNum{$class}">{$hits}</td>
|
||||
<td class="coverNum{$class}">{$total}</td>
|
||||
</tr>
|
||||
EOS;
|
||||
}
|
||||
else {
|
||||
return <<<EOS
|
||||
<tr $c>
|
||||
<td class="coverFile">{$srcfile_html}</a></td>
|
||||
<td class="coverBar"></td>
|
||||
<td class="coverNumLo"></td>
|
||||
<td class="coverNumLo">{$total}</td>
|
||||
</tr>
|
||||
EOS;
|
||||
}
|
||||
}
|
||||
|
||||
function file_foot()
|
||||
{
|
||||
return <<<EOS
|
||||
</table>
|
||||
EOS;
|
||||
}
|
||||
|
||||
if ($action == 'dir') {
|
||||
$path_html = htmlspecialchars($path);
|
||||
echo <<<EOS
|
||||
<a href="?">root</a> $path<br />
|
||||
EOS;
|
||||
echo dir_head($dirinfo);
|
||||
echo dir_row($dirinfo, $path);
|
||||
echo dir_foot($dirinfo);
|
||||
if ($dirinfo['subdirs']) {
|
||||
echo dir_head();
|
||||
foreach ($dirinfo['subdirs'] as $srcdir => $info) {
|
||||
echo dir_row($info, $srcdir);
|
||||
}
|
||||
echo dir_foot();
|
||||
}
|
||||
if ($dirinfo['files']) {
|
||||
echo file_head();
|
||||
foreach ($dirinfo['files'] as $srcfile => $info) {
|
||||
echo file_row($info, $srcfile);
|
||||
}
|
||||
echo file_foot();
|
||||
}
|
||||
}
|
||||
else if ($action == 'file') {
|
||||
$dir_url = urlencode($dir);
|
||||
$dir_html = htmlspecialchars($dir);
|
||||
echo <<<EOS
|
||||
<a href="?">root</a> <a href="?path={$dir_url}">{$dir_html}</a>/<b>{$filename}</b><br />
|
||||
EOS;
|
||||
|
||||
echo file_head();
|
||||
echo file_row($fileinfo, $path);
|
||||
echo file_foot();
|
||||
|
||||
if ($tplfile) {
|
||||
$tplfile_html = htmlspecialchars($tplfile);
|
||||
echo <<<EOS
|
||||
<a href="#tpl">{$tplfile_html}</a><br />
|
||||
EOS;
|
||||
}
|
||||
echo <<<EOS
|
||||
<pre class="code"><ol>{$filecov}</ol></pre>
|
||||
EOS;
|
||||
if ($tplfile) {
|
||||
echo <<<EOS
|
||||
<a name="tpl">{$tplfile}</a>
|
||||
<pre class="code"><ol>{$tplcov}</ol></pre>
|
||||
EOS;
|
||||
}
|
||||
}
|
||||
else {
|
||||
echo htmlspecialchars($action);
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
include("coverager.php");
|
Loading…
Reference in new issue