. ** ** debug.class - Debug Functionality for ITools */ /** * Debug functions */ class it_debug { var $level; /** * Constructor * @param $level Debug level. All debug() calls with a level <= $level are shown. */ function it_debug($level=0) { $this->level = isset($GLOBALS['debug_level']) ? $GLOBALS['debug_level'] : $level; } /** * Output a message if the global debug level is higher or the same as $level * @param $text Message to display * @param $level Debug level */ function debug($text, $level = 0) { if ($this->level >= $level) { echo (isset($_SERVER['REMOTE_ADDR']) ? nl2br("$level $text\n") : "$level $text")."\n"; flush(); } } /** * Get source line of grandparent calling this function * @param $stacksoffs go up an extra $stacksoffs levels */ function srcline($stackoffs = 0) { $stack = debug_backtrace(); $line = $stack[1 + $stackoffs]['line']; $file = $stack[1 + $stackoffs]['file']; if (!isset($GLOBALS['it_debug::dump source'][$file])) $GLOBALS['it_debug::dump source'][$file] = file($file); return $GLOBALS['it_debug::dump source'][$file][$line-1]; } /** * Backend for functions D(), ED() and EDX() in functions.php * @param Origargs Array containing original arguments do ED() etc * @return String representation of dump */ function dump($args) { if (ereg('(csv|txt|gif|jpg)', $_SERVER['PHP_SELF']) || !$_SERVER['HTTP_USER_AGENT']) $plain = 1; else if ($_SERVER['REMOTE_ADDR']) { $blue = ""; $noblue = ""; } else if (getenv('USER') != 'cschneid') # ;) { $blue = "\033[34m"; $noblue = "\033[m"; $red = "\033[31m"; $nored = "\033[m"; } $src = it_debug::srcline(1); list($function, $paramlist) = it::match('\b(D|ED|EDC|EDX)\s*\((.*)', $src); $paramtokens = token_get_all("([^\n]+),#", 'var \$$1 = $2;', $values); $item = $head . "class $classname { $values }$tail"; } $item = preg_replace("#(=>?)\s*\n\s*(array|class)#", '$1 $2', $item); # array( and class on same line as key $item = preg_replace('#array \(\s+([^({,;]+),\s+\)#', 'array( $1 )', $item); # 1-element arrays on 1 line $item = preg_replace('#class (\S+) \{\s+([^({,;]+;)?\s+\}#', 'class $1 { $2 }', $item); # 1-element objects on 1 line #$item = preg_replace('#\{\s*var \$attr#', '{ var $attr', $item); # move $attr on same line $item = preg_replace("#\\(\s*\n\s*\\)#", "()", $item); # empty arrays on 1 line #$item = preg_replace('#\s+var \$_(.|\n)*?;\s*\n#', "", $item); $item = "$red$item$nored"; if (isset($_SERVER['REMOTE_ADDR']) && !$plain) $item = htmlspecialchars($item); if (ereg('^[\'"]', $var)) $r .= "$item "; else { $var = "$blue$var=$noblue"; $r .= $previtem && preg_match("/\n/", $item . $previtem) ? "\n$var$item " : "$var$item "; $previtem = $item; } } if ($GLOBALS['debug_indent']) $r = str_repeat(" ", count(debug_backtrace())-3) . $r; $title = it_html::Q(it_debug::backtrace(array('skiplevels' => 1))); if (isset($_SERVER['REMOTE_ADDR']) && !$plain) return "
$r\n"; else return "$r\n"; } /** * Return short stackdump * @param $p['levels'] number of stack levels to return (default: 0 = all) * @param $p['skiplevels'] number of stack levels to omit * @param $p['skipfiles'] regular expression of filenames to omit */ function backtrace($p = array()) { if (!is_array($p)) $p = array('skiplevels' => $p); $p += array('levels' => 0, 'skiplevels'=> 0, 'skipfiles' => "###"); if (!function_exists('memory_get_usage') || (memory_get_usage() < 50000000)) { foreach (array_slice(debug_backtrace(), $p['skiplevels'] + 1) as $call) { if (($fn = $call['file']) && !it::match($p['skipfiles'], $call['file'])) { $fn = (it::match('auto_prepend', $fn) ? basename(dirname(dirname($fn))) . "/" : "") . basename($fn); $result[] = $fn . ":" . $call['line']; if (--$p['levels'] == 0) break; } } } return join(" ", (array)$result); } } ?>