Skip to content

Commit

Permalink
php-gettext#282 Added warning for dangling comments in the end of the…
Browse files Browse the repository at this point in the history
… file, added method getWarnings() and introduced new function (loadStringExtended) to avoid breaking the Gettext\Loader\Loader contract
  • Loading branch information
jonasraoni committed Jul 24, 2022
1 parent 3347517 commit d70bb1b
Showing 1 changed file with 41 additions and 20 deletions.
61 changes: 41 additions & 20 deletions src/Loader/StrictPoLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
*/
final class StrictPoLoader extends Loader
{
/** @var string[] */
public $warnings = [];

/** @var Translations */
private $translations;
/** @var Translation */
Expand All @@ -31,15 +28,26 @@ final class StrictPoLoader extends Loader
private $inPreviousComment;
/** @var bool */
private $throwOnWarning;
/** @var string[] */
private $warnings = [];

/**
* Generates a Translations object from a .po based string
*/
public function loadString(
public function loadString(string $string, Translations $translations = null): Translations
{
return $this->loadStringExtended(...func_get_args());
}

/**
* Generates a Translations object from a .po based string with extra options
*/
public function loadStringExtended(
string $string,
Translations $translations = null,
bool $throwOnWarning = false
): Translations {
): Translations
{
$this->data = $string;
$this->position = 0;
$this->translations = parent::loadString($string, $translations);
Expand All @@ -49,6 +57,9 @@ public function loadString(
$this->warnings = [];
for ($this->newEntry(); $this->getChar() !== null; $this->newEntry()) {
while ($this->readComment());
if ($this->getChar() === null) {
$this->addWarning("Comment ignored at the end of the string at byte {$this->position}");
}
$this->readContext();
$this->readOriginal();
if ($this->readPlural() && $this->readPluralTranslation(true)) {
Expand All @@ -65,6 +76,15 @@ public function loadString(
return $this->translations;
}

/**
* Retrieves the collected warnings
* @return string[]
*/
public function getWarnings(): array
{
return $this->warnings;
}

/**
* Prepares to parse a new translation
*/
Expand All @@ -88,9 +108,9 @@ private function saveEntry(): void
throw new Exception("Duplicated entry at byte {$this->position}");
}
if ($this->pluralCount !== null && $this->translation->getPlural() !== null
&& count($this->translation->getPluralTranslations()) < $this->pluralCount) {
$this->addWarning("The translation doesn't have all the {$this->pluralCount} "
. "plural forms at byte {$this->position}");
&& ($translationCount = count($this->translation->getPluralTranslations())) !== ($this->pluralCount - 1)) {
$this->addWarning("The translation has {$translationCount} plural forms, "
."while the header expects {$this->pluralCount} at byte {$this->position}");
}
$this->translations->add($this->translation);
}
Expand All @@ -114,7 +134,7 @@ private function readPreviousTranslationComment(): bool
/**
* Attempts to read whitespace characters, also might skip complex comment prologs when needed
*/
private function readWhiteSpace(): bool
private function readWhitespace(): bool
{
$position = $this->position;
while ((ctype_space($this->getChar() ?? '') && $this->nextChar())
Expand Down Expand Up @@ -258,11 +278,11 @@ private function readQuotedString(): string
}
}
if (!$this->readChar('"')) {
throw new Exception("Expected an ending quote at byte {$this->position}");
throw new Exception("Expected a closing quote at byte {$this->position}");
}
// Saves a checkpoint and attempts to read a new sequence
$checkpoint = $this->position;
$this->readWhiteSpace();
$this->readWhitespace();
}

return $data;
Expand All @@ -273,7 +293,7 @@ private function readQuotedString(): string
*/
private function readComment(): bool
{
$this->readWhiteSpace();
$this->readWhitespace();
if (!$this->readChar('#')) {
return false;
}
Expand Down Expand Up @@ -336,7 +356,7 @@ private function readComment(): bool
private function readIdentifier(string $identifier, bool $throwIfNotFound = false): ?string
{
$checkpoint = $this->position;
$this->readWhiteSpace();
$this->readWhitespace();
if (!$this->readString($identifier)) {
if ($throwIfNotFound) {
throw new Exception("Expected $identifier at byte {$this->position}");
Expand All @@ -345,7 +365,7 @@ private function readIdentifier(string $identifier, bool $throwIfNotFound = fals

return null;
}
$this->readWhiteSpace();
$this->readWhitespace();

return $this->readQuotedString();
}
Expand Down Expand Up @@ -392,11 +412,11 @@ private function readPlural(): bool
*/
private function readTranslation(): void
{
$this->readWhiteSpace();
$this->readWhitespace();
if (!$this->readString('msgstr')) {
throw new Exception("Expected msgstr at byte {$this->position}");
}
$this->readWhiteSpace();
$this->readWhitespace();
$data = $this->readQuotedString();
// The header might be surrounded by newlines
if ($this->translation->getOriginal() !== '') {
Expand All @@ -410,22 +430,23 @@ private function readTranslation(): void
*/
private function readPluralTranslation(bool $throwIfNotFound = false): bool
{
$this->readWhiteSpace();
$this->readWhitespace();
if (!$this->readString('msgstr')) {
if ($throwIfNotFound) {
throw new Exception("Expected indexed msgstr at byte {$this->position}");
}

return false;
}
$this->readWhiteSpace();
$this->readWhitespace();
if (!$this->readChar('[')) {
throw new Exception("Expected character \"[\" at byte {$this->position}");
}
$this->readWhitespace();
if (!strlen($index = $this->readNumber())) {
throw new Exception("Expected msgstr index at byte {$this->position}");
}
$this->readWhiteSpace();
$this->readWhitespace();
if (!$this->readChar(']')) {
throw new Exception("Expected character \"]\" at byte {$this->position}");
}
Expand All @@ -436,7 +457,7 @@ private function readPluralTranslation(bool $throwIfNotFound = false): bool
if (count($translations) !== (int) $index) {
throw new Exception("The msgstr has an invalid index at byte {$this->position}");
}
$this->readWhiteSpace();
$this->readWhitespace();
$data = $this->readQuotedString();
$translations[] = $data;
$this->checkNewLine($data, 'msgstr');
Expand Down

0 comments on commit d70bb1b

Please sign in to comment.