Skip to content

Commit

Permalink
Separate regular PhD output from error handling (#176)
Browse files Browse the repository at this point in the history
- Move error handling code into a class and remove PhD message output handling from it.
- Introduce a new class to handle PhD message output.
- Make the implicit dependency on the output functionality of classes explicit.
- Update PEAR package.xml.
- Fix tests.
- Use proper variadic parameters
- Use class constants
- Use first-class callable syntax

---------

Co-authored-by: haszi <haszika80@gmail.com>
  • Loading branch information
haszi and haszi authored Nov 10, 2024
1 parent b0c1f87 commit 1528413
Show file tree
Hide file tree
Showing 84 changed files with 565 additions and 439 deletions.
4 changes: 3 additions & 1 deletion package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,19 @@
<file name="PHPDOCHandler.php" role="php"/>
</dir>
<file name="Autoloader.php" role="php"/>
<file name="constants.php" role="php"/>
<file name="Config.php" role="php">
<tasks:replace from="@php_dir@" to="php_dir" type="pear-config"/>
<tasks:replace from="@phd_version@" to="version" type="package-info" />
</file>
<file name="ErrorHandler.php" role="php"/>
<file name="Format.php" role="php"/>
<file name="functions.php" role="php"/>
<file name="Highlighter.php" role="php"/>
<file name="Index.php" role="php"/>
<file name="IndexRepository.php" role="php"/>
<file name="MediaManager.php" role="php"/>
<file name="ObjectStorage.php" role="php"/>
<file name="OutputHandler.php" role="php"/>
<file name="PIHandler.php" role="php"/>
<file name="Reader.php" role="php"/>
<file name="ReaderKeeper.php" role="php"/>
Expand Down
72 changes: 72 additions & 0 deletions phpdotnet/phd/ErrorHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
namespace phpdotnet\phd;

class ErrorHandler
{
private const ERROR_MAP = [
// PHP Triggered Errors
E_DEPRECATED => 'E_DEPRECATED ',
E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR ',
E_STRICT => 'E_STRICT ',
E_WARNING => 'E_WARNING ',
E_NOTICE => 'E_NOTICE ',

// User Triggered Errors
E_USER_ERROR => 'E_USER_ERROR ',
E_USER_WARNING => 'E_USER_WARNING ',
E_USER_NOTICE => 'E_USER_NOTICE ',
E_USER_DEPRECATED => 'E_USER_DEPRECATED ',
];

private bool $recursive = false;

public function __construct(
private OutputHandler $outputHandler
) {}

public function handleError($errno, $msg, $file, $line) {
// Respect the error_reporting setting
if (!(error_reporting() & $errno)) {
return false;
}

// Recursive protection
if ($this->recursive) {
// Thats bad.. lets print a backtrace right away
debug_print_backtrace();
// Fallback to the default errorhandler
return false;
}
$this->recursive = true;

switch($errno) {
// User triggered errors
case E_USER_ERROR:
case E_USER_WARNING:
case E_USER_NOTICE:
$this->outputHandler->printUserError($msg, $file, $line, self::ERROR_MAP[$errno]);
break;

// PHP triggered errors
case E_DEPRECATED:
case E_RECOVERABLE_ERROR:
case E_STRICT:
case E_WARNING:
case E_NOTICE:
$this->outputHandler->printPhpError($msg, $file, $line, self::ERROR_MAP[$errno]);
break;

default:
$this->recursive = false;
return false;
}

// Abort on fatal errors
if ($errno & (E_USER_ERROR|E_RECOVERABLE_ERROR)) {
exit(1);
}

$this->recursive = false;
return true;
}
}
6 changes: 4 additions & 2 deletions phpdotnet/phd/Format.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ abstract class Format extends ObjectStorage
const LDESC = 2;

protected Config $config;
protected OutputHandler $outputHandler;

private $elementmap = array();
private $textmap = array();
Expand Down Expand Up @@ -64,8 +65,9 @@ abstract class Format extends ObjectStorage
*/
protected $CURRENT_ID = "";

public function __construct(Config $config) {
public function __construct(Config $config, OutputHandler $outputHandler) {
$this->config = $config;
$this->outputHandler = $outputHandler;
if ($this->config->indexcache()) {
$this->indexRepository = $this->config->indexcache();
if (!($this instanceof Index)) {
Expand Down Expand Up @@ -312,7 +314,7 @@ public function getFormatName() {

/* Buffer where append data instead of the standard stream (see format's appendData()) */
final public function parse($xml) {
$reader = new Reader();
$reader = new Reader($this->outputHandler);
$render = new Render();

$reader->XML("<notatag>" . $xml . "</notatag>");
Expand Down
9 changes: 5 additions & 4 deletions phpdotnet/phd/Format/Abstract/Manpage.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
abstract class Format_Abstract_Manpage extends Format {
public $role = false;

public function __construct(Config $config) {
parent::__construct($config);
public function __construct(
Config $config,
OutputHandler $outputHandler,
) {
parent::__construct($config, $outputHandler);
}

public function UNDEF($open, $name, $attrs, $props) {
Expand Down Expand Up @@ -55,5 +58,3 @@ public function createLink($for, &$desc = null, $type = Format::SDESC) {
}

}


7 changes: 5 additions & 2 deletions phpdotnet/phd/Format/Abstract/XHTML.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ abstract class Format_Abstract_XHTML extends Format {
protected $mediamanager = null;
protected $lang = 'en';

public function __construct(Config $config) {
parent::__construct($config);
public function __construct(
Config $config,
OutputHandler $outputHandler
) {
parent::__construct($config, $outputHandler);
}

public function transformFromMap($open, $tag, $name, $attrs, $props) {
Expand Down
5 changes: 3 additions & 2 deletions phpdotnet/phd/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,11 @@ class Index extends Format

public function __construct(
IndexRepository $indexRepository,
Config $config
Config $config,
OutputHandler $outputHandler
) {
$this->indexRepository = $indexRepository;
parent::__construct($config);
parent::__construct($config, $outputHandler);
}

public function transformFromMap($open, $tag, $name, $attrs, $props) {
Expand Down
18 changes: 8 additions & 10 deletions phpdotnet/phd/Options/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ class Options_Handler implements Options_Interface
{
public function __construct(
private Config $config,
private Format_Factory $formatFactory
private Format_Factory $formatFactory,
private OutputHandler $outputHandler
) {}

/**
Expand Down Expand Up @@ -211,11 +212,11 @@ public function option_output(string $k, mixed $v): array
trigger_error("Only a single output location can be supplied", E_USER_ERROR);
}
if (!file_exists($v)) {
v("Creating output directory..", VERBOSE_MESSAGES);
$this->outputHandler->v("Creating output directory..", VERBOSE_MESSAGES);
if (!mkdir($v, 0777, true)) {
trigger_error(vsprintf("Can't create output directory : %s", [$v]), E_USER_ERROR);
}
v("Output directory created", VERBOSE_MESSAGES);
$this->outputHandler->v("Output directory created", VERBOSE_MESSAGES);
} elseif (!is_dir($v)) {
trigger_error("Output directory is a file?", E_USER_ERROR);
}
Expand Down Expand Up @@ -510,17 +511,14 @@ public function option_xinclude(string $k, mixed $v): array
*/
public function option_version(string $k, mixed $v): never
{
$color = $this->config->phd_info_color();
$output = $this->config->phd_info_output();
fprintf($output, "%s\n", term_color('PhD Version: ' . $this->config::VERSION, $color));

$this->outputHandler->printPhdInfo('PhD Version: ' . $this->config::VERSION);
$packageList = $this->config->getSupportedPackages();
foreach ($packageList as $package) {
$version = $this->formatFactory::createFactory($package)->getPackageVersion();
fprintf($output, "\t%s: %s\n", term_color($package, $color), term_color($version, $color));
$this->outputHandler->printPhdInfo("\t$package: $version");
}
fprintf($output, "%s\n", term_color('PHP Version: ' . phpversion(), $color));
fprintf($output, "%s\n", term_color($this->config->copyright(), $color));
$this->outputHandler->printPhdInfo('PHP Version: ' . phpversion());
$this->outputHandler->printPhdInfo($this->config->copyright());
exit(0);
}

Expand Down
117 changes: 117 additions & 0 deletions phpdotnet/phd/OutputHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
namespace phpdotnet\phd;

class OutputHandler
{
/** @var array */
private const CONSTANT_TO_MESSAGE_CATEGORY_MAP = [
// PhD informationals
VERBOSE_INDEXING => 'Indexing ',
VERBOSE_FORMAT_RENDERING => 'Rendering Format ',
VERBOSE_THEME_RENDERING => 'Rendering Theme ',
VERBOSE_RENDER_STYLE => 'Rendering Style ',
VERBOSE_PARTIAL_READING => 'Partial Reading ',
VERBOSE_PARTIAL_CHILD_READING => 'Partial Child Reading ',
VERBOSE_TOC_WRITING => 'Writing TOC ',
VERBOSE_CHUNK_WRITING => 'Writing Chunk ',
VERBOSE_MESSAGES => 'Heads up ',

// PhD warnings
VERBOSE_NOVERSION => 'No version information',
VERBOSE_BROKEN_LINKS => 'Broken links ',
VERBOSE_OLD_LIBXML => 'Old libxml2 ',
VERBOSE_MISSING_ATTRIBUTES => 'Missing attributes ',
];

public function __construct(
private Config $config
) {}

/**
* Method to get a color escape sequence
*/
private function term_color(string $text, string|false $color): string {
return $this->config->color_output() && $color !== false ? "\033[" . $color . "m" . $text . "\033[m" : $text;
}

public function printPhdInfo(string $msg, string $info = ""): int {
$color = $this->config->phd_info_color();
$outputStream = $this->config->phd_info_output();

return $this->print($msg, $outputStream, $color, $info);
}

private function printPhdWarning(string $msg, string $warning = ""): int {
$color = $this->config->phd_warning_color();
$outputStream = $this->config->phd_warning_output();

return $this->print($msg, $outputStream, $color, $warning);
}

public function printUserError(string $msg, string $file, int $line, string $error = ""): int {
$color = $this->config->user_error_color();
$outputStream = $this->config->user_error_output();
$data = \sprintf("%s:%d\n\t%s", $file, $line, $msg);

return $this->print($data, $outputStream, $color, $error);
}

public function printPhpError(string $msg, string $file, int $line, string $error = ""): int {
$color = $this->config->php_error_color();
$outputStream = $this->config->php_error_output();
$data = \sprintf("%s:%d\n\t%s", $file, $line, $msg);

return $this->print($data, $outputStream, $color, $error);
}

private function print(string $msg, $outputStream, string|false $color = false, string $infoOrErrorString = ""): int {
if ($infoOrErrorString === "") {
$colorMsg = $this->term_color(\sprintf("%s", $msg), $color);

return \fprintf($outputStream, "%s\n", $colorMsg);
}

$time = \date($this->config->date_format());
$timestamp = $this->term_color(\sprintf("[%s - %s]", $time, $infoOrErrorString), $color);

return \fprintf($outputStream, "%s %s\n", $timestamp, $msg);
}

/**
* Print info messages: v("printf-format-text" [, $arg1, ...], $verbose-level)
*/
public function v(...$args): bool {
$messageCategory = \array_pop($args);
$msg = \vsprintf(\array_shift($args), $args);

// Respect the error_reporting setting
if (!(\error_reporting() & $messageCategory)) {
return false;
}

switch($messageCategory) {
case VERBOSE_INDEXING:
case VERBOSE_FORMAT_RENDERING:
case VERBOSE_THEME_RENDERING:
case VERBOSE_RENDER_STYLE:
case VERBOSE_PARTIAL_READING:
case VERBOSE_PARTIAL_CHILD_READING:
case VERBOSE_TOC_WRITING:
case VERBOSE_CHUNK_WRITING:
case VERBOSE_MESSAGES:
$this->printPhdInfo($msg, self::CONSTANT_TO_MESSAGE_CATEGORY_MAP[$messageCategory]);
break;

case VERBOSE_NOVERSION:
case VERBOSE_BROKEN_LINKS:
case VERBOSE_OLD_LIBXML:
case VERBOSE_MISSING_ATTRIBUTES:
$this->printPhdWarning($msg, self::CONSTANT_TO_MESSAGE_CATEGORY_MAP[$messageCategory]);
break;

default:
return false;
}
return true;
}
}
11 changes: 6 additions & 5 deletions phpdotnet/phd/Package/Generic/BigXHTML.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
namespace phpdotnet\phd;

class Package_Generic_BigXHTML extends Package_Generic_XHTML {
public function __construct(Config $config) {
parent::__construct($config);
public function __construct(
Config $config,
OutputHandler $outputHandler
) {
parent::__construct($config, $outputHandler);
$this->registerFormatName("Big-XHTML");
$this->setTitle("Index");
$this->setChunked(false);
Expand Down Expand Up @@ -94,7 +97,7 @@ public function update($event, $value = null) {
break;

case Render::VERBOSE:
v("Starting %s rendering", $this->getFormatName(), VERBOSE_FORMAT_RENDERING);
$this->outputHandler->v("Starting %s rendering", $this->getFormatName(), VERBOSE_FORMAT_RENDERING);
break;
}
}
Expand All @@ -113,5 +116,3 @@ public function createLink($for, &$desc = null, $type = self::SDESC) {
}

}


11 changes: 6 additions & 5 deletions phpdotnet/phd/Package/Generic/ChunkedXHTML.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
namespace phpdotnet\phd;

class Package_Generic_ChunkedXHTML extends Package_Generic_XHTML {
public function __construct(Config $config) {
parent::__construct($config);
public function __construct(
Config $config,
OutputHandler $outputHandler
) {
parent::__construct($config, $outputHandler);
$this->registerFormatName("Chunked-XHTML");
$this->setTitle("Index");
$this->setChunked(true);
Expand Down Expand Up @@ -86,7 +89,7 @@ public function update($event, $value = null) {
}
break;
case Render::VERBOSE:
v("Starting %s rendering", $this->getFormatName(), VERBOSE_FORMAT_RENDERING);
$this->outputHandler->v("Starting %s rendering", $this->getFormatName(), VERBOSE_FORMAT_RENDERING);
break;
}
}
Expand Down Expand Up @@ -207,5 +210,3 @@ protected function createNavBar($id) {
}

}


Loading

0 comments on commit 1528413

Please sign in to comment.