Initial Commit

This commit is contained in:
2019-11-21 12:25:31 +01:00
commit f4aabcb9b1
13959 changed files with 787761 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
<?php
namespace Gettext\Utils;
use Exception;
use Gettext\Translations;
abstract class FunctionsScanner
{
/**
* Scan and returns the functions and the arguments
*
* @return array
*/
abstract public function getFunctions();
/**
* Search for specific functions and create translations
*
* @param array $functions The gettext functions to search
* @param Translations $translations The translations instance where save the values
* @param string $file The filename used to the reference
*/
public function saveGettextFunctions(array $functions, Translations $translations, $file = '')
{
foreach ($this->getFunctions() as $function) {
list($name, $line, $args) = $function;
if (!isset($functions[$name])) {
continue;
}
switch ($functions[$name]) {
case '__':
if (!isset($args[0])) {
continue 2;
}
$original = $args[0];
$translation = $translations->insert('', $original);
break;
case 'n__':
if (!isset($args[1])) {
continue 2;
}
$original = $args[0];
$plural = $args[1];
$translation = $translations->insert('', $original, $plural);
break;
case 'p__':
if (!isset($args[1])) {
continue 2;
}
$context = $args[0];
$original = $args[1];
$translation = $translations->insert($context, $original);
break;
default:
throw new Exception('Not valid functions');
}
$translation->addReference($file, $line);
}
}
}

View File

@@ -0,0 +1,216 @@
<?php
namespace Gettext\Utils;
class JsFunctionsScanner extends FunctionsScanner
{
protected $code;
protected $status = array();
/**
* Constructor
*
* @param string $code The php code to scan
*/
public function __construct($code)
{
$this->code = $code;
}
/**
* {@inheritDoc}
*/
public function getFunctions()
{
$length = strlen($this->code);
$line = 1;
$buffer = '';
$functions = array();
$bufferFunctions = array();
$char = null;
for ($pos = 0; $pos < $length; $pos++) {
$prev = $char;
$char = $this->code[$pos];
$next = isset($this->code[$pos]) ? $this->code[$pos] : null;
switch ($char) {
case "\n":
++$line;
if ($this->status('line-comment')) {
$this->upStatus();
}
break;
case "/":
switch ($this->status()) {
case 'simple-quote':
case 'double-quote':
case 'line-comment':
break;
case 'block-comment':
if ($prev === '*') {
$this->upStatus();
}
break;
default:
if ($next === '/') {
$this->downStatus('line-comment');
} elseif ($next === '*') {
$this->downStatus('block-comment');
}
break;
}
break;
case "'":
switch ($this->status()) {
case 'simple-quote':
$this->upStatus();
break;
case 'line-comment':
case 'block-comment':
break;
default:
$this->downStatus('simple-quote');
break;
}
break;
case '"':
switch ($this->status()) {
case 'double-quote':
$this->upStatus();
break;
case 'line-comment':
case 'block-comment':
break;
default:
$this->downStatus('double-quote');
break;
}
break;
case '(':
switch ($this->status()) {
case 'double-quote':
case 'line-comment':
case 'block-comment':
break;
default:
if ($buffer && preg_match('/(\w+)$/', $buffer, $matches)) {
$this->downStatus('function');
array_unshift($bufferFunctions, array($matches[1], $line, array()));
$buffer = '';
continue 3;
}
break;
}
break;
case ')':
switch ($this->status()) {
case 'function':
if (($argument = self::prepareArgument($buffer))) {
$bufferFunctions[0][2][] = $argument;
}
if ($bufferFunctions) {
$functions[] = array_shift($bufferFunctions);
}
$buffer = '';
continue 3;
}
case ',':
switch ($this->status()) {
case 'function':
if (($argument = self::prepareArgument($buffer))) {
$bufferFunctions[0][2][] = $argument;
}
$buffer = '';
continue 3;
}
}
switch ($this->status()) {
case 'line-comment':
case 'block-comment':
break;
default:
$buffer .= $char;
break;
}
}
return $functions;
}
/**
* Get the current context of the scan
*
* @param null|string $match To check whether the current status is this value
*
* @return string|boolean
*/
protected function status($match = null)
{
$status = isset($this->status[0]) ? $this->status[0] : null;
if ($match) {
return ($status === $match);
}
return $status;
}
/**
* Add a new status to the stack
*
* @param string $status
*/
protected function downStatus($status)
{
array_unshift($this->status, $status);
}
/**
* Removes and return the current status
*
* @return string|null
*/
protected function upStatus()
{
return array_shift($this->status);
}
/**
* Prepares the arguments found in functions
*
* @param string $argument
*
* @return string
*/
protected static function prepareArgument($argument)
{
if ($argument && ($argument[0] === '"' || $argument[0] === "'")) {
if ($argument[0] === '"') {
$argument = str_replace('\\"', '"', $argument);
} else {
$argument = str_replace("\\'", "'", $argument);
}
return substr($argument, 1, -1);
}
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace Gettext\Utils;
class PhpFunctionsScanner extends FunctionsScanner
{
protected $tokens;
/**
* Constructor
*
* @param string $code The php code to scan
*/
public function __construct($code)
{
$this->tokens = token_get_all($code);
}
/**
* {@inheritDoc}
*/
public function getFunctions()
{
$count = count($this->tokens);
$bufferFunctions = array();
$functions = array();
for ($k = 0; $k < $count; $k++) {
$value = $this->tokens[$k];
//close the current function
if (is_string($value)) {
if ($value === ')' && isset($bufferFunctions[0])) {
$functions[] = array_shift($bufferFunctions);
}
continue;
}
//add an argument to the current function
if (isset($bufferFunctions[0]) && ($value[0] === T_CONSTANT_ENCAPSED_STRING)) {
$val = $value[1];
if ($val[0] === '"') {
$val = str_replace('\\"', '"', $val);
} else {
$val = str_replace("\\'", "'", $val);
}
$bufferFunctions[0][2][] = substr($val, 1, -1);
continue;
}
//new function found
if (($value[0] === T_STRING) && is_string($this->tokens[$k + 1]) && ($this->tokens[$k + 1] === '(')) {
array_unshift($bufferFunctions, array($value[1], $value[2], array()));
$k++;
continue;
}
}
return $functions;
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Gettext\Utils;
class StringReader
{
public $pos;
public $str;
public $strlen;
/**
* Constructor
*
* @param string $str The string to read
*/
public function __construct($str)
{
$this->str = $str;
$this->strlen = strlen($this->str);
}
/**
* Read and returns a part of the string
*
* @param int $bytes The number of bytes to read
*
* @return string
*/
public function read($bytes)
{
$data = substr($this->str, $this->pos, $bytes);
$this->seekto($this->pos + $bytes);
return $data;
}
/**
* Move the cursor to a specific position
*
* @param int $pos The amount of bytes to move
*
* @return int The new position
*/
public function seekto($pos)
{
$this->pos = ($this->strlen < $pos) ? $this->strlen : $pos;
return $this->pos;
}
}