芝麻web文件管理V1.00
编辑当前文件:/home/sditechnicalteam/public_html/vendor/phpmyadmin/sql-parser/src/Tools/ContextGenerator.php
2, // reserved '(D)' => 8, // data type '(K)' => 16, // keyword '(F)' => 32, // function name ]; /** * Documentation links for each context. * * @var array */ public static $LINKS = [ 'MySql50000' => 'https://dev.mysql.com/doc/refman/5.0/en/keywords.html', 'MySql50100' => 'https://dev.mysql.com/doc/refman/5.1/en/keywords.html', 'MySql50500' => 'https://dev.mysql.com/doc/refman/5.5/en/keywords.html', 'MySql50600' => 'https://dev.mysql.com/doc/refman/5.6/en/keywords.html', 'MySql50700' => 'https://dev.mysql.com/doc/refman/5.7/en/keywords.html', 'MySql80000' => 'https://dev.mysql.com/doc/refman/8.0/en/keywords.html', 'MariaDb100000' => 'https://mariadb.com/kb/en/reserved-words/', 'MariaDb100100' => 'https://mariadb.com/kb/en/reserved-words/', 'MariaDb100200' => 'https://mariadb.com/kb/en/reserved-words/', 'MariaDb100300' => 'https://mariadb.com/kb/en/reserved-words/', 'MariaDb100400' => 'https://mariadb.com/kb/en/reserved-words/', 'MariaDb100500' => 'https://mariadb.com/kb/en/reserved-words/', 'MariaDb100600' => 'https://mariadb.com/kb/en/reserved-words/', ]; /** * The template of a context. * * Parameters: * 1 - name * 2 - class * 3 - link * 4 - keywords array */ public const TEMPLATE = <<<'PHP' * @phpstan-var non-empty-array
*/ public static $KEYWORDS = [ %4$s ]; } PHP; /** * Sorts an array of words. * * @param array $arr * * @return array */ public static function sortWords(array &$arr) { ksort($arr); foreach ($arr as &$wordsByLen) { ksort($wordsByLen); foreach ($wordsByLen as &$words) { sort($words, SORT_STRING); } } return $arr; } /** * Reads a list of words and sorts it by type, length and keyword. * * @param string[] $files * * @return array */ public static function readWords(array $files) { $words = []; foreach ($files as $file) { $words = array_merge($words, file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)); } $types = []; for ($i = 0, $count = count($words); $i !== $count; ++$i) { $type = 1; $value = trim($words[$i]); // Reserved, data types, keys, functions, etc. keywords. foreach (static::$LABELS_FLAGS as $label => $flags) { if (strstr($value, $label) === false) { continue; } $type |= $flags; $value = trim(str_replace($label, '', $value)); } // Composed keyword. if (strstr($value, ' ') !== false) { $type |= 2; // Reserved keyword. $type |= 4; // Composed keyword. } $len = strlen($words[$i]); if ($len === 0) { continue; } $value = strtoupper($value); if (! isset($types[$value])) { $types[$value] = $type; } else { $types[$value] |= $type; } } $ret = []; foreach ($types as $word => $type) { $len = strlen($word); if (! isset($ret[$type])) { $ret[$type] = []; } if (! isset($ret[$type][$len])) { $ret[$type][$len] = []; } $ret[$type][$len][] = $word; } return static::sortWords($ret); } /** * Prints an array of a words in PHP format. * * @param array $words the list of words to be formatted * @param int $spaces the number of spaces that starts every line * @param int $line the length of a line * * @return string */ public static function printWords($words, $spaces = 8, $line = 140) { $typesCount = count($words); $ret = ''; $j = 0; foreach ($words as $type => $wordsByType) { foreach ($wordsByType as $len => $wordsByLen) { $count = round(($line - $spaces) / ($len + 9)); // strlen("'' => 1, ") = 9 $i = 0; foreach ($wordsByLen as $word) { if ($i === 0) { $ret .= str_repeat(' ', $spaces); } $ret .= sprintf('\'%s\' => %s, ', $word, $type); if (++$i !== $count && ++$i <= $count) { continue; } $ret .= "\n"; $i = 0; } if ($i === 0) { continue; } $ret .= "\n"; } if (++$j >= $typesCount) { continue; } $ret .= "\n"; } // Trim trailing spaces and return. return str_replace(" \n", "\n", $ret); } /** * Generates a context's class. * * @param array $options the options that are used in generating this context * * @return string */ public static function generate($options) { if (isset($options['keywords'])) { $options['keywords'] = static::printWords($options['keywords']); } return sprintf(self::TEMPLATE, $options['name'], $options['class'], $options['link'], $options['keywords']); } /** * Formats context name. * * @param string $name name to format * * @return string */ public static function formatName($name) { /* Split name and version */ $parts = []; if (preg_match('/([^[0-9]*)([0-9]*)/', $name, $parts) === false) { return $name; } /* Format name */ $base = $parts[1]; switch ($base) { case 'MySql': $base = 'MySQL'; break; case 'MariaDb': $base = 'MariaDB'; break; } /* Parse version to array */ $versionString = $parts[2]; if (strlen($versionString) % 2 === 1) { $versionString = '0' . $versionString; } $version = array_map('intval', str_split($versionString, 2)); /* Remove trailing zero */ if ($version[count($version) - 1] === 0) { $version = array_slice($version, 0, count($version) - 1); } /* Create name */ return $base . ' ' . implode('.', $version); } /** * Builds a test. * * Reads the input file, generates the data and writes it back. * * @param string $input the input file * @param string $output the output directory */ public static function build($input, $output) { /** * The directory that contains the input file. * * Used to include common files. * * @var string */ $directory = dirname($input) . '/'; /** * The name of the file that contains the context. * * @var string */ $file = basename($input); /** * The name of the context. * * @var string */ $name = substr($file, 0, -4); /** * The name of the class that defines this context. * * @var string */ $class = 'Context' . $name; /** * The formatted name of this context. * * @var string */ $formattedName = static::formatName($name); file_put_contents( $output . '/' . $class . '.php', static::generate( [ 'name' => $formattedName, 'class' => $class, 'link' => static::$LINKS[$name], 'keywords' => static::readWords( [ $directory . '_common.txt', $directory . '_functions' . $file, $directory . $file, ] ), ] ) ); } /** * Generates recursively all tests preserving the directory structure. * * @param string $input the input directory * @param string $output the output directory */ public static function buildAll($input, $output) { $files = scandir($input); foreach ($files as $file) { // Skipping current and parent directories. if (($file[0] === '.') || ($file[0] === '_')) { continue; } // Building the context. sprintf("Building context for %s...\n", $file); static::build($input . '/' . $file, $output); } } }