Ооочень странный косяк при загрузке .po файла

Главные вкладки

Аватар пользователя Azerot Azerot 1 апреля 2010 в 20:41

В общем беру .po файл с переводом Drupal. В нём есть строки вида:

msgid "1 comment"
msgid_plural "count comments"
msgstr[0] "count комментарий"
msgstr[1] "count комментария"
msgstr[2] "count комментариев"

Вроде бы всё пучком. Файл импортируется без ошибок и предупреждений, а вот этот перевод почему-то не работает! Более того, смотрел в базе в таблице locales_target нет перевода, а в таблице locales_source есть только строка "1 comment", а строки "count comments" нет!

Самое интересное, что если из .po файла выкинуть все остальные строки, оставив только те, что я привёл выше, то всё загружается и работает! Т.е. никаких синтаксических ошибок в этих строках нет. Более того, строка с переводом, которая идёт до этих строк - благополучно загружается и работает.

Нифига не понимаю! Ситуация проверена на двух абсолютно разных компьютерах с установкой Drupal 6.16 с нуля.
Понятное дело, что какой-то косяк в .po файле, но почему тогда при загрузке нет никаких ошибок или предупреждений?
Как отловить багу?

Комментарии

Аватар пользователя riyuzakki riyuzakki 1 апреля 2010 в 23:24

Во-первых, можно выложить файл целиком, авось кто найдет.
Во-вторых, убедиться, что все разделительные символы в пределах видимости соответствуют ожидаемым. Пробелы должны быть пробелами, а переносы строк переносами. А то всякое бывает.
В-третьих, на крайний случай попробовать применить метод Больцано-Вейерштрасса или, как его называл мой препод по матанализу, "как поймать льва в пустыне"

Аватар пользователя Azerot Azerot 2 апреля 2010 в 11:13

Ага. В общем похоже нарыл багу в Друпал'е.
Обратил внимание вот на что - у меня .po файл без комментариев, т.е. в нём нет ни одной строки, которая начинается с '#'. Взял перевод с drupaler.ru - он с комментариями и он работает. Удалил оттуда комментарии - и он тоже перестал работать.

Тогда я взялся смотреть код. Вся эта хрень лежит в includes/locale.inc
В итоге для меня стало шоковым открытием, что в locale.inc отрабатывают совершенно разные куски кода в случае, если в .po файле есть комментарии перед msgid и в случае, когда их нет. После чего найти разницу не составило труда. Можете полюбоваться в функции _locale_import_read_po видим кусок который работает в случае наличия комментариев перед msgid:

...
    if (!strncmp("#", $line, 1)) { // A comment
      if ($context == "COMMENT") { // Already in comment context: add
        $current["#"][] = substr($line, 1);
      }
      elseif (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) { // End current entry, start a new one
        _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
...

а вот этот кусок работает, когда их нет:

...    elseif (!strncmp("msgid", $line, 5)) {
      if ($context == "MSGSTR") {   // End current entry, start a new one
        _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
...

Как видим разница в том, что во втором случае почему-то не проверяется условие ($context == "MSGSTR_ARR"). Если исправить это, то всё работает как и должно.

Теперь вопрос к тем, кому интересна тема - куда с этим? Для начала хотелось бы подтверждения, что я прав - может кто-нибудь у себя попробовать? Проверять надо на msgid_plural строках, потому что именно они в результате этого косяка перестают работать.

Аватар пользователя PVasili PVasili 2 апреля 2010 в 13:50

Откуда нам знать, что вы удалили в файле?
Берите работающее, есть и "Компактный файл,...", зачем велики изобретать?

Аватар пользователя Azerot Azerot 2 апреля 2010 в 14:13

А вы сами-то её читали? Smile
Обратите внимание на строчку выделенную жирным

Quote:

Entries begin with some optional white space. Usually, when generated through GNU gettext tools, there is exactly one blank line between entries. Then comments follow, on lines all starting with the character #. There are two kinds of comments: those which have some white space immediately following the # - the translator comments -, which comments are created and maintained exclusively by the translator, and those which have some non-white character just after the # - the automatic comments -, which comments are created and maintained automatically by GNU gettext tools. Comment lines starting with #. contain comments given by the programmer, directed at the translator; these comments are called extracted comments because the xgettext program extracts them from the program's source code. Comment lines starting with #: contain references to the program's source code. Comment lines starting with #, contain flags; more about these below. Comment lines starting with #| contain the previous untranslated string for which the translator gave a translation.

All comments, of either kind, are optional.

Quote:
Откуда нам знать, что вы удалили в файле?

А зачем знать? Помоему проверяется просто. Берёте файл с drupaler.ru, удаляете из него комментарии. Загружаете в нулёвый английский друпал, после чего видно, что все msgid_plural не работают и даже более того отсутствуют в таблице locales_source. Не нужно верить мне на слово - проверьте сами.

Аватар пользователя riyuzakki riyuzakki 2 апреля 2010 в 14:51

"Azerot" wrote:
А вы сами-то её читали? :)

Да, полностью.
Обратите внимание на строчки выделенные жирным:
Quote:

white-space
# translator-comments
#. extracted-comments
#: reference...
#, flag...
#| msgid previous-untranslated-string
msgid untranslated-string
msgstr translated-string

Quote:

The comment lines beginning with #, are special because they are not completely ignored by the programs as comments generally are. The comma separated list of flags is used by the msgfmt program to give the user some better diagnostic messages.

Аватар пользователя Azerot Azerot 2 апреля 2010 в 15:02

Ну и что? Да поможет юзверям диагностировать то место откуда была извлечена строка и что? Где написано, что комментарии такого вида обязательны? Наоборот, я приводил вам строку где написано полностью обратное: All comments, of either kind, are optional.

И вообще, что вы мне пытаетесь доказать? Что в .po файле ДОЛЖНЫ быть комментарии строго перед каждой строкой msgid? (так это неверно из той же сепцификации) или что Drupal рассчитан на их наличие перед каждой строкой? Тогда во-первых, почему, если этого не требует специцикация, а во вторых почему этого нигде не написано явно?

Или вы сомневаетесь баг ли это на том основании, что никогда на него не попадали?

Аватар пользователя riyuzakki riyuzakki 2 апреля 2010 в 15:31

Я хочу доказать две вещи.
1.

"PVasili" wrote:
Откуда нам знать, что вы удалили в файле?

"Azerot" wrote:
А зачем знать? Помоему проверяется просто.

Нихрена не просто, потому что
2.
Quote:

white-space
# translator-comments
#. extracted-comments
#: reference...
#, flag...
#| msgid previous-untranslated-string
msgid untranslated-string
msgstr translated-string

Дело, скорее всего, в отсутствии не только комментариев, но и того самого white-space. Но Вы ведь не хотите описывать ситуацию целиком, выкладывать файл, а заставляете гадать и читать мысли. А про комменты я выделил, дабы показать что бездумно их грохать не стоит.

Аватар пользователя Azerot Azerot 2 апреля 2010 в 15:34

Если хотите, чтобы я выложил файл - я его подготовлю и выложу. Просто я предложил взять не мой, а другой, в котором вы уверены. Если вы настаиваете, что проблема в кривом файле - будет вам файл, попозже.
Комменты я грохаю совершенно не бездумно, а решая этим свои задачи и показываю вам на спецификацию, которая их наличия не требует, хотя и говорит, что оно будет полезно некоторым программам и пользователям.

Аватар пользователя Dan Dan 4 апреля 2010 в 12:33

"Azerot" wrote:
Как видим разница в том, что во втором случае почему-то не проверяется условие ($context == "MSGSTR_ARR"). Если исправить это, то всё работает как и должно.

Потому что контекст стоит в комментах.
Комменты быть должны - в них храниться служебная информация, о чём прямо стандарт и говорит.

Аватар пользователя Azerot Azerot 4 апреля 2010 в 13:57

Quote:
о чём прямо стандарт и говорит.

Цитату в студию из стандарта, где он об этом и говорит
И сразу доказательство от противного: если стандарт ТРЕБУЕТ наличия комментов, почему Drupal не говорит при загрузке о синтаксической ошибке в файле - отсутствует НЕОБХОДИМЫЙ комментарий? Тогда получается снова баг Smile

Аватар пользователя Azerot Azerot 10 ноября 2015 в 11:46

Так, ну вот собственно ваш файл как обещал.
Итак. Последовательность действий.
1. Ставим английский Drupal
2. Добавляем русский язык.
3. Идём на drupaler.ru (обратите внимание)!!!!!!!!!!!!!
4. Выбираем экспорт перевода Drupal 6.16 В КОМПАКТНОМ ВИДЕ!
5. Получаем файл БЕЗ комментариев как и у меня
6. Идём в админку и загружаем перевод. Вроде всё загружается без ошибок.
7. Создаём публикацию типа Story с любым названием и содержимым.
8. Добавляем к публикации комментарий с любым содержимым
9. Переходим на главную страницу где видим анонс нашей Story и под ним НЕПЕРЕВЕДЁННЫЙ
1 comment

Файл прикладываю, во избежание отмазок, что я мол не я и снова лошадь не моя.
Dan, если это баг (как вы настаиваете) в моём файле с переводом - бегом на drupaler.ru править некошерный перевод!