diff --git a/.gitignore b/.gitignore index 43e881f..07a5d7e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,5 +12,6 @@ src/ncc/ThirdParty/Symfony/Process/autoload_spl.php src/ncc/ThirdParty/Symfony/Uid/autoload_spl.php src/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php src/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php +src/ncc/ThirdParty/theseer/Autoload/autoload_spl.php src/ncc/autoload_spl.php src/ncc/autoload.php \ No newline at end of file diff --git a/Makefile b/Makefile index 7c2e53c..4d0b112 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ autoload: make src/ncc/ThirdParty/Symfony/Uid/autoload_spl.php make src/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php make src/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php + make src/ncc/ThirdParty/theseer/Autoload/autoload_spl.php make src/ncc/autoload_spl.php cp src/autoload/autoload.php src/ncc/autoload.php @@ -41,6 +42,10 @@ src/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php: $(PHPCC) $(PHPAB) --output src/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php \ src/ncc/ThirdParty/Symfony/Yaml +src/ncc/ThirdParty/theseer/Autoload/autoload_spl.php: + $(PHPCC) $(PHPAB) --output src/ncc/ThirdParty/theseer/Autoload/autoload_spl.php \ + src/ncc/ThirdParty/theseer/Autoload + src/ncc/autoload_spl.php: $(PHPCC) $(PHPAB) --output src/ncc/autoload_spl.php \ src/ncc/Abstracts \ diff --git a/src/autoload/autoload.php b/src/autoload/autoload.php index 2bb52d7..5d05c62 100644 --- a/src/autoload/autoload.php +++ b/src/autoload/autoload.php @@ -22,6 +22,7 @@ $third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Uid' . DIRECTORY_SEPARATOR . 'autoload_spl.php', $third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Filesystem' . DIRECTORY_SEPARATOR . 'autoload_spl.php', $third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Yaml' . DIRECTORY_SEPARATOR . 'autoload_spl.php', + $third_party_path . 'theseer' . DIRECTORY_SEPARATOR . 'Autoload' . DIRECTORY_SEPARATOR . 'autoload_spl.php', ]; foreach($target_files as $file) diff --git a/src/ncc/ThirdParty/theseer/Autoload/Application.php b/src/ncc/ThirdParty/theseer/Autoload/Application.php new file mode 100644 index 0000000..9a2ab99 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/Application.php @@ -0,0 +1,247 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + * + */ +namespace TheSeer\Autoload { + + class Application { + + private $logger; + private $factory; + private $config; + + public function __construct(Logger $logger, Config $config, Factory $factory) { + $this->logger = $logger; + $this->config = $config; + $this->factory = $factory; + } + + public function run() { + $result = $this->runCollector(); + if (!$result->hasUnits()) { + throw new ApplicationException('No units were found - process aborted.', ApplicationException::NoUnitsFound); + } + if ($result->hasDuplicates()) { + return $this->showDuplicatesError($result->getDuplicates()); + } + + if ($this->config->isCacheEnabled()) { + $this->factory->getCache()->persist($this->config->getCacheFile()); + } + + $template = @file_get_contents($this->config->getTemplate()); + if ($template === false) { + throw new ApplicationException("Failed to read the template file."); + } + + $builder = $this->factory->getRenderer($result); + $code = $builder->render($template); + if ($this->config->isLintMode()) { + return $this->runLint($code); + } + return $this->runSaver($code); + } + + /** + * @return CollectorResult + */ + private function runCollector() { + if ($this->config->isFollowSymlinks()) { + $this->logger->log('Following symbolic links is enabled.' . "\n\n"); + } + $collector = $this->factory->getCollector(); + foreach ($this->config->getDirectories() as $directory) { + if (is_dir($directory)) { + $this->logger->log('Scanning directory ' . $directory . "\n"); + $scanner = $this->factory->getScanner()->getIterator($directory); + $collector->processDirectory($scanner); + // this unset is needed to "fix" a segfault on shutdown in some PHP Versions + unset($scanner); + } else { + $file = new \SplFileInfo($directory); + $filter = $this->factory->getFilter(new \ArrayIterator(array($file))); + foreach($filter as $file) { + $this->logger->log('Scanning file ' . $file . "\n"); + $collector->processFile($file); + } + } + } + return $collector->getResult(); + } + + private function runSaver($code) { + $output = $this->config->getOutputFile(); + if (!$this->config->isPharMode()) { + if ($output === 'STDOUT') { + $this->logger->log("\n"); + echo $code; + $this->logger->log("\n\n"); + return CLI::RC_OK; + } + // @codingStandardsIgnoreStart + $written = @file_put_contents($output, $code); + // @codingStandardsIgnoreEnd + if ($written != strlen($code)) { + $this->logger->log("Writing to file '$output' failed.", STDERR); + return CLI::RC_EXEC_ERROR; + } + $this->logger->log("\nAutoload file {$output} generated.\n\n"); + return CLI::RC_OK; + } + if (strpos($code, '__HALT_COMPILER();') === FALSE) { + $this->logger->log( + "Warning: Template used in phar mode did not contain required __HALT_COMPILER() call\n" . + "which has been added automatically. The used stub code may not work as intended.\n\n", STDERR); + $code .= $this->config->getLinebreak() . '__HALT_COMPILER();'; + } + $pharBuilder = $this->factory->getPharBuilder(); + if ($keyfile = $this->config->getPharKey()) { + $pharBuilder->setSignatureKey($this->loadPharSignatureKey($keyfile)); + } + if ($aliasName = $this->config->getPharAliasName()) { + $pharBuilder->setAliasName($aliasName); + } + if ($this->config->hasPharHashAlgorithm()) { + $pharBuilder->setSignatureType($this->config->getPharHashAlgorithm()); + } + $pharBuilder->build($output, $code); + $this->logger->log("\nphar archive '{$output}' generated.\n\n"); + return CLI::RC_OK; + } + + private function loadPharSignatureKey($keyfile) { + if (!extension_loaded('openssl')) { + throw new ApplicationException('Extension for OpenSSL not loaded - cannot sign phar archive - process aborted.', + ApplicationException::OpenSSLError); + } + $keydata = file_get_contents($keyfile); + if (strpos($keydata, 'ENCRYPTED') !== FALSE) { + $this->logger->log("Passphrase for key '$keyfile': "); + $g = shell_exec('stty -g'); + shell_exec('stty -echo'); + $passphrase = trim(fgets(STDIN)); + $this->logger->log("\n"); + shell_exec('stty ' . $g); + $private = openssl_pkey_get_private($keydata, $passphrase); + } else { + $private = openssl_pkey_get_private($keydata); + } + if (!$private) { + throw new ApplicationException("Opening private key '$keyfile' failed - process aborted.\n\n", ApplicationException::OpenSSLError); + } + return $private; + } + + + /** + * Execute a lint check on generated code + * + * @param string $code Generated code to lint + * + * @return boolean + */ + protected function runLint($code) { + $dsp = array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ); + + $binary = $this->config->getPhp(); + + $process = proc_open($binary . ' -l', $dsp, $pipes); + + if (!is_resource($process)) { + $this->logger->log("Opening php binary for linting failed.\n", STDERR); + return 1; + } + + fwrite($pipes[0], $code); + fclose($pipes[0]); + fclose($pipes[1]); + + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[2]); + + $rc = proc_close($process); + + if ($rc == 255) { + $this->logger->log("Syntax errors during lint:\n" . + str_replace('in - on line', 'in generated code on line', $stderr) . + "\n", STDERR); + return CLI::RC_LINT_ERROR; + } + + $this->logger->log("Lint check of geneated code okay\n\n"); + return CLI::RC_OK; + } + + /** + * @param array $duplicates + * + * @return int + */ + private function showDuplicatesError(array $duplicates) { + $this->logger->log( + sprintf("\nMultiple declarations of trait(s), interface(s) or class(es). Could not generate autoload map.\n"), + STDERR + ); + foreach($duplicates as $unit => $files) { + $this->logger->log( + sprintf("\nUnit '%s' defined in:\n", $unit), + STDERR + ); + + /** @var array $files */ + foreach($files as $file) { + $this->logger->log( + sprintf(" - %s\n", $file), + STDERR + ); + + } + } + return CLI::RC_DUPLICATES_ERROR; + } + + } + + class ApplicationException extends \Exception { + const NoUnitsFound = 1; + const OpenSSLError = 2; + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/AutoloadRenderer.php b/src/ncc/ThirdParty/theseer/Autoload/AutoloadRenderer.php new file mode 100644 index 0000000..57c9e6c --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/AutoloadRenderer.php @@ -0,0 +1,297 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + */ + +namespace TheSeer\Autoload { + + /** + * Builds spl based autoload code for inclusion into projects + * + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + */ + class AutoloadRenderer { + + /** + * Associative array of classes (key) and the files (value) they are in + * + * @var array + */ + protected $classes; + + /** + * An optional base dir to strip for the realpath of the filename + * + * @var string + */ + protected $baseDir = ''; + + /** + * Indenting char(s) + * + * @var string + */ + protected $indent = ' '; + + /** + * Char(s) used as linebreak + * + * @var string + */ + protected $linebreak = "\n"; + + /** + * Timestamp of production start + * + * @var integer + */ + protected $timestamp; + + /** + * Format string supplied to date() for use with ___CREATED___ + * + * @var string + */ + protected $dateformat = 'r'; + + /** + * Variables for templates + * + * @var array + */ + protected $variables = array(); + + /** + * Flag to toggle PHP 5.2 compat mode + * + * @var boolean + */ + protected $compat = false; + + /** + * Flag to pass on to spl_autoload_register to prepend + * + * @var bool + */ + private $usePrepend = false; + + /** + * Flag to pass on to spl_autoload_register to optionally throw exceptions on registration error + * + * @var bool + */ + private $throwExceptions = false; + + /** + * Constructor of AutoloadRenderer class + * + * @param array $classlist Array of classes + * + */ + public function __construct(array $classlist) { + $this->classes = $classlist; + ksort($this->classes); + } + + /** + * Toggle PHP 5.2 compat mode + * + * @param boolean $mode Mode to set compat to + */ + public function setCompat($mode) { + $this->compat = $mode; + } + + public function enableExceptions() { + $this->throwExceptions = true; + } + + public function prependAutoloader() { + $this->usePrepend = true; + } + + /** + * Setter for the Basedir + * + * @param string $dir Path to strip from beginning of filenames + * + * @return void + */ + public function setBaseDir($dir) { + $this->baseDir = $dir; + } + + /** + * Overwrite default or previously set indenting option + * + * @param string $indent Char(s) to use for indenting + * + * @return void + */ + public function setIndent($indent) { + $this->indent = $indent; + } + + /** + * Overwrite default or previously set linebreak chars + * + * @param string $lbs Code to set linebreak + * + * @return void + */ + public function setLineBreak($lbs) { + $this->linebreak = $lbs; + } + + /** + * Accessor for current linebreak setting + * + * @return string + */ + public function getLineBreak() { + return $this->linebreak; + } + + /** + * Setter to use allow usage of fixed date/time for ___CREATED___ + * + * @param integer $time unix timestamp + * + * @throws AutoloadBuilderException + */ + public function setTimestamp($time) { + if (!is_int($time) && null !== $time) { + throw new AutoloadBuilderException("'$time' is not a unix timestamp", AutoloadBuilderException::InvalidTimestamp); + } + $this->timestamp = $time; + } + + /** + * Setter to adjust the date/time format output of ___CREATED___ + * + * @param string $frmt Date/Time format string + */ + public function setDateTimeFormat($frmt) { + $this->dateformat = $frmt; + } + + /** + * Set a variable for use with template code + * + * @param string $name Key name (use as ___key___ in template) + * @param string $value Value to use + */ + public function setVariable($name, $value) { + $this->variables['___'.$name.'___'] = $value; + } + + + /** + * Resolve relative location of file path to basedir if one is set and fix potential + * broken windows pathnames when run on windows. + * + * @param string $fname + * + * @return string + */ + protected function resolvePath($fname) { + if (empty($this->baseDir)) { + return str_replace('\\', '/', $fname); + } + $basedir = explode(DIRECTORY_SEPARATOR, $this->baseDir); + $filedir = explode(DIRECTORY_SEPARATOR, dirname(realpath($fname))); + $pos = 0; + $max = count($basedir); + while (isset($filedir[$pos]) && $filedir[$pos] == $basedir[$pos]) { + $pos++; + if ($pos == $max) { + break; + } + } + if ($pos == 0) { + return str_replace('\\', '/', $fname); + } + $rel = join('/', array_slice($filedir, $pos)); + if (!empty($rel)) { + $rel .= '/'; + } + if ($posclasses as $class => $file) { + $fname = $this->resolvePath($file); + $entries[] = "'". addslashes($class). "' => '$fname'"; + } + + $baseDir = ''; + if ($this->baseDir) { + $baseDir = $this->compat ? 'dirname(__FILE__) . ' : '__DIR__ . '; + } + + $replace = array_merge($this->variables, array( + '___CREATED___' => date( $this->dateformat, $this->timestamp ? $this->timestamp : time()), + '___CLASSLIST___' => join( ',' . $this->linebreak . $this->indent, $entries), + '___BASEDIR___' => $baseDir, + '___AUTOLOAD___' => 'autoload' . md5(serialize($entries)), + '___EXCEPTION___' => $this->throwExceptions ? 'true' : 'false', + '___PREPEND___' => $this->usePrepend ? 'true' : 'false' + )); + return str_replace(array_keys($replace), array_values($replace), $template); + } + + } + + + class AutoloadBuilderException extends \Exception { + + const TemplateNotFound = 1; + const InvalidTimestamp = 2; + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/CLI.php b/src/ncc/ThirdParty/theseer/Autoload/CLI.php new file mode 100644 index 0000000..454bc30 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/CLI.php @@ -0,0 +1,607 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + */ + +namespace TheSeer\Autoload { + + /** + * CLI interface to AutoloadRenderer / StaticRenderer + * + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + */ + class CLI { + + const RC_OK = 0; + const RC_EXEC_ERROR = 1; + const RC_PARAM_ERROR = 3; + const RC_LINT_ERROR = 4; + const RC_DUPLICATES_ERROR = 5; + + private $pharOption; + private $staticOption; + private $helpOption; + private $versionOption; + private $onceOption; + + /** + * @var Factory + */ + private $factory; + + + public function __construct(Factory $factory) { + $this->factory = $factory; + } + + /** + * Main executor method + * + * @return void + */ + public function run() { + + try { + + $this->preBootstrap(); + + $input = $this->setupInput(); + $input->process(); + + if ($input->getOption('help')->value === TRUE) { + $this->showVersion(); + $this->showUsage(); + exit(CLI::RC_OK); + } + + if ($input->getOption('version')->value === TRUE ) { + $this->showVersion(); + exit(CLI::RC_OK); + } + + $config = $this->configure($input); + $this->factory->setConfig($config); + if (!$config->isQuietMode()) { + $this->showVersion(); + } + $rc = $this->factory->getApplication()->run(); + exit($rc); + + } catch (CLIEnvironmentException $e) { + $this->showVersion(); + fwrite(STDERR, 'Sorry, but your PHP environment is currently not able to run phpab due to'); + fwrite(STDERR, "\nthe following issue(s):\n\n" . $e->getMessage() . "\n\n"); + fwrite(STDERR, "Please adjust your PHP configuration and try again.\n\n"); + exit(CLI::RC_EXEC_ERROR); + } catch (\ezcConsoleException $e) { + $this->showVersion(); + echo $e->getMessage() . "\n\n"; + $this->showUsage(); + exit(CLI::RC_PARAM_ERROR); + } catch (CollectorException $e) { + switch($e->getCode()) { + case CollectorException::InFileRedeclarationFound: + case CollectorException::RedeclarationFound: + case CollectorException::ParseErrror: { + $message = $e->getMessage(); + break; + } + default: { + $message = 'Unexpected error in collector process: ' . $e->getMessage() . "\n\nPlease report this as a bug.\n\n"; + } + } + $this->showVersion(); + fwrite(STDERR, $message . "\n\n"); + exit(CLI::RC_EXEC_ERROR); + } catch (\Exception $e) { + $this->showVersion(); + fwrite(STDERR, "\nError while processing request:\n - " . $e->getMessage()."\n"); + exit(CLI::RC_EXEC_ERROR); + } + + } + + /** + * @param \ezcConsoleInput $input + * + * @return \TheSeer\Autoload\Config + */ + private function configure(\ezcConsoleInput $input) { + $config = new Config($input->getArguments()); + if ($input->getOption('quiet')->value) { + $config->setQuietMode(TRUE); + } + if ($input->getOption('compat')->value) { + $config->setCompatMode(TRUE); + } + if ($input->getOption('tolerant')->value) { + $config->setTolerantMode(TRUE); + } + if ($output = $input->getOption('output')->value) { + $config->setOutputFile($output); + } + if ($input->getOption('phar')->value) { + $compression = \Phar::NONE; + if ($input->getOption('bzip2')->value === TRUE) { + $compression = \Phar::BZ2; + } else if ($input->getOption('gzip')->value === TRUE) { + $compression = \Phar::GZ; + } + $config->enablePharMode( + $compression, + $input->getOption('all')->value, + $input->getOption('key')->value, + $input->getOption('alias')->value + ); + $config->setVariable('PHAR', + $input->getOption('alias')->value ? $input->getOption('alias')->value : basename($output) + ); + if ($hashAlgorithm = $input->getOption('hash')->value) { + $config->setPharHashAlgorithm($hashAlgorithm); + } + } + + if ($input->getOption('cache')->value) { + $config->setCacheFile($input->getOption('cache')->value); + } + + if ($basedir = $input->getOption('basedir')->value) { + $config->setBaseDirectory($basedir); + } + + $include = $input->getOption('include')->value; + if (!is_array($include)) { + $include = array($include); + } + $config->setInclude($include); + + if ($exclude = $input->getOption('exclude')->value) { + if (!is_array($exclude)) { + $exclude = array($exclude); + } + $config->setExclude($exclude); + } + + $whitelist = $input->getOption('whitelist')->value; + if (!is_array($whitelist)) { + $whitelist = array($whitelist); + } + $config->setWhitelist($whitelist); + + if ($blacklist = $input->getOption('blacklist')->value) { + if (!is_array($blacklist)) { + $blacklist = array($blacklist); + } + $config->setBlacklist($blacklist); + } + + if ($input->getOption('static')->value) { + $config->setStaticMode(TRUE); + } + if ($input->getOption('once')->value) { + $config->setOnceMode(TRUE); + } + + if ($input->getOption('warm')->value) { + $config->setWarmMode(TRUE); + } + if ($input->getOption('reset')->value) { + $config->setResetMode(TRUE); + } + + if ($input->getOption('follow')->value) { + $config->setFollowSymlinks(TRUE); + } + + if ($input->getOption('prepend')->value) { + $config->enablePrepend(); + } + + if ($input->getOption('no-exception')->value) { + $config->disableExceptions(); + } + + $indent = $input->getOption('indent')->value; + if ($indent !== FALSE) { + $config->setIndent($indent); + } + if ($template = $input->getOption('template')->value) { + $config->setTemplate($template); + } + if ($linebreak = $input->getOption('linebreak')->value) { + $config->setLinebreak($linebreak); + } + if ($input->getOption('nolower')->value) { + $config->setLowercaseMode(FALSE); + } + if ($variables = $input->getOption('var')->value) { + foreach($variables as $var) { + if (strpos($var, '=')===FALSE) { + throw new \RuntimeException("Variable defintion '$var' is invalid and cannot be processed."); + } + list($name, $value) = explode('=', $var, 2); + $config->setVariable($name, $value); + } + } + + if ($input->getOption('paranoid')->value || !$input->getOption('trusting')->value) { + $config->setTrusting(FALSE); + } + + return $config; + } + + /** + * Helper to output version information + */ + protected function showVersion() { + static $shown = false; + if (!$shown) { + $shown = true; + echo Version::getInfoString() . "\n\n"; + } + } + + /** + * Helper to output usage information + */ + protected function showUsage() { + print << [...] + + -i, --include File pattern to include (default: *.php) + -e, --exclude File pattern to exclude + + --blacklist Blacklist classname or namespace (wildcards supported) + --whitelist Whitelist classname or namespace (wildcards supported) + + -b, --basedir Basedir for filepaths + -t, --template Path to code template to use + + -o, --output Output file for generated code (default: STDOUT) + + -p, --phar Create a phar archive (requires -o ) + --all Include all files in given directory when creating a phar + --alias Specify explicit internal phar alias filename (default: output filename) + --hash Force given hash algorithm (SHA-1, SHA-256 or SHA-512) (requires -p, conflicts with --key) + --bzip2 Compress phar archive using bzip2 (requires -p) (bzip2 required) + --gzip Compress phar archive using gzip (requires -p) (gzip required) + --key OpenSSL key file to use for signing phar archive (requires -p) (openssl required) + + -c, --compat Generate PHP 5.2 compatible code + -s, --static Generate a static require file + + -w, --warm Generate a static opcache warming file + --reset Add opcache reset call when generating opcache warming file + + -1, --prepend Register as first autoloader (prepend to stack, default: append) + -d, --no-exception Do not throw exception on registration problem (default: throw exception) + + -n, --nolower Do not lowercase classnames for case insensitivity + + -q, --quiet Quiet mode, do not output any processing errors or information + + --cache Enable caching and set filename to use for cache storage + + --follow Enables following symbolic links (not compatible with phar mode) + --format Dateformat string for timestamp + --linebreak Linebreak style (CR, CRLF or LF, default: LF) + --indent String used for indenting or number of spaces (default: 16 (compat 12) spaces) + + --tolerant Ignore Class Redeclarations in the same file + --once Use require_once instead of require when creating a static require file + + + --trusting Do not check mimetype of files prior to parsing (default) + --paranoid Do check mimetype of files prior to parsing + + --var name=foo Assign value 'foo' to variable 'name' to be used in (custom) templates + + --lint Run lint on generated code and exit + --lint-php PHP binary to use for linting (default: /usr/bin/php or c:\php\php.exe) + + -h, --help Prints this usage information + -v, --version Prints the version and exits + +EOF; + } + + /** + * @return \ezcConsoleInput + */ + protected function setupInput() { + $input = new \ezcConsoleInput(); + + $this->versionOption = $input->registerOption( new \ezcConsoleOption( 'v', 'version' ) ); + $this->versionOption->shorthelp = 'Prints the version and exits'; + $this->versionOption->isHelpOption = TRUE; + + $this->helpOption = $input->registerOption( new \ezcConsoleOption( 'h', 'help' ) ); + $this->helpOption->isHelpOption = TRUE; + $this->helpOption->shorthelp = 'Prints this usage information'; + + $input->registerOption( new \ezcConsoleOption( + '', 'cache', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'Enable cache and set cache filename' + )); + + $this->outputOption = $input->registerOption( new \ezcConsoleOption( + 'o', 'output', \ezcConsoleInput::TYPE_STRING, 'STDOUT', FALSE, + 'Output file for generated code (default: STDOUT)' + )); + + $this->pharOption = $input->registerOption( new \ezcConsoleOption( + 'p', 'phar', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Build a phar archive of directory contents', + NULL, + array( new \ezcConsoleOptionRule( $input->getOption( 'o' ) ) ) + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'all', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Add all files from src dir to phar', + NULL, + array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ) + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'alias', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'Provide explicit internal alias filename for phar', + NULL, + array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ) + )); + + $bzip2 = $input->registerOption( new \ezcConsoleOption( + '', 'bzip2', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Compress files phar with bzip2', + NULL, + array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ) + )); + + $gzip = $input->registerOption( new \ezcConsoleOption( + '', 'gzip', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Compress files phar with gzip', + NULL, + array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ), + array( new \ezcConsoleOptionRule( $bzip2 ) ) + )); + $bzip2->addExclusion(new \ezcConsoleOptionRule($gzip)); + + $input->registerOption( new \ezcConsoleOption( + '', 'key', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'Keyfile to use for signing phar archive', + NULL, + array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ) + )); + + $this->outputOption = $input->registerOption( new \ezcConsoleOption( + '', 'hash', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'Force given hash algorithm (SHA-1, SHA-256 or SHA-512) (requires -p)', + NULL, + array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ), + array( new \ezcConsoleOptionRule( $input->getOption( 'key' ) ) ) + )); + + $input->registerOption( new \ezcConsoleOption( + 'i', 'include', \ezcConsoleInput::TYPE_STRING, '*.php', TRUE, + 'File pattern to include (default: *.php)' + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'blacklist', \ezcConsoleInput::TYPE_STRING, NULL, TRUE, + 'Name pattern to exclude' + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'whitelist', \ezcConsoleInput::TYPE_STRING, '*', TRUE, + 'Name pattern to include (default: *)' + )); + + $input->registerOption( new \ezcConsoleOption( + 'e', 'exclude', \ezcConsoleInput::TYPE_STRING, NULL, TRUE, + 'File pattern to exclude' + )); + + $input->registerOption( new \ezcConsoleOption( + 'b', 'basedir', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'Basedir for filepaths' + )); + + $input->registerOption( new \ezcConsoleOption( + 't', 'template', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'Path to code template to use' + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'follow', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Enables following symbolic links', + NULL, + array(), + array( new \ezcConsoleOptionRule($this->pharOption) ) + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'format', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'Dateformat string for timestamp' + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'linebreak', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'Linebreak style (CR, CR/LF or LF)' + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'indent', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'String used for indenting (default: 3 spaces)' + )); + + $this->lintOption = $input->registerOption( new \ezcConsoleOption( + '', 'lint', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Run lint on generated code' + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'lint-php', \ezcConsoleInput::TYPE_STRING, NULL, FALSE, + 'PHP binary path for linting (default: /usr/bin/php or c:\\php\\php.exe)', + NULL, + array( new \ezcConsoleOptionRule( $input->getOption( 'lint' ) ) ) + )); + + $compat = $input->registerOption( new \ezcConsoleOption( + 'c', 'compat', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Generate PHP 5.2 compliant code' + )); + + $this->staticOption = $input->registerOption( new \ezcConsoleOption( + 's', 'static', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Build a static require file' + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'tolerant', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Ignore Class Redeclarations in the same file' + )); + + $trusting = $input->registerOption( new \ezcConsoleOption( + '', 'trusting', \ezcConsoleInput::TYPE_NONE, TRUE, FALSE, + 'Do not check mimetype of files prior to parsing' + )); + $paranoid = $input->registerOption( new \ezcConsoleOption( + '', 'paranoid', \ezcConsoleInput::TYPE_NONE, FALSE, FALSE, + 'Do check mimetype of files prior to parsing', + NULL, + array(), + array( new \ezcConsoleOptionRule($trusting) ) + )); + $trusting->addExclusion(new \ezcConsoleOptionRule($paranoid)); + + $this->onceOption = $input->registerOption( new \ezcConsoleOption( + '', 'once', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Use require_once in static require mode', + NULL, + array( new \ezcConsoleOptionRule( $input->getOption( 's' ) ) ) + )); + + $input->registerOption( new \ezcConsoleOption( + 'n', 'nolower', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Do not lowercase classnames for case insensitivity' + )); + + $input->registerOption( new \ezcConsoleOption( + 'q', 'quiet', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Run in quiet mode, no output' + )); + + $input->registerOption( new \ezcConsoleOption( + '1', 'prepend', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Prepend autoloader to stack', + NULL, + array(), + array( new \ezcConsoleOptionRule( $compat ) ) + )); + + $input->registerOption( new \ezcConsoleOption( + 'd', 'no-exception', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'Disable exceptions on registration error' + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'var', \ezcConsoleInput::TYPE_STRING, array(), TRUE, + 'Assign variable' + )); + + $warm = $input->registerOption( new \ezcConsoleOption( + 'w', 'warm', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'generate opcache warming file', + NULL, + array(), + array( + new \ezcConsoleOptionRule($this->pharOption), + new \ezcConsoleOptionRule($this->staticOption) + ) + )); + + $input->registerOption( new \ezcConsoleOption( + '', 'reset', \ezcConsoleInput::TYPE_NONE, NULL, FALSE, + 'add reset call to generated opcache warming file', + NULL, + array( + new \ezcConsoleOptionRule($warm) + ) + )); + + $input->argumentDefinition = new \ezcConsoleArguments(); + $input->argumentDefinition[0] = new \ezcConsoleArgument('directory'); + $input->argumentDefinition[0]->shorthelp = 'The directory to process.'; + $input->argumentDefinition[0]->multiple = TRUE; + + return $input; + } + + private function preBootstrap() { + $required = array('tokenizer', 'fileinfo'); + $missing = array(); + foreach($required as $test) { + if (!extension_loaded($test)) { + $missing[] = sprintf('ext/%s not installed/enabled', $test); + } + } + if (count($missing)) { + throw new CLIEnvironmentException( + join("\n", $missing), + CLIEnvironmentException::ExtensionMissing + ); + } + + if (extension_loaded('xdebug')) { + ini_set('xdebug.scream', 0); + ini_set('xdebug.max_nesting_level', 8192); + ini_set('xdebug.show_exception_trace', 0); + if (function_exists('xdebug_disable')) { // Xdebug v2 + xdebug_disable(); + } + } + + } + + } + + class CLIEnvironmentException extends \Exception { + const ExtensionMissing = 1; + } +} + diff --git a/src/ncc/ThirdParty/theseer/Autoload/Cache.php b/src/ncc/ThirdParty/theseer/Autoload/Cache.php new file mode 100644 index 0000000..74417b0 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/Cache.php @@ -0,0 +1,61 @@ +loadedEntries = $initialEntries; + } + + /** + * @param SourceFile $file + * + * @return bool + */ + public function hasResult(SourceFile $file) { + $pathname = $file->getPathname(); + if (!isset($this->loadedEntries[$pathname])) { + return false; + } + return $this->loadedEntries[$pathname]->getTimestamp() === $file->getMTime(); + } + + public function getResult(SourceFile $file) { + if (!$this->hasResult($file)) { + throw new CacheException('Entry not found'); + } + $pathname = $file->getPathname(); + $entry = $this->loadedEntries[$pathname]; + $this->usedEntries[$pathname] = $entry; + return $entry->getResult(); + } + + public function addResult(SourceFile $file, ParseResult $result) { + $this->usedEntries[$file->getPathname()] = new CacheEntry($file->getMTime(), $result); + } + + public function persist($fname) { + if (file_exists($fname)) { + unlink($fname); + } + file_put_contents($fname, serialize($this->usedEntries)); + } + } + + + class CacheException extends \Exception { + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/CacheEntry.php b/src/ncc/ThirdParty/theseer/Autoload/CacheEntry.php new file mode 100644 index 0000000..8002099 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/CacheEntry.php @@ -0,0 +1,38 @@ +timestamp = $timestamp; + $this->result = $result; + } + + /** + * @return ParseResult + */ + public function getResult() { + return $this->result; + } + + /** + * @return int + */ + public function getTimestamp() { + return $this->timestamp; + } + + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/CacheWarmingListRenderer.php b/src/ncc/ThirdParty/theseer/Autoload/CacheWarmingListRenderer.php new file mode 100644 index 0000000..7c0fce3 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/CacheWarmingListRenderer.php @@ -0,0 +1,39 @@ +addReset = $addReset; + $this->indent = $indent; + $this->linebreak = $linebreak; + } + + /** + * @return string + */ + public function render(array $list) { + $line = $this->indent . 'opcache_compile_file(___BASEDIR___\''; + $glue = '\');' . $this->linebreak . $line; + + $firstLine = $this->addReset ? $this->indent . 'opcache_reset();' . $this->linebreak : ''; + return $firstLine . $line . implode($glue, $list) . '\');'; + + } +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/CachingParser.php b/src/ncc/ThirdParty/theseer/Autoload/CachingParser.php new file mode 100644 index 0000000..1d7f5c8 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/CachingParser.php @@ -0,0 +1,39 @@ +cache = $cache; + $this->parser = $parser; + } + + /** + * Parse a given file for defintions of classes, traits and interfaces + * + * @param SourceFile $source file to process + * + * @return ParseResult + */ + public function parse(SourceFile $source) { + if ($this->cache->hasResult($source)) { + return $this->cache->getResult($source); + } + $result = $this->parser->parse($source); + $this->cache->addResult($source, $result); + return $result; + } + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/Collector.php b/src/ncc/ThirdParty/theseer/Autoload/Collector.php new file mode 100644 index 0000000..b74621d --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/Collector.php @@ -0,0 +1,96 @@ +parser = $parser; + $this->tolerantMode = $tolerantMode; + $this->trustingMode = $trustingMode; + $this->collectorResult = new CollectorResult($whitelist, $blacklist); + } + + public function getResult() { + return $this->collectorResult; + } + + public function processDirectory(\Iterator $sources) { + $worker = $this->trustingMode ? $sources : new PHPFilterIterator($sources); + foreach($worker as $file) { + $this->processFile($file); + } + } + + public function processFile(\SplFileInfo $file) { + if ($this->collectorResult->hasResultFor($file)) { + return; + } + try { + $parseResult = $this->parser->parse(new SourceFile($file->getRealPath())); + if ($parseResult->hasRedeclarations() && !$this->tolerantMode) { + throw new CollectorException( + sprintf( + "Duplicate (potentially conditional) definitions of the following unit(s) found:\n\n\tUnit(s): %s\n\tFile: %s", + join(', ', $parseResult->getRedeclarations()), + $file->getRealPath() + ), + CollectorException::InFileRedeclarationFound + ); + } + $this->collectorResult->addParseResult($file, $parseResult); + } catch(ParserException $e) { + throw new CollectorException( + sprintf( + "Could not process file '%s' due to parse errors: %s", + $file->getRealPath(), + $e->getMessage() + ), + CollectorException::ParseErrror, + $e + ); + } catch(CollectorResultException $e) { + throw new CollectorException( + $e->getMessage(), + CollectorException::RedeclarationFound + ); + } + } + } + + class CollectorException extends \Exception { + const ParseErrror = 1; + const RedeclarationFound = 2; + const InFileRedeclarationFound = 3; + } +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/CollectorResult.php b/src/ncc/ThirdParty/theseer/Autoload/CollectorResult.php new file mode 100644 index 0000000..7c79c94 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/CollectorResult.php @@ -0,0 +1,118 @@ +whitelist = $whitelist; + $this->blacklist = $blacklist; + } + + public function hasResultFor(\SplFileInfo $file) { + return isset($this->seenFiles[$file->getRealPath()]); + } + + public function addParseResult(\SplFileInfo $file, ParseResult $result) { + if (!$result->hasUnits()) { + return; + } + $filename = $file->getRealPath(); + $this->seenFiles[$filename] = true; + + foreach($result->getUnits() as $unit) { + if (!$this->accept($unit)) { + continue; + } + if (isset($this->units[$unit])) { + if (!isset($this->duplicates[$unit])) { + $this->duplicates[$unit] = array( $this->units[$unit] ); + } + $this->duplicates[$unit][] = $filename; + continue; + } + $this->units[$unit] = $filename; + $this->dependencies[$unit] = $result->getDependenciesForUnit($unit); + } + } + + public function hasUnits() { + return count($this->units) > 0; + } + + public function hasDuplicates() { + return count($this->duplicates) > 0; + } + /** + * @return array + */ + public function getDependencies() { + return $this->dependencies; + } + + /** + * @return array + */ + public function getUnits() { + return $this->units; + } + + /** + * @param string $unit + * + * @return bool + */ + private function accept($unit) { + foreach($this->blacklist as $entry) { + if (fnmatch($entry, $unit)) { + return false; + } + } + foreach($this->whitelist as $entry) { + if (fnmatch($entry, $unit)) { + return true; + } + } + return false; + } + + public function getDuplicates() { + return $this->duplicates; + } + + } + + class CollectorResultException extends \Exception { + const DuplicateUnitName = 1; + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/ComposerIterator.php b/src/ncc/ThirdParty/theseer/Autoload/ComposerIterator.php new file mode 100644 index 0000000..d543500 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/ComposerIterator.php @@ -0,0 +1,178 @@ +isFile() || !$composerFile->isReadable()) { + throw new ComposerIteratorException( + sprintf('Composer file "%s" not found or not readable', $composerFile->getPathname()), + ComposerIteratorException::InvalidComposerJsonFile + ); + } + $composerDir = dirname($composerFile->getRealPath()); + $composerData = json_decode(file_get_contents($composerFile->getRealPath()), true); + if (isset($composerData['require'])) { + foreach($composerData['require'] as $require => $version) { + if ($require === 'php' || strpos($require, 'ext-') === 0) { + continue; + } + $this->processRequire($composerDir, $require); + } + } + if (isset($composerData['autoload'])) { + $this->processAutoload($composerDir, $composerData['autoload']); + } + } + + private function processAutoload($baseDir, array $map) { + if (isset($map['classmap'])) { + foreach($map['classmap'] as $dir) { + $this->addDirectory($baseDir . '/' . $dir); + } + } + foreach(array('psr-0', 'psr-4') as $psr) { + if (isset($map[$psr])) { + foreach ($map[$psr] as $node => $dir) { + if ($dir === '') { + $this->addDirectory($baseDir); + continue; + } + if (is_array($dir)) { + foreach($dir as $d) { + $this->addDirectory($baseDir . '/' . $d); + } + + continue; + } + $this->addDirectory($baseDir . '/' . $dir); + } + } + } + } + + private function processRequire($basedir, $require) { + if (isset($this->seen[$require])) { + return; + } + $this->seen[$require] = true; + + $requireDir = $basedir . '/vendor/' . $require; + $jsonFile = $this->findComposerJson($requireDir); + if ($jsonFile === null) { + return; + } + $jsonData = json_decode(file_get_contents($jsonFile), true); + + if (isset($jsonData['require'])) { + foreach($jsonData['require'] as $entry => $version) { + if ($entry === 'php' || strpos($entry, 'ext-') === 0 || strpos($entry, 'lib-') === 0) { + continue; + } + $this->processRequire($basedir, $entry); + } + } + + if (isset($jsonData['autoload'])) { + $this->processAutoload($requireDir, $jsonData['autoload']); + return; + } + $this->addDirectory($requireDir); + } + + private function findComposerJson($dir) { + if (file_exists($dir . '/composer.json')) { + return $dir . '/composer.json'; + } + foreach(glob($dir . '/*', GLOB_ONLYDIR) as $subDir) { + $result = $this->findComposerJson($subDir); + if ($result !== NULL) { + return $result; + } + } + } + + private function addDirectory($dir) { + $dir = rtrim($dir, '/'); + if (!in_array($dir, $this->directories)) { + $this->directories[] = $dir; + } + } + + /** + * (PHP 5 >= 5.0.0)
+ * Return the current element + * + * @link http://php.net/manual/en/iterator.current.php + * @return mixed Can return any type. + */ + #[\ReturnTypeWillChange] + public function current() { + return $this->directories[$this->pos]; + } + + /** + * (PHP 5 >= 5.0.0)
+ * Move forward to next element + * + * @link http://php.net/manual/en/iterator.next.php + * @return void Any returned value is ignored. + */ + #[\ReturnTypeWillChange] + public function next() { + $this->pos++; + } + + /** + * (PHP 5 >= 5.0.0)
+ * Return the key of the current element + * + * @link http://php.net/manual/en/iterator.key.php + * @return mixed scalar on success, or null on failure. + */ + #[\ReturnTypeWillChange] + public function key() { + return $this->pos; + } + + /** + * (PHP 5 >= 5.0.0)
+ * Checks if current position is valid + * + * @link http://php.net/manual/en/iterator.valid.php + * @return boolean The return value will be casted to boolean and then evaluated. + * Returns true on success or false on failure. + */ + #[\ReturnTypeWillChange] + public function valid() { + return $this->pos < count($this->directories); + } + + /** + * (PHP 5 >= 5.0.0)
+ * Rewind the Iterator to the first element + * + * @link http://php.net/manual/en/iterator.rewind.php + * @return void Any returned value is ignored. + */ + #[\ReturnTypeWillChange] + public function rewind() { + $this->pos = 0; + } + + } + + class ComposerIteratorException extends \Exception { + const InvalidComposerJsonFile = 1; + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/Config.php b/src/ncc/ThirdParty/theseer/Autoload/Config.php new file mode 100644 index 0000000..ff2735a --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/Config.php @@ -0,0 +1,435 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + * + */ +namespace TheSeer\Autoload { + + class Config { + + private $quietMode = FALSE; + private $directories = array(); + private $outputFile = 'STDOUT'; + private $pharMode = FALSE; + private $include = array('*.php'); + private $exclude = array(); + private $whitelist = array('*'); + private $blacklist = array(); + private $baseDirectory = NULL; + private $template; + private $linebreak = "\n"; + private $indent; + private $lint = FALSE; + private $php; + private $compatMode = FALSE; + private $staticMode = FALSE; + private $warmMode = FALSE; + private $tolerant = FALSE; + private $trusting = TRUE; + private $once = FALSE; + private $reset = FALSE; + private $lowercase = TRUE; + private $dateFormat; + private $variable = array(); + private $pharCompression = 'NONE'; + private $pharKey; + private $pharAll = false; + private $pharAliasName = ''; + private $pharHashAlgorithm; + private $followSymlinks = false; + private $cacheFilename; + private $prepend = false; + private $exceptions = true; + + public function __construct(Array $directories) { + $this->directories = $directories; + $this->php = (PHP_OS === 'WIN' ? 'C:\php\php.exe' : '/usr/bin/php'); + } + + public function setBaseDirectory($baseDirectory) { + $this->baseDirectory = $baseDirectory; + } + + public function getBaseDirectory() { + if ($this->baseDirectory !== NULL) { + return realpath($this->baseDirectory); + } + if ($this->isPharMode()) { + $comparator = new PathComparator($this->directories); + return $comparator->getCommonBase(); + } + if ($this->outputFile != 'STDOUT') { + return realpath(dirname($this->outputFile) ?: '.'); + } + $tmp = $this->getDirectories(); + return realpath(is_dir($tmp[0]) ? $tmp[0] : (dirname($tmp[0]) ?: '.')); + } + + public function setCompatMode($compatMode) { + $this->compatMode = $compatMode; + } + + public function isCompatMode() { + return $this->compatMode === true; + } + + public function setDateFormat($dateFormat) { + $this->dateFormat = $dateFormat; + } + + public function getDateFormat() { + return $this->dateFormat; + } + + public function setExclude(Array $exclude) { + $this->exclude = $exclude; + } + + public function getExclude() { + return $this->exclude; + } + + public function setInclude(Array $include) { + $this->include = $include; + } + + public function getInclude() { + return $this->include; + } + + /** + * @return array + */ + public function getBlacklist() { + return $this->blacklist; + } + + /** + * @param array $blacklist + */ + public function setBlacklist($blacklist) { + $this->blacklist = $blacklist; + } + + /** + * @return array + */ + public function getWhitelist() { + return $this->whitelist; + } + + /** + * @param array $whitelist + */ + public function setWhitelist($whitelist) { + $this->whitelist = $whitelist; + } + + public function setIndent($indent) { + $this->indent = $indent; + } + + public function getIndent() { + if ($this->indent !== NULL) { + if (is_numeric($this->indent) && (int)$this->indent == $this->indent) { + return str_repeat(' ', (int)$this->indent); + } + return $this->indent; + } + if ($this->isStaticMode() || $this->isWarmMode()) { + return ''; + } + return str_repeat(' ', $this->isCompatMode() ? 12 : 16); + } + + public function setLinebreak($linebreak) { + $lbr = array('LF' => "\n", 'CR' => "\r", 'CRLF' => "\r\n" ); + if (isset($lbr[$linebreak])) { + $this->linebreak = $lbr[$linebreak]; + } else { + $this->linebreak = $linebreak; + } + } + + public function getLinebreak() { + return $this->linebreak; + } + + public function setLintMode($lint) { + $this->lint = (boolean)$lint; + } + + public function isLintMode() { + return $this->lint; + } + + public function setLowercaseMode($lowercase) { + $this->lowercase = (boolean)$lowercase; + } + + public function isLowercaseMode() { + return $this->lowercase; + } + + public function setOnceMode($once) { + $this->once = (boolean)$once; + } + + public function isOnceMode() { + return $this->once; + } + + public function setOutputFile($outputFile) { + $this->outputFile = $outputFile; + } + + public function getOutputFile() { + return $this->outputFile; + } + + public function enablePharMode($compression = 'NONE', $all = true, $key = NULL, $alias = NULL) { + $this->pharMode = true; + $this->pharCompression = $compression; + $this->pharAll = (boolean)$all; + $this->pharKey = $key; + $this->pharAliasName = $alias; + } + + public function isPharMode() { + return $this->pharMode; + } + + public function isPharAllMode() { + return $this->pharAll; + } + + public function getPharCompression() { + return $this->pharCompression; + } + + public function getPharKey() { + return $this->pharKey; + } + + public function getPharAliasName() { + return $this->pharAliasName; + } + + public function hasPharHashAlgorithm() { + return $this->pharHashAlgorithm !== null; + } + + /** + * @return string + */ + public function getPharHashAlgorithm() { + return $this->pharHashAlgorithm; + } + + /** + * @param string $pharHashAlgorithm + */ + public function setPharHashAlgorithm($pharHashAlgorithm) { + if (!in_array($pharHashAlgorithm, array('SHA-512','SHA-256','SHA-1'))) { + throw new \InvalidArgumentException( + sprintf('Algorithm %s not supported', $pharHashAlgorithm) + ); + } + $this->pharHashAlgorithm = $pharHashAlgorithm; + } + + public function setPhp($php) { + $this->php = $php; + } + + public function getPhp() { + return $this->php; + } + + public function setQuietMode($quietMode) { + $this->quietMode = (boolean)$quietMode; + } + + public function setStaticMode($staticMode) { + $this->staticMode = (boolean)$staticMode; + $this->warmMode = FALSE; + } + + public function isStaticMode() { + return $this->staticMode; + } + + public function setWarmMode($warmMode) { + $this->warmMode = (boolean)$warmMode; + $this->staticMode = FALSE; + } + + public function isWarmMode() { + return $this->warmMode; + } + + public function setResetMode($resetMode) { + $this->reset = (boolean)$resetMode; + } + + public function isResetMode() { + return $this->reset; + } + + public function setTemplate($template) { + $this->template = $template; + } + + public function getTemplate() { + $tplType = $this->isLowercaseMode() ? 'ci' : 'cs'; + $template = $this->template; + if ($template !== NULL) { + if (!file_exists($template)) { + $alternative = __DIR__.'/templates/'. $tplType .'/'.$template; + if (file_exists($alternative)) { + $template = $alternative; + } + $alternative .= '.php.tpl'; + if (file_exists($alternative)) { + $template = $alternative; + } + } + return $template; + } + + // determine auto template to use + $tplFile = 'default.php.tpl'; + if ($this->isCompatMode()) { + $tplFile = 'php52.php.tpl'; + } + + if ($this->isPharMode()) { + if ($this->isStaticMode()) { + $tplFile = 'staticphar.php.tpl'; + $tplType = '.'; + } else { + $tplFile = 'phar.php.tpl'; + } + } elseif ($this->isStaticMode() || $this->isWarmMode()) { + $tplFile = 'static.php.tpl'; + $tplType = '.'; + } + + return __DIR__.'/templates/'.$tplType.'/'.$tplFile; + + } + + public function setTolerantMode($tolerant) { + $this->tolerant = (boolean)$tolerant; + } + + public function isTolerantMode() { + return $this->tolerant; + } + + public function setTrusting($trusting) { + $this->trusting = (boolean)$trusting; + } + + public function setFollowSymlinks($followSymlinks) { + $this->followSymlinks = (boolean)$followSymlinks; + } + + public function isFollowSymlinks() { + return $this->followSymlinks; + } + + public function isTrustingMode() { + return $this->trusting; + } + + public function setVariable($name, $value) { + $this->variable[$name] = $value; + } + + public function getVariables() { + return $this->variable; + } + + public function isQuietMode() { + return $this->quietMode; + } + + public function getDirectories() { + $list = array(); + foreach($this->directories as $dir) { + if (is_file($dir) && basename($dir) == 'composer.json') { + foreach(new ComposerIterator(new \SplFileInfo($dir)) as $d) { + $list[] = $d; + } + } else { + foreach(glob($dir) as $match) { + $list[] = $match; + } + } + } + return $list; + } + + public function setCacheFile($filename) { + $this->cacheFilename = $filename; + } + + public function isCacheEnabled() { + return $this->cacheFilename !== NULL; + } + + public function getCacheFile() { + return $this->cacheFilename; + } + + public function enablePrepend() { + $this->prepend = true; + } + + public function usePrepend() { + return $this->prepend; + } + + public function disableExceptions() { + $this->exceptions = false; + } + + public function useExceptions() { + return $this->exceptions; + } + + } +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/DependencySorter.php b/src/ncc/ThirdParty/theseer/Autoload/DependencySorter.php new file mode 100644 index 0000000..a4e49b1 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/DependencySorter.php @@ -0,0 +1,100 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + */ + +namespace TheSeer\Autoload { + + /** + * Sorting classes by depdendency for static requires + * + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + */ + class ClassDependencySorter { + + private $classList; + private $dependencies; + + private $level; + + private $sorted = array(); + + public function __construct(Array $classes, Array $dependencies) { + $this->classList = $classes; + $this->dependencies = $dependencies; + } + + public function process() { + $this->level = 0; + foreach($this->classList as $class => $file) { + if (!in_array($class, $this->sorted)) { + $this->resolve($class); + } + } + + $res = array(); + foreach($this->sorted as $class) { + if (!isset($this->classList[$class])) { + continue; + } + $res[$class] = $this->classList[$class]; + } + return $res; + } + + private function resolve($class) { + $this->level++; + if ($this->level == 50) { + throw new ClassDependencySorterException("Can't resolve more than 50 levels of dependencies", ClassDependencySorterException::TooManyDependencyLevels); + } + if (isset($this->dependencies[$class])) { + foreach($this->dependencies[$class] as $depclass) { + if (!in_array($depclass, $this->sorted)) { + $this->resolve($depclass); + } + } + } + $this->sorted[] = $class; + $this->level--; + } + } + + class ClassDependencySorterException extends \Exception { + + const TooManyDependencyLevels = 1; + + } +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/Factory.php b/src/ncc/ThirdParty/theseer/Autoload/Factory.php new file mode 100644 index 0000000..2552082 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/Factory.php @@ -0,0 +1,242 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + * + */ +namespace TheSeer\Autoload { + + use TheSeer\DirectoryScanner\DirectoryScanner; + use TheSeer\DirectoryScanner\IncludeExcludeFilterIterator; + + class Factory { + + /** + * @var Config + */ + private $config; + + /** + * @var Cache + */ + private $cache; + + /** + * @param \TheSeer\Autoload\Config $config + */ + public function setConfig(Config $config) { + $this->config = $config; + } + + /** + * @return CLI + */ + public function getCLI() { + return new CLI($this); + } + + /** + * @return Application + */ + public function getApplication() { + return new Application($this->getLogger(), $this->config, $this); + } + + public function getLogger() { + return new Logger($this->config->isQuietMode()); + } + + /** + * @return Parser + */ + public function getParser() { + $parser = new Parser( + $this->config->isLowercaseMode() + ); + if (!$this->config->isCacheEnabled()) { + return $parser; + } + return new CachingParser( + $this->getCache(), + $parser + ); + } + + /** + * @return Cache + */ + public function getCache() { + if (!$this->cache instanceof Cache) { + $fname = $this->config->getCacheFile(); + if (file_exists($fname)) { + $data = unserialize(file_get_contents($fname)); + } else { + $data = array(); + } + $this->cache = new Cache($data); + } + return $this->cache; + } + + public function getCollector() { + return new Collector( + $this->getParser(), + $this->config->isTolerantMode(), + $this->config->isTrustingMode(), + $this->config->getWhitelist(), + $this->config->getBlacklist() + ); + } + + /** + * Get instance of DirectoryScanner with filter options applied + * + * @param bool $filter + * @return DirectoryScanner + */ + public function getScanner($filter = TRUE) { + $scanner = new DirectoryScanner; + if ($filter) { + $scanner->setIncludes($this->config->getInclude()); + $scanner->setExcludes($this->config->getExclude()); + } + if ($this->config->isFollowSymlinks()) { + $scanner->setFlag(\FilesystemIterator::FOLLOW_SYMLINKS); + } + return $scanner; + } + + public function getFilter(\Iterator $files) { + $filter = new IncludeExcludeFilterIterator($files); + $filter->setInclude($this->config->getInclude()); + $filter->setExclude($this->config->getExclude()); + return $filter; + } + + + public function getPharBuilder() { + $builder = new PharBuilder( + $this->getScanner(!$this->config->isPharAllMode()), + $this->config->getBaseDirectory() + ); + $builder->setCompressionMode($this->config->getPharCompression()); + foreach($this->config->getDirectories() as $directory) { + $builder->addDirectory($directory); + } + + return $builder; + } + + /** + * Helper to get instance of AutoloadRenderer with cli options applied + * + * @param CollectorResult $result + * + * @throws \RuntimeException + * @return \TheSeer\Autoload\AutoloadRenderer|\TheSeer\Autoload\StaticRenderer + */ + public function getRenderer(CollectorResult $result) { + $isStatic = $this->config->isStaticMode(); + $isPhar = $this->config->isPharMode(); + $isCompat = $this->config->isCompatMode(); + $isOnce = $this->config->isOnceMode(); + $isWarm = $this->config->isWarmMode(); + $isReset = $this->config->isResetMode(); + + if ($isWarm === TRUE) { + $renderer = new StaticRenderer( + $result->getUnits(), + $this->getCacheWarmingListRenderer($isReset) + ); + $renderer->setDependencies($result->getDependencies()); + $renderer->setPharMode($isPhar); + } else if ($isStatic === TRUE) { + $renderer = new StaticRenderer( + $result->getUnits(), + $this->getStaticRequireListRenderer($isOnce) + ); + $renderer->setDependencies($result->getDependencies()); + $renderer->setPharMode($isPhar); + } else { + $renderer = new AutoloadRenderer($result->getUnits()); + if ($this->config->usePrepend()) { + $renderer->prependAutoloader(); + } + if ($this->config->useExceptions()) { + $renderer->enableExceptions(); + } + } + + $renderer->setCompat($isCompat); + + $basedir = $this->config->getBaseDirectory(); + if (!$basedir || !is_dir($basedir)) { + throw new \RuntimeException("Given basedir '{$basedir}' does not exist or is not a directory"); + } + $renderer->setBaseDir($basedir); + + $format = $this->config->getDateFormat(); + if ($format) { + $renderer->setDateTimeFormat($format); + } + + $renderer->setIndent($this->config->getIndent()); + $renderer->setLineBreak($this->config->getLinebreak()); + + foreach($this->config->getVariables() as $name => $value) { + $renderer->setVariable($name, $value); + } + + return $renderer; + } + + private function getStaticRequireListRenderer($useOnce) { + return new StaticRequireListRenderer( + $useOnce, + $this->config->getIndent(), + $this->config->getLinebreak() + ); + } + + private function getCacheWarmingListRenderer($addReset) { + return new CacheWarmingListRenderer( + $addReset, + $this->config->getIndent(), + $this->config->getLinebreak() + ); + } + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/Logger.php b/src/ncc/ThirdParty/theseer/Autoload/Logger.php new file mode 100644 index 0000000..9a3637d --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/Logger.php @@ -0,0 +1,59 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + * + */ +namespace TheSeer\Autoload { + + class Logger { + + private $quiet = FALSE; + + /** + * @param bool $quietMode + */ + public function __construct($quietMode = FALSE) { + $this->quiet = $quietMode; + } + + public function log($message, $target = STDOUT) { + if ($this->quiet) { + return; + } + fwrite($target, $message); + } + + } +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/ParseResult.php b/src/ncc/ThirdParty/theseer/Autoload/ParseResult.php new file mode 100644 index 0000000..70e030b --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/ParseResult.php @@ -0,0 +1,64 @@ +units = $units; + $this->dependencies = $dependencies; + $this->redeclarations = $redeclarations; + } + + public function hasUnits() { + return count($this->units) > 0; + } + + public function hasRedeclarations() { + return count($this->redeclarations) > 0; + } + + /** + * + * @param string $unit + * + * @return array + */ + public function getDependenciesForUnit($unit) { + if (!isset($this->dependencies[$unit])) { + return array(); + } + return $this->dependencies[$unit]; + } + + /** + * @return \string[] + */ + public function getRedeclarations() { + return $this->redeclarations; + } + + /** + * @return \string[] + */ + public function getUnits() { + return $this->units; + } + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/Parser.php b/src/ncc/ThirdParty/theseer/Autoload/Parser.php new file mode 100644 index 0000000..9d2bf8b --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/Parser.php @@ -0,0 +1,598 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + */ + +namespace TheSeer\Autoload { + + // PHP 5.3 compat + define('T_TRAIT_53', 10355); + if (!defined('T_TRAIT')) { + define('T_TRAIT', -1); + } + + // PHP 8.0 forward compat + if (!defined('T_NAME_FULLY_QUALIFIED')) { + define('T_NAME_FULLY_QUALIFIED', -1); + define('T_NAME_QUALIFIED', -1); + } + + // PHP 8.1 forward compat + if (!defined('T_ENUM')) { + define('T_ENUM', -1); + } + + /** + * Namespace aware parser to find and extract defined classes within php source files + * + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + */ + class Parser implements ParserInterface { + + private $methodMap = array( + T_TRAIT => 'processClass', + T_TRAIT_53 => 'processClass', + T_CLASS => 'processClass', + T_ENUM => 'processEnum', + //T_CASE => 'processEnumCase', + T_INTERFACE => 'processInterface', + T_NAMESPACE => 'processNamespace', + T_USE => 'processUse', + '}' => 'processBracketClose', + '{' => 'processBracketOpen', + T_CURLY_OPEN => 'processBracketOpen', + T_DOLLAR_OPEN_CURLY_BRACES => 'processBracketOpen' + ); + + private $typeMap = array( + T_INTERFACE => 'interface', + T_CLASS => 'class', + T_ENUM => 'enum', + T_TRAIT => 'trait', + T_TRAIT_53 => 'trait' + ); + + private $caseInsensitive; + + private $tokenArray = array(); + + private $inNamespace = ''; + private $inUnit = ''; + + private $nsBracket = 0; + private $classBracket = 0; + + private $bracketLevel = 0; + private $aliases = array(); + + private $found = array(); + private $dependencies = array(); + private $redeclarations = array(); + + public function __construct($caseInsensitive = true) { + $this->caseInsensitive = $caseInsensitive; + } + + /** + * Parse a given file for defintions of classes, traits and interfaces + * + * @param SourceFile $source file to process + * + * @return ParseResult + */ + public function parse(SourceFile $source) { + $this->found = array(); + $this->redeclarations = array(); + $this->inNamespace = ''; + $this->aliases = array(); + $this->bracketLevel = 0; + $this->inUnit = ''; + $this->nsBracket = 0; + $this->classBracket = 0; + $this->tokenArray = $source->getTokens(); + $tokenCount = count($this->tokenArray); + $tokList = array_keys($this->methodMap); + for($t=0; $t<$tokenCount; $t++) { + $current = (array)$this->tokenArray[$t]; + + if ($current[0]===T_STRING && $current[1]==='trait' && T_TRAIT===-1) { + // PHP < 5.4 compat fix + $current[0] = T_TRAIT_53; + $this->tokenArray[$t] = $current; + } + if (!in_array($current[0], $tokList)) { + continue; + } + + $t = call_user_func(array($this, $this->methodMap[$current[0]]), $t); + } + return new ParseResult($this->found, $this->dependencies, $this->redeclarations); + } + + private function processBracketOpen($pos) { + $this->bracketLevel++; + return $pos + 1; + } + + private function processBracketClose($pos) { + $this->bracketLevel--; + if ($this->nsBracket !== 0 && $this->bracketLevel < $this->nsBracket) { + $this->inNamespace = ''; + $this->nsBracket = 0; + $this->aliases = array(); + } + if ($this->bracketLevel <= $this->classBracket) { + $this->classBracket = 0; + $this->inUnit = ''; + } + return $pos + 1; + } + + private function processClass($pos) { + if (!$this->classTokenNeedsProcessing($pos)) { + return $pos; + } + $list = array('{'); + $stack = $this->getTokensTill($pos, $list); + $stackSize = count($stack); + $classname = $this->inNamespace !== '' ? $this->inNamespace . '\\' : ''; + $extends = ''; + $extendsFound = false; + $implementsFound = false; + $implementsList = array(); + $implements = ''; + $mode = 'classname'; + foreach(array_slice($stack, 1, -1) as $tok) { + switch ($tok[0]) { + case T_COMMENT: + case T_DOC_COMMENT: + case T_WHITESPACE: { + break; + } + + case T_NAME_FULLY_QUALIFIED: + case T_NAME_QUALIFIED: + case T_STRING: { + $$mode .= $tok[1]; + break; + } + case T_NS_SEPARATOR: { + $$mode .= '\\'; + break; + } + case T_EXTENDS: { + $extendsFound = true; + $mode = 'extends'; + break; + } + case T_IMPLEMENTS: { + $implementsFound = true; + $mode = 'implements'; + break; + } + + case ',': { + if ($mode === 'implements') { + $implementsList[] = $this->resolveDependencyName($implements); + $implements = ''; + } + break; + } + default: { + throw new ParserException(sprintf( + 'Parse error while trying to process class definition (unexpected token "%s" in name).', + \token_name($tok[0]) + ), ParserException::ParseError + ); + } + } + } + if ($implements != '') { + $implementsList[] = $this->resolveDependencyName($implements); + } + if ($implementsFound && count($implementsList)==0) { + throw new ParserException(sprintf( + 'Parse error while trying to process class definition (extends or implements).' + ), ParserException::ParseError + ); + } + $classname = $this->registerUnit($classname, $stack[0][0]); + $this->dependencies[$classname] = $implementsList; + if ($extendsFound) { + $this->dependencies[$classname][] = $this->resolveDependencyName($extends); + } + $this->inUnit = $classname; + $this->classBracket = $this->bracketLevel + 1; + return $pos + $stackSize - 1; + } + + private function processEnum($pos) { + $list = array('{'); + $stack = $this->getTokensTill($pos, $list); + $stackSize = count($stack); + $enumName = $this->inNamespace !== '' ? $this->inNamespace . '\\' : ''; + $implementsFound = false; + $implementsList = array(); + $implements = ''; + $backType = ''; + $mode = 'enumName'; + foreach(array_slice($stack, 1, -1) as $tok) { + switch ($tok[0]) { + case T_COMMENT: + case T_DOC_COMMENT: + case T_WHITESPACE: { + break; + } + + case T_NAME_FULLY_QUALIFIED: + case T_NAME_QUALIFIED: + case T_STRING: { + $$mode .= $tok[1]; + break; + } + case T_NS_SEPARATOR: { + $$mode .= '\\'; + break; + } + case T_IMPLEMENTS: { + $implementsFound = true; + $mode = 'implements'; + break; + } + + case ':': { + $isBacked = true; + $mode = 'backType'; + break; + } + + case ',': { + if ($mode === 'implements') { + $implementsList[] = $this->resolveDependencyName($implements); + $implements = ''; + } + break; + } + + default: { + throw new ParserException(sprintf( + 'Parse error while trying to process class definition (unexpected token "%s" in name).', + is_int($tok[0]) ? \token_name($tok[0]) : $tok[0] + ), ParserException::ParseError + ); + } + } + } + + if ($implements != '') { + $implementsList[] = $this->resolveDependencyName($implements); + } + if ($implementsFound && count($implementsList)==0) { + throw new ParserException(sprintf( + 'Parse error while trying to process enum definition (implements).' + ), ParserException::ParseError + ); + } + + $enumName = $this->registerUnit($enumName, $stack[0][0]); + $this->dependencies[$enumName] = $implementsList; + + return $pos + $stackSize - 1; + } + + private function processInterface($pos) { + $list = array('{'); + $stack = $this->getTokensTill($pos, $list); + $stackSize = count($stack); + $next = $stack[1]; + if (is_array($next) && $next[0] === '(') { + // sort of inline use - ignore + return $pos + $stackSize; + } + + $name = $this->inNamespace != '' ? $this->inNamespace . '\\' : ''; + $extends = ''; + $extendsList = array(); + $mode = 'name'; + foreach(array_slice($stack, 1, -1) as $tok) { + switch ($tok[0]) { + case T_NS_SEPARATOR: + case T_NAME_QUALIFIED: + case T_NAME_FULLY_QUALIFIED: + case T_STRING: { + $$mode .= $tok[1]; + break; + } + case T_EXTENDS: { + $mode = 'extends'; + break; + } + case ',': { + if ($mode == 'extends') { + $extendsList[] = $this->resolveDependencyName($extends); + $extends = ''; + } + } + } + } + $name = $this->registerUnit($name, T_INTERFACE); + if ($extends != '') { + $extendsList[] = $this->resolveDependencyName($extends); + } + $this->dependencies[$name] = $extendsList; + $this->inUnit = $name; + return $pos + $stackSize - 1; + } + + private function resolveDependencyName($name) { + if ($name == '') { + throw new ParserException(sprintf( + 'Parse error while trying to process class definition (extends or implements).' + ), ParserException::ParseError + ); + } + if ($name[0] == '\\') { + $name = substr($name, 1); + } else { + $parts = explode('\\', $name, 2); + $search = $this->caseInsensitive ? strtolower($parts[0]) : $parts[0]; + $key = array_search($search, $this->aliases); + if (!$key) { + $name = ($this->inNamespace != '' ? $this->inNamespace . '\\' : ''). $name; + } else { + $name = $key; + if (isset($parts[1])) { + $name .= '\\' . $parts[1]; + } + } + } + if ($this->caseInsensitive) { + $name = strtolower($name); + } + return $name; + } + + private function registerUnit($name, $type) { + if ($name == '' || substr($name, -1) == '\\') { + throw new ParserException(sprintf( + 'Parse error while trying to process %s definition.', + $this->typeMap[$type] + ), ParserException::ParseError + ); + } + if ($this->caseInsensitive) { + $name = strtolower($name); + } + if (in_array($name, $this->found)) { + $this->redeclarations[] = $name; + } else { + $this->found[] = $name; + } + return $name; + } + + private function processNamespace($pos) { + $list = array(';', '{'); + $stack = $this->getTokensTill($pos, $list); + $stackSize = count($stack); + $newpos = $pos + $stackSize; + if ($stackSize < 3) { // empty namespace defintion == root namespace + $this->inNamespace = ''; + $this->aliases = array(); + return $newpos - 1; + } + $next = $stack[1]; + if (is_array($next) && ($next[0] === T_NS_SEPARATOR || $next[0] === '(')) { + // sort of inline use - ignore + return $newpos; + } + + $this->inNamespace = ''; + foreach(array_slice($stack, 1, -1) as $tok) { + $this->inNamespace .= $tok[1]; + } + $this->aliases = array(); + + return $pos + $stackSize - 1; + } + + private function processUse($pos) { + $list = array(';','('); + $stack = $this->getTokensTill($pos, $list); + $stackSize = count($stack); + $ignore = array( + '(', // closue use + T_CONST, // use const foo\bar; + T_FUNCTION // use function foo\bar; + ); + if (in_array($stack[1][0], $ignore)) { + return $pos + $stackSize - 1; + } + + if ($this->classBracket > 0) { + $this->parseUseOfTrait($stackSize, $stack); + + } else { + $this->parseUseAsImport($stack); + + } + return $pos + $stackSize - 1; + } + + private function getTokensTill($start, $list) { + $list = (array)$list; + $stack = array(); + $skip = array( + T_WHITESPACE, + T_COMMENT, + T_DOC_COMMENT + ); + $limit = count($this->tokenArray); + for ($t=$start; $t<$limit; $t++) { + $current = (array)$this->tokenArray[$t]; + if (in_array($current[0], $skip)) { + continue; + } + $stack[] = $current; + if (in_array($current[0], $list)) { + break; + } + } + return $stack; + } + + /** + * @param $stackSize + * @param $stack + */ + private function parseUseOfTrait($stackSize, $stack) { + $use = ''; + for ($t = 0; $t < $stackSize; $t++) { + $current = (array)$stack[$t]; + switch ($current[0]) { + case '{': { + // find closing bracket to skip contents + for ($x = $t + 1; $x < $stackSize; $x++) { + $tok = $stack[$x]; + if ($tok[0] == '}') { + $t = $x; + break; + } + } + break; + } + case ';': + case ',': { + $this->dependencies[$this->inUnit][] = $this->resolveDependencyName($use); + $use = ''; + break; + } + case T_NS_SEPARATOR: + case T_NAME_QUALIFIED: + case T_NAME_FULLY_QUALIFIED: + case T_STRING: { + $use .= $current[1]; + break; + } + } + } + } + + /** + * @param $stack + */ + private function parseUseAsImport($stack) { + $use = ''; + $alias = ''; + $mode = 'use'; + $group = ''; + $ignore = false; + foreach ($stack as $tok) { + $current = $tok; + switch ($current[0]) { + case T_CONST: + case T_FUNCTION: { + $ignore = true; + break; + } + case '{': { + $group = $use; + break; + } + case ';': + case ',': { + if (!$ignore) { + if ($alias == '') { + $nss = strrpos($use, '\\'); + if ($nss !== FALSE) { + $alias = substr($use, $nss + 1); + } else { + $alias = $use; + } + } + if ($this->caseInsensitive) { + $alias = strtolower($alias); + } + $this->aliases[$use] = $alias; + } + $alias = ''; + $use = $group; + $mode = 'use'; + $ignore = false; + break; + } + case T_NS_SEPARATOR: + case T_NAME_QUALIFIED: + case T_NAME_FULLY_QUALIFIED: + case T_STRING: { + $$mode .= $current[1]; + break; + } + case T_AS: { + $mode = 'alias'; + break; + } + } + } + } + + private function classTokenNeedsProcessing($position) { + + // PHP 5.5 has classname::class, reusing T_CLASS + if ($this->tokenArray[$position-1][0] == T_DOUBLE_COLON) { + return false; + } + + // PHP 7 has anonymous classes: $x = new class { ... } + if ($position > 2 && $this->tokenArray[$position-2][0] === T_NEW) { + return false; + } + + if ($this->tokenArray[$position + 1] === '(' || $this->tokenArray[$position + 2] === '(') { + return false; + } + + return true; + } + + } + + class ParserException extends \Exception { + + const ParseError = 1; + + } +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/ParserInterface.php b/src/ncc/ThirdParty/theseer/Autoload/ParserInterface.php new file mode 100644 index 0000000..2c951b8 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/ParserInterface.php @@ -0,0 +1,20 @@ + + * @copyright Arne Blankerts , All rights reserved. + */ +interface ParserInterface { + + /** + * Parse a given file for defintions of classes, traits and interfaces + * + * @param SourceFile $source file to process + * + * @return ParseResult + */ + public function parse(SourceFile $source); +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/PathComparator.php b/src/ncc/ThirdParty/theseer/Autoload/PathComparator.php new file mode 100644 index 0000000..ae628d4 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/PathComparator.php @@ -0,0 +1,45 @@ +directories[] = realpath($dir).'/'; + } + } + + public function getCommonBase() { + if (count($this->directories) == 0) { + return '/'; + } + $result = $this->directories[0]; + foreach($this->directories as $dir) { + $result = substr($dir, 0, $this->commonPrefix($result, $dir)); + } + return ($result ?: '/'); + } + + + private function commonPrefix( $s1, $s2 ) { + $l1 = strlen($s1); + $l2 = strlen($s2); + $i=0; + while($i < $l1 && $i < $l2 && $s1[$i] == $s2[$i]) { + $i++; + } + return strrpos(substr($s1, 0, $i), '/'); + } + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/PharBuilder.php b/src/ncc/ThirdParty/theseer/Autoload/PharBuilder.php new file mode 100644 index 0000000..b1dde20 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/PharBuilder.php @@ -0,0 +1,135 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + * + */ +namespace TheSeer\Autoload { + + use TheSeer\DirectoryScanner\DirectoryScanner; + + class PharBuilder { + + private $scanner; + private $compression; + private $key; + private $basedir; + private $aliasName; + private $signatureType; + + private $directories = array(); + + private $supportedSignatureTypes = array( + 'SHA-512' => \Phar::SHA512, + 'SHA-256' => \Phar::SHA256, + 'SHA-1' => \Phar::SHA1 + ); + + public function __construct(DirectoryScanner $scanner, $basedir) { + $this->scanner = $scanner; + $this->basedir = $basedir; + } + + public function setCompressionMode($mode) { + $this->compression = $mode; + } + + public function setSignatureType($type) { + if (!in_array($type, array_keys($this->supportedSignatureTypes))) { + throw new \InvalidArgumentException( + sprintf('Signature type "%s" not known or not supported by this PHP installation.', $type) + ); + } + $this->signatureType = $type; + } + + public function setSignatureKey($key) { + $this->key = $key; + } + + public function addDirectory($directory) { + $this->directories[] = $directory; + } + + public function setAliasName($name) { + $this->aliasName = $name; + } + + public function build($filename, $stub) { + if (file_exists($filename)) { + unlink($filename); + } + $phar = new \Phar($filename, 0, $this->aliasName != '' ? $this->aliasName : basename($filename)); + $phar->startBuffering(); + $phar->setStub($stub); + if ($this->key !== NULL) { + $privateKey = ''; + openssl_pkey_export($this->key, $privateKey); + $phar->setSignatureAlgorithm(\Phar::OPENSSL, $privateKey); + $keyDetails = openssl_pkey_get_details($this->key); + file_put_contents($filename . '.pubkey', $keyDetails['key']); + } else { + $phar->setSignatureAlgorithm($this->selectSignatureType()); + } + + $basedir = $this->basedir ? $this->basedir : $this->directories[0]; + foreach($this->directories as $directory) { + $phar->buildFromIterator($this->scanner->__invoke($directory), $basedir); + } + + if ($this->compression !== \Phar::NONE) { + $phar->compressFiles($this->compression); + } + $phar->stopBuffering(); + } + + private function selectSignatureType() { + if ($this->signatureType !== NULL) { + return $this->supportedSignatureTypes[$this->signatureType]; + } + $supported = \Phar::getSupportedSignatures(); + foreach($this->supportedSignatureTypes as $candidate => $type) { + if (in_array($candidate, $supported)) { + return $type; + } + } + + // Is there any PHP Version out there that does not support at least SHA-1? + // But hey, fallback to md5, better than nothing + return \Phar::MD5; + } + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/SourceFile.php b/src/ncc/ThirdParty/theseer/Autoload/SourceFile.php new file mode 100644 index 0000000..a2a722f --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/SourceFile.php @@ -0,0 +1,12 @@ +getRealPath())); + } + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/StaticListRenderer.php b/src/ncc/ThirdParty/theseer/Autoload/StaticListRenderer.php new file mode 100644 index 0000000..a026882 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/StaticListRenderer.php @@ -0,0 +1,10 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + */ + +namespace TheSeer\Autoload { + + /** + * Builds static require list for inclusion into projects + * + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + */ + class StaticRenderer extends AutoloadRenderer { + + private $dependencies; + private $phar; + private $require = 'require'; + + /** + * @var StaticListRenderer + */ + private $renderHelper; + + public function __construct(array $classlist, StaticListRenderer $renderHelper) { + parent::__construct($classlist); + $this->renderHelper = $renderHelper; + } + + /** + * Setter for Dependency Array + * @param array $dep Dependency Array from classfinder + */ + public function setDependencies(Array $dep) { + $this->dependencies = $dep; + } + + /** + * Toggle phar outut mode + * + * @param boolean $phar + */ + public function setPharMode($phar) { + $this->phar = (boolean)$phar; + } + + /** + * Toggle wether or not to use require_once over require + * + * @param boolean $mode + */ + public function setRequireOnce($mode) { + } + + + /** + * @param string $template + * + * @return string + */ + public function render($template) { + $baseDir = ''; + if ($this->phar) { + $baseDir = "'phar://". $this->variables['___PHAR___']."' . "; + } else if ($this->baseDir) { + $baseDir = $this->compat ? 'dirname(__FILE__) . ' : '__DIR__ . '; + } + + $entries = array(); + foreach($this->sortByDependency() as $fname) { + $entries[] = $this->resolvePath($fname); + } + + $replace = array_merge( + $this->variables, + array( + '___CREATED___' => date( $this->dateformat, $this->timestamp ? $this->timestamp : time()), + '___FILELIST___' => $this->renderHelper->render($entries), + '___BASEDIR___' => $baseDir, + '___AUTOLOAD___' => uniqid('autoload', true) + ) + ); + + return str_replace(array_keys($replace), array_values($replace), $template); + } + + /** + * Helper to sort classes/interfaces and traits based on their depdendency info + * + * @return array + */ + protected function sortByDependency() { + $sorter = new ClassDependencySorter($this->classes, $this->dependencies); + $list = $sorter->process(); + + return array_unique($list); + } + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/StaticRequireListRenderer.php b/src/ncc/ThirdParty/theseer/Autoload/StaticRequireListRenderer.php new file mode 100644 index 0000000..c6875f9 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/StaticRequireListRenderer.php @@ -0,0 +1,34 @@ +useOnce = $useOnce; + $this->indent = $indent; + $this->linebreak = $linebreak; + } + + /** + * @return string + */ + public function render(array $list) { + $require = (boolean)$this->useOnce ? 'require_once' : 'require'; + $require .= ' ___BASEDIR___\''; + $glue = '\';' . $this->linebreak . $this->indent . $require; + + return $this->indent . $require . implode($glue, $list) . '\';'; + } +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/VERSION b/src/ncc/ThirdParty/theseer/Autoload/VERSION new file mode 100644 index 0000000..c5b4f6e --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/VERSION @@ -0,0 +1 @@ +1.27.1 \ No newline at end of file diff --git a/src/ncc/ThirdParty/theseer/Autoload/Version.php b/src/ncc/ThirdParty/theseer/Autoload/Version.php new file mode 100644 index 0000000..a9f84f8 --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/Version.php @@ -0,0 +1,66 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Arne Blankerts nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Autoload + * @author Arne Blankerts + * @copyright Arne Blankerts , All rights reserved. + * @license BSD License + * + */ +namespace TheSeer\Autoload { + + class Version { + + private static $version = NULL; + + public static function getVersion() { + if (self::$version === NULL) { + self::$version = PHPAB_VERSION; + if (PHPAB_VERSION == '%development%') { + $cwd = getcwd(); + chdir(__DIR__); + $git = exec('command -p git describe --always --dirty 2>/dev/null', $foo, $rc); + chdir($cwd); + if ($rc === 0) { + self::$version = $git; + } + } + } + return self::$version; + } + + public static function getInfoString() { + return 'phpab ' . self::getVersion() . ' - Copyright (C) 2009 - ' . date('Y') . ' by Arne Blankerts and Contributors'; + } + + } + +} diff --git a/src/ncc/ThirdParty/theseer/Autoload/autoload.php b/src/ncc/ThirdParty/theseer/Autoload/autoload.php new file mode 100644 index 0000000..86691bf --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/autoload.php @@ -0,0 +1,153 @@ + '/../vendor/zetacomponents/base/src/base.php', + 'ezcbaseautoloadexception' => '/../vendor/zetacomponents/base/src/exceptions/autoload.php', + 'ezcbaseautoloadoptions' => '/../vendor/zetacomponents/base/src/options/autoload.php', + 'ezcbaseconfigurationinitializer' => '/../vendor/zetacomponents/base/src/interfaces/configuration_initializer.php', + 'ezcbasedoubleclassrepositoryprefixexception' => '/../vendor/zetacomponents/base/src/exceptions/double_class_repository_prefix.php', + 'ezcbaseexception' => '/../vendor/zetacomponents/base/src/exceptions/exception.php', + 'ezcbaseexportable' => '/../vendor/zetacomponents/base/src/interfaces/exportable.php', + 'ezcbaseextensionnotfoundexception' => '/../vendor/zetacomponents/base/src/exceptions/extension_not_found.php', + 'ezcbasefeatures' => '/../vendor/zetacomponents/base/src/features.php', + 'ezcbasefile' => '/../vendor/zetacomponents/base/src/file.php', + 'ezcbasefileexception' => '/../vendor/zetacomponents/base/src/exceptions/file_exception.php', + 'ezcbasefilefindcontext' => '/../vendor/zetacomponents/base/src/structs/file_find_context.php', + 'ezcbasefileioexception' => '/../vendor/zetacomponents/base/src/exceptions/file_io.php', + 'ezcbasefilenotfoundexception' => '/../vendor/zetacomponents/base/src/exceptions/file_not_found.php', + 'ezcbasefilepermissionexception' => '/../vendor/zetacomponents/base/src/exceptions/file_permission.php', + 'ezcbasefunctionalitynotsupportedexception' => '/../vendor/zetacomponents/base/src/exceptions/functionality_not_supported.php', + 'ezcbaseinit' => '/../vendor/zetacomponents/base/src/init.php', + 'ezcbaseinitcallbackconfiguredexception' => '/../vendor/zetacomponents/base/src/exceptions/init_callback_configured.php', + 'ezcbaseinitinvalidcallbackclassexception' => '/../vendor/zetacomponents/base/src/exceptions/invalid_callback_class.php', + 'ezcbaseinvalidparentclassexception' => '/../vendor/zetacomponents/base/src/exceptions/invalid_parent_class.php', + 'ezcbasemetadata' => '/../vendor/zetacomponents/base/src/metadata.php', + 'ezcbasemetadatapearreader' => '/../vendor/zetacomponents/base/src/metadata/pear.php', + 'ezcbasemetadatatarballreader' => '/../vendor/zetacomponents/base/src/metadata/tarball.php', + 'ezcbaseoptions' => '/../vendor/zetacomponents/base/src/options.php', + 'ezcbasepersistable' => '/../vendor/zetacomponents/base/src/interfaces/persistable.php', + 'ezcbasepropertynotfoundexception' => '/../vendor/zetacomponents/base/src/exceptions/property_not_found.php', + 'ezcbasepropertypermissionexception' => '/../vendor/zetacomponents/base/src/exceptions/property_permission.php', + 'ezcbaserepositorydirectory' => '/../vendor/zetacomponents/base/src/structs/repository_directory.php', + 'ezcbasesettingnotfoundexception' => '/../vendor/zetacomponents/base/src/exceptions/setting_not_found.php', + 'ezcbasesettingvalueexception' => '/../vendor/zetacomponents/base/src/exceptions/setting_value.php', + 'ezcbasestruct' => '/../vendor/zetacomponents/base/src/struct.php', + 'ezcbasevalueexception' => '/../vendor/zetacomponents/base/src/exceptions/value.php', + 'ezcbasewhateverexception' => '/../vendor/zetacomponents/base/src/exceptions/whatever.php', + 'ezcconsoleargument' => '/../vendor/zetacomponents/console-tools/src/input/argument.php', + 'ezcconsoleargumentalreadyregisteredexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/argument_already_registered.php', + 'ezcconsoleargumentexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/argument.php', + 'ezcconsoleargumentmandatoryviolationexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/argument_mandatory_violation.php', + 'ezcconsolearguments' => '/../vendor/zetacomponents/console-tools/src/input/arguments.php', + 'ezcconsoleargumenttypeviolationexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/argument_type_violation.php', + 'ezcconsoledialog' => '/../vendor/zetacomponents/console-tools/src/interfaces/dialog.php', + 'ezcconsoledialogabortexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/dialog_abort.php', + 'ezcconsoledialogoptions' => '/../vendor/zetacomponents/console-tools/src/options/dialog.php', + 'ezcconsoledialogvalidator' => '/../vendor/zetacomponents/console-tools/src/interfaces/dialog_validator.php', + 'ezcconsoledialogviewer' => '/../vendor/zetacomponents/console-tools/src/dialog_viewer.php', + 'ezcconsoleexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/exception.php', + 'ezcconsoleinput' => '/../vendor/zetacomponents/console-tools/src/input.php', + 'ezcconsoleinputhelpgenerator' => '/../vendor/zetacomponents/console-tools/src/interfaces/input_help_generator.php', + 'ezcconsoleinputstandardhelpgenerator' => '/../vendor/zetacomponents/console-tools/src/input/help_generators/standard.php', + 'ezcconsoleinputvalidator' => '/../vendor/zetacomponents/console-tools/src/interfaces/input_validator.php', + 'ezcconsoleinvalidoptionnameexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/invalid_option_name.php', + 'ezcconsoleinvalidoutputtargetexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/invalid_output_target.php', + 'ezcconsolemenudialog' => '/../vendor/zetacomponents/console-tools/src/dialog/menu_dialog.php', + 'ezcconsolemenudialogdefaultvalidator' => '/../vendor/zetacomponents/console-tools/src/dialog/validators/menu_dialog_default.php', + 'ezcconsolemenudialogoptions' => '/../vendor/zetacomponents/console-tools/src/options/menu_dialog.php', + 'ezcconsolemenudialogvalidator' => '/../vendor/zetacomponents/console-tools/src/interfaces/menu_dialog_validator.php', + 'ezcconsolenopositionstoredexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/no_position_stored.php', + 'ezcconsolenovaliddialogresultexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/no_valid_dialog_result.php', + 'ezcconsoleoption' => '/../vendor/zetacomponents/console-tools/src/input/option.php', + 'ezcconsoleoptionalreadyregisteredexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_already_registered.php', + 'ezcconsoleoptionargumentsviolationexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_arguments_violation.php', + 'ezcconsoleoptiondependencyviolationexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_dependency_violation.php', + 'ezcconsoleoptionexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option.php', + 'ezcconsoleoptionexclusionviolationexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_exclusion_violation.php', + 'ezcconsoleoptionmandatoryviolationexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_mandatory_violation.php', + 'ezcconsoleoptionmissingvalueexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_missing_value.php', + 'ezcconsoleoptionnoaliasexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_no_alias.php', + 'ezcconsoleoptionnotexistsexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_not_exists.php', + 'ezcconsoleoptionrule' => '/../vendor/zetacomponents/console-tools/src/structs/option_rule.php', + 'ezcconsoleoptionstringnotwellformedexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_string_not_wellformed.php', + 'ezcconsoleoptiontoomanyvaluesexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_too_many_values.php', + 'ezcconsoleoptiontypeviolationexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/option_type_violation.php', + 'ezcconsoleoutput' => '/../vendor/zetacomponents/console-tools/src/output.php', + 'ezcconsoleoutputformat' => '/../vendor/zetacomponents/console-tools/src/structs/output_format.php', + 'ezcconsoleoutputformats' => '/../vendor/zetacomponents/console-tools/src/structs/output_formats.php', + 'ezcconsoleoutputoptions' => '/../vendor/zetacomponents/console-tools/src/options/output.php', + 'ezcconsoleprogressbar' => '/../vendor/zetacomponents/console-tools/src/progressbar.php', + 'ezcconsoleprogressbaroptions' => '/../vendor/zetacomponents/console-tools/src/options/progressbar.php', + 'ezcconsoleprogressmonitor' => '/../vendor/zetacomponents/console-tools/src/progressmonitor.php', + 'ezcconsoleprogressmonitoroptions' => '/../vendor/zetacomponents/console-tools/src/options/progressmonitor.php', + 'ezcconsolequestiondialog' => '/../vendor/zetacomponents/console-tools/src/dialog/question_dialog.php', + 'ezcconsolequestiondialogcollectionvalidator' => '/../vendor/zetacomponents/console-tools/src/dialog/validators/question_dialog_collection.php', + 'ezcconsolequestiondialogmappingvalidator' => '/../vendor/zetacomponents/console-tools/src/dialog/validators/question_dialog_mapping.php', + 'ezcconsolequestiondialogoptions' => '/../vendor/zetacomponents/console-tools/src/options/question_dialog.php', + 'ezcconsolequestiondialogregexvalidator' => '/../vendor/zetacomponents/console-tools/src/dialog/validators/question_dialog_regex.php', + 'ezcconsolequestiondialogtypevalidator' => '/../vendor/zetacomponents/console-tools/src/dialog/validators/question_dialog_type.php', + 'ezcconsolequestiondialogvalidator' => '/../vendor/zetacomponents/console-tools/src/interfaces/question_dialog_validator.php', + 'ezcconsolestandardinputvalidator' => '/../vendor/zetacomponents/console-tools/src/input/validators/standard.php', + 'ezcconsolestatusbar' => '/../vendor/zetacomponents/console-tools/src/statusbar.php', + 'ezcconsolestatusbaroptions' => '/../vendor/zetacomponents/console-tools/src/options/statusbar.php', + 'ezcconsolestringtool' => '/../vendor/zetacomponents/console-tools/src/tools/string.php', + 'ezcconsoletable' => '/../vendor/zetacomponents/console-tools/src/table.php', + 'ezcconsoletablecell' => '/../vendor/zetacomponents/console-tools/src/table/cell.php', + 'ezcconsoletableoptions' => '/../vendor/zetacomponents/console-tools/src/options/table.php', + 'ezcconsoletablerow' => '/../vendor/zetacomponents/console-tools/src/table/row.php', + 'ezcconsoletoomanyargumentsexception' => '/../vendor/zetacomponents/console-tools/src/exceptions/argument_too_many.php', + 'theseer\\autoload\\application' => '/Application.php', + 'theseer\\autoload\\applicationexception' => '/Application.php', + 'theseer\\autoload\\autoloadbuilderexception' => '/AutoloadRenderer.php', + 'theseer\\autoload\\autoloadrenderer' => '/AutoloadRenderer.php', + 'theseer\\autoload\\cache' => '/Cache.php', + 'theseer\\autoload\\cacheentry' => '/CacheEntry.php', + 'theseer\\autoload\\cacheexception' => '/Cache.php', + 'theseer\\autoload\\cachewarminglistrenderer' => '/CacheWarmingListRenderer.php', + 'theseer\\autoload\\cachingparser' => '/CachingParser.php', + 'theseer\\autoload\\classdependencysorter' => '/DependencySorter.php', + 'theseer\\autoload\\classdependencysorterexception' => '/DependencySorter.php', + 'theseer\\autoload\\cli' => '/CLI.php', + 'theseer\\autoload\\clienvironmentexception' => '/CLI.php', + 'theseer\\autoload\\collector' => '/Collector.php', + 'theseer\\autoload\\collectorexception' => '/Collector.php', + 'theseer\\autoload\\collectorresult' => '/CollectorResult.php', + 'theseer\\autoload\\collectorresultexception' => '/CollectorResult.php', + 'theseer\\autoload\\composeriterator' => '/ComposerIterator.php', + 'theseer\\autoload\\composeriteratorexception' => '/ComposerIterator.php', + 'theseer\\autoload\\config' => '/Config.php', + 'theseer\\autoload\\factory' => '/Factory.php', + 'theseer\\autoload\\logger' => '/Logger.php', + 'theseer\\autoload\\parser' => '/Parser.php', + 'theseer\\autoload\\parseresult' => '/ParseResult.php', + 'theseer\\autoload\\parserexception' => '/Parser.php', + 'theseer\\autoload\\parserinterface' => '/ParserInterface.php', + 'theseer\\autoload\\pathcomparator' => '/PathComparator.php', + 'theseer\\autoload\\pharbuilder' => '/PharBuilder.php', + 'theseer\\autoload\\sourcefile' => '/SourceFile.php', + 'theseer\\autoload\\staticlistrenderer' => '/StaticListRenderer.php', + 'theseer\\autoload\\staticrenderer' => '/StaticRenderer.php', + 'theseer\\autoload\\staticrequirelistrenderer' => '/StaticRequireListRenderer.php', + 'theseer\\autoload\\version' => '/Version.php', + 'theseer\\directoryscanner\\directoryscanner' => '/../vendor/theseer/directoryscanner/src/directoryscanner.php', + 'theseer\\directoryscanner\\exception' => '/../vendor/theseer/directoryscanner/src/directoryscanner.php', + 'theseer\\directoryscanner\\filesonlyfilteriterator' => '/../vendor/theseer/directoryscanner/src/filesonlyfilter.php', + 'theseer\\directoryscanner\\includeexcludefilteriterator' => '/../vendor/theseer/directoryscanner/src/includeexcludefilter.php', + 'theseer\\directoryscanner\\phpfilteriterator' => '/../vendor/theseer/directoryscanner/src/phpfilter.php' + ); + } + $cn = strtolower($class); + if (isset($classes[$cn])) { + require __DIR__ . $classes[$cn]; + } + }, + true, + false +); +// @codeCoverageIgnoreEnd diff --git a/src/ncc/ThirdParty/theseer/Autoload/templates/ci/default.php.tpl b/src/ncc/ThirdParty/theseer/Autoload/templates/ci/default.php.tpl new file mode 100644 index 0000000..b007e0b --- /dev/null +++ b/src/ncc/ThirdParty/theseer/Autoload/templates/ci/default.php.tpl @@ -0,0 +1,21 @@ +