Return the HTML or CLI debug report.
@param  array  $backtrace
@return string
6513
public static function getReport(array $backtrace) {
		$r = '';

		if(static::$format === 'html') {
			$request = \Asgard\Http\Request::singleton();
			$r .= static::getHTMLBacktrace($request, $backtrace);
			$r .= static::getHTMLRequest($request);
		}
		else
			$r .= static::getCLIBacktrace($backtrace);

		return $r;
	}
642282
static private function getTextBackTrace($backtrace) {
		$str = '';
	
		foreach ($backtrace as $step) {
			if ($step['function']!='getTextBackTrace' && $step['function']!='handle_error')
			{
				if (isset($step['file']) && isset($step['line'])) {
					$str .= "In ".$step['file'] . " at line ".$step['line'].": ";
				}
				if (isset($step['class']) && isset($step['type']) && isset($step['function'])) {
					$str .= $step['class'].$step['type'].$step['function'].'(';
				}
	
				if (is_array($step['args'])) {
					$drawn = false;
					$params = '';
					foreach ( $step['args'] as $param)
					{
						$params .= self::getPhpVariableAsText($param);
						//$params .= var_export($param, true);
						$params .= ', ';
						$drawn = true;
					}
					$str .= $params;
					if ($drawn == true)
					$str = substr($str, 0, strlen($str)-2);
				}
				$str .= ')';
				$str .= "\n";
			}
		}
	
		return $str;
	}
833726
public static function normalize($backtrace)
    {
        if (!static::isThrowable($backtrace)) {
            return $backtrace;
        }
        return array_merge([[
            'function' => '[NA]',
            'file'     => $backtrace->getFile(),
            'line'     => $backtrace->getLine(),
            'args'     => []
        ]], $backtrace->getTrace());
    }
702153
public function get_debug_backtrace( $unset = [] ) {
		$backtrace = debug_backtrace();
		foreach ( $backtrace as $k => $v ) {
			// 大量のデータになりがちな object と args を削除や編集
			unset( $backtrace[ $k ]['object'] );
			if ( ! empty( $backtrace[ $k ]['args'] ) ) {
				$backtrace[ $k ]['args'] = $this->parse_backtrace_args( $backtrace[ $k ]['args'] );
			} else {
				unset( $backtrace[ $k ]['args'] );
			}
			if ( ! empty( $unset ) ) {
				foreach ( $v as $key => $value ) {
					if ( in_array( $key, $unset ) ) {
						unset( $backtrace[ $k ][ $key ] );
					}
				}
			}
		}

		return $backtrace;
	}
428477
public static function debugBacktraceString($trace = null) {
		$result = [];
		if (!\Debug::$debug) return $result;
		$i = 1;
		// if trace is not provided
		if (empty($trace)) {
			$trace = debug_backtrace();
			unset($trace[0]);
		}
		foreach($trace as $v) {
			$stack = '#' . $i . ' ' . (isset($v['file']) ? $v['file'] : 'Unknown');
			if (isset($v['line'])) {
				$stack.= '(' . $v['line'] . ')';
			}
			// do not show error handler
			if (!(isset($v['class']) && $v['class'] == 'error' && $v['function'] == 'error_handler')) {
				$stack.= ': ';
				if(isset($v['class'])) {
					$stack.= $v['class'] . $v['type'];
				}
				$params = [];
				if (isset($v['args'])) {
					foreach ($v['args'] as $v2) {
						if (gettype($v2) == 'string') {
							$params[] = str_replace(["\n", "\r", "\t"], ' ', $v2);
						} else if (is_array($v2)) {
							$temp = var_export_condensed($v2, ['skip_objects' => true]);
							$params[] = substr($temp, 0, 100) . '...';
						} else {
							$params[] = var_export_condensed($v2, ['skip_objects' => true]);
						}
					}
				}
				$stack.= $v['function'] . '(' . implode(', ', $params) . ');';
			}
			$i++;
			$result[] = $stack;
		}
		return $result;
	}
763008
private function getTrace()
    {
        $trace = array();

        if (PHP_VERSION_ID >= 50400) {
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
        } else if (PHP_VERSION_ID >= 50306) {
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
        } else {
            $trace = debug_backtrace();
        }
        if (empty($trace)) {
            return '';
        }
        array_shift($trace); // ignore $this->getTrace();
        array_shift($trace); // ignore $this->process()
        $i = 0;
        $returnArray = array();
        while (isset($trace[$i]['class']) && false === strpos($trace[$i]['class'], 'Zend\\Log')
            && false === strpos($trace[$i]['class'], 'DhErrorLogging')) {
            $i++;
            $returnArray[] = array(
                'file'     => isset($trace[$i]['file'])   ? $trace[$i]['file']   : null,
                'line'     => isset($trace[$i]['line'])   ? $trace[$i]['line']   : null,
                'class'    => isset($trace[$i]['class'])    ? $trace[$i]['class']    : null,
                'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null,
            );
        }

        return $returnArray;
    }
556321
function getBacktrace($frame = null)
    {
        if (defined('PEAR_IGNORE_BACKTRACE')) {
            return null;
        }
        if ($frame === null) {
            return $this->backtrace;
        }
        return $this->backtrace[$frame];
    }
255255
public function getBetterTrace() {
        $trace = $this->betterTrace;

        if (!$trace) {
            // transform the original stacktrace into a better one
            $trace = DebugHelper::fixTrace($this->getTrace(), $this->getFile(), $this->getLine());

            // drop the first frame if the exception was created in the registered error handler
            if (DebugHelper::getFQFunctionName($trace[0]) == ErrorHandler::class.'::handleError') {
                \array_shift($trace);

                // if the error was triggered by include/require/_once: fix the next frame, it's wrong
                if (sizeof($trace) > 1) {
                    $function = DebugHelper::getFQFunctionName($trace[0]);
                    if ($function=='include' || $function=='include_once' || $function=='require' || $function=='require_once') {
                        if (isset($trace[0]['file']) && isset($trace[1]['file'])) {
                            if ($trace[0]['file'] == $trace[1]['file']) {
                                if (isset($trace[0]['line']) && isset($trace[1]['line'])) {
                                    if ($trace[0]['line'] == $trace[1]['line']) {
                                        unset($trace[0]['file'], $trace[0]['line']);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // store the new stacktrace
            $this->betterTrace = $trace;
        }
        return $trace;
    }
316487
private function getTraceOutput()
    {
        if (! $this->addTraceToOutput()) {
            return '';
        }
        $inspector = $this->getInspector();
        $frames = $inspector->getFrames();

        $response = "\nStack trace:";

        $line = 1;
        foreach ($frames as $frame) {
            /** @var Frame $frame */
            $class = $frame->getClass();

            $template = "\n%3d. %s->%s() %s:%d%s";
            if (! $class) {
                // Remove method arrow (->) from output.
                $template = "\n%3d. %s%s() %s:%d%s";
            }

            $response .= sprintf(
                $template,
                $line,
                $class,
                $frame->getFunction(),
                $frame->getFile(),
                $frame->getLine(),
                $this->getFrameArgsOutput($frame, $line)
            );

            $line++;
        }

        return $response;
    }
430247
public static function walkBacktrace($backtraces, callable $callback)
    {
        foreach($backtraces as $index => $item){
            $func  = $item['function'] ?? '';
            $class = $item['class'] ?? '';
            $type  = $item['type'] ?? '';
            $file  = $item['file'] ?? '';
            $line  = $item['line'] ?? '';
            ($callback)($index, $file, $line, $class, $type, $func);
        }
    }
413943
protected function _errorhandler_output($errstr, $backtrace, $errortype) {
		// output error
		$error = '<div class="dp_container">';
		$error .= '<div class="skyline">'.$errortype.'</div>';
		$error .= '<h1 class="exception">'.htmlspecialchars($errstr, ENT_QUOTES, 'UTF-8').'</h1>';

		$count = 0;
		foreach ($backtrace as $key => $value) {
			// only if file is available
			if (!empty($value['file']) && is_file($value['file'])) {
				$id_file = '_errorhandler_file_'.$this->errorcounter.'_'.$count;
				$id_args = 'errorhandler_args_'.$this->errorcounter.'_'.$count;
				$show = ($count === 0) ? 'style="display: block;"' : '';

				if ($count>0) {
					$call = $value['class'].$value['type'].$value['function'].'()';
					$error .= '<h2>'.$call.'</h2>';
				}

				// highlight the file name
				$file = preg_replace('=[^/]+$=', '<strong>$0</strong>', $value['file']);
				
				$error .= '<h3>'.$file.' (Line '.$value['line'].')</h3>';
				$error .= '<div class="file" id="'.$id_file.'" '.$show.'>'.$this->_getContent($value['file'], $value['line']).'<div style="clear: both;"></div></div>';

				if (count($value['args'])>0 and $count > 0) {
					$dump = htmlspecialchars(print_r($value['args'], true));
					$error .= '<h3>Arguments ('.count($value['args']).')</h3>';
					$error .= '<div class="args" id="'.$id_args.'">'.$dump.'</div>';
				}

				$count++;
			}
		}

		$error .= '</div>';

		// output css and js only at first call
		if ($this->errorcounter === 1) $error .= $this->_debug_styles();

		return $error;
	}
1234684
public function renderBacktrace()
	{
		$contents  = null;
		$backtrace = $this->error->getTrace();

		if (is_array($backtrace))
		{
			ob_start();

			$j = 1;

			$html = array();
			$html[] = '<table class="backtrace">';
			$html[] = '	<caption>Call stack</caption>';
			$html[] = '	<thead>';
			$html[] = '		<tr>';
			$html[] = '			<th scope="col">#</th>';
			$html[] = '			<th scope="col">Function</th>';
			$html[] = '			<th scope="col">Location</th>';
			$html[] = '		</tr>';
			$html[] = '	</thead>';
			$html[] = '	<tbody>';
			$html[] = '		<tr>';
			$html[] = '			<th scope="row">0</th>';
			$html[] = '			<td><span class="msg">!! ' . $this->error->getMessage() . ' !!</span></td>';
			$html[] = '			<td><span class="fl">' . $this->rooted($this->error->getFile()) . '</span>:<span class="ln">' . $this->error->getLine() . '</span></td>';
			$html[] = '		</tr>';
			for ($i = count($backtrace) - 1; $i >= 0; $i--)
			{
				$html[] = '		<tr>';
				$html[] = '			<th scope="row">' . $j . '</th>';
				if (isset($backtrace[$i]['class']))
				{
					$html[] = '			<td><span class="cls">' . $backtrace[$i]['class'] . '</span><span class="opn">' . $backtrace[$i]['type'] . '</span><span class="mtd">' . $backtrace[$i]['function'] . '</span>()</td>';
				}
				else
				{
					$html[] = '			<td><span class="fnc">' . $backtrace[$i]['function'] . '</span>()</td>';
				}
				if (isset($backtrace[$i]['file']))
				{
					$html[] = '			<td><span class="fl">' . $this->rooted($backtrace[$i]['file']) . '</span>:<span class="ln">' . $backtrace[$i]['line'] . '</span></td>';
				}
				else
				{
					$html[] = '			<td>&#160;</td>';
				}
				$html[] = '		</tr>';
				$j++;
			}
			$html[] = '	</tbody>';
			$html[] = '</table>';

			echo "\n" . implode("\n", $html) . "\n";
			$contents = ob_get_contents();
			ob_end_clean();
		}
		return $contents;
	}
289251
public static function debugTrail() {
		$trail = debug_backtrace();
		$trail = array_reverse($trail);
		array_pop($trail);

		$path = array();
		foreach ($trail as $dat) {
			$pathFragment = $dat['class'] . $dat['type'] . $dat['function'];
				// add the path of the included file
			if (in_array($dat['function'], array('require', 'include', 'require_once', 'include_once'))) {
				$pathFragment .= '(' . substr($dat['args'][0], strlen(PATH_site)) . '),' . substr($dat['file'], strlen(PATH_site));
			}
			$path[] = $pathFragment . '#' . $dat['line'];
		}

		return implode(' // ', $path);
	}
587509
public static function dump($debug_backtrace)
    {
        if (PHP_SAPI === 'cli') {
            self::cliDump($debug_backtrace);
        }

        ob_end_clean();
        ob_start();
        echo <<<END
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/styles/default.min.css" />
<script>hljs.initHighlightingOnLoad();</script>
<style>code.php.hljs{margin: -0.4em 0;}code.active{background-color:#e0e0e0;}code:before{content:attr(data-line);}code.active:before{color:#c00;font-weight:bold;}</style>
</head>
<body>
END;

        echo '<div>Dump: ' . $debug_backtrace['file'] . ':<b>' . $debug_backtrace['line'] . "</b></div>";
        echo '<pre>';
        $i = 0;
        foreach ($debug_backtrace['args'] as $data) {
            echo '<code>';
            var_dump($data);
            echo '</code>';
            $i += 1;
        }
        echo '</pre>';
        echo <<<END
</body>
</html>
END;
        exit;
    }
1019068
public function backtrace(string $name = null) : string
    {
        $exception = new ErrorException(
            $name ?? 'backtrace',
            0,
            1,
            debug_backtrace()[0]['file'],
            (int) debug_backtrace()[0]['line']
        );

        return $this->render($exception, 1);
    }
253977
private static function getFunctionNameForReport(array $trace = null)
    {
        if (null === $trace) {
            return '<unknown function>';
        }
        if (empty($trace[0]['function'])) {
            return '<none>';
        }
        $functionName = [$trace[0]['function']];
        if (isset($trace[0]['type'])) {
            $functionName[] = $trace[0]['type'];
        }
        if (isset($trace[0]['class'])) {
            $functionName[] = $trace[0]['class'];
        }
        return implode('', array_reverse($functionName));
    }
945897
public static function backtrace($trace = null)
	{
		$trace or $trace = debug_backtrace();

		if (\Fuel::$is_cli) {
			// Special case for CLI since the var_dump of a backtrace is of little use.
			$str = '';
			foreach ($trace as $i => $frame)
			{
				$line = "#$i\t";

				if ( ! isset($frame['file']))
				{
					$line .= "[internal function]";
				}
				else
				{
					$line .= $frame['file'] . ":" . $frame['line'];
				}

				$line .= "\t";

				if (isset($frame['function']))
				{
					if (isset($frame['class']))
					{
						$line .= $frame['class'] . '::';
					}

					$line .= $frame['function'] . "()";
				}

				$str .= $line . "\n";

			}

			return $str;
		}
		else
		{
			return static::dump($trace);
		}
	}