Локализатор

Файлы

Текущая версия: 1.3.1

  • Собственно утилита, zip
    Внутри файл exe. Никакой установки не требуется. Программа распространяется свободно.
  • Загрузчик
    Эти два файла надо включить в свой проект. Опции компиляции большого значения не имеют, так как файлы очень простые. Никаких дополнительных библиотек (помимо стандартных) не требуется, код распространяется свободно.
  • Исходники
    Часть исходников проекта Localizer. Проект является частично Open Source - в той мере, в какой здесь выложены исходники. Эти фрагменты вы можете использовать на свое усмотрение. Для компиляции необходима моя библиотека GreenWin, исходники которой на данный момент не распространяются.

Общие сведения

Программа позволяет выполнять автоматизированную локализацию для проектов.

Достоинства:

  • Внесение изменений в локализацию не вызывает изменений в общем заголовочном файле и не приводит к масштабной перекомпиляции проекта.
  • Локализованные строки представляют собой указатели типа const char *. Это делает работу со строками максимально эффективной. Во время исполнения не происходит поиска строк по ключу или идентификатору, не вызываются никакие функции.
  • Процесс локализации сильно автоматизирован. После первоначального освоения от пользователя требуются минимальные трудозатраты на поддержание проекта в "локализованном" состоянии.

Недостатки:

  • Не поддерживается Unicode.
  • Программа средней сырости - бета-версия, ожидаются глюки и баги. Как обычно, никаких гарантий не дается.

Быстрый старт

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

У вас должен быть файл проекта Microsoft Visual Studio 2003, 2005... ну и, наверное, выше (не проверял). Либо должен быть просто список файлов в файле с расширением .lst. Определите в программе специальный префикс:

#define LS
- такой или другой, лишь бы уникальный. Пометьте этим префиксом все строки, подлежащие локализации (например LS"this string").

Вызовите программу-локализатор:

localizer -auto LS файл1 файл2...

Пример:

localizer -auto LS interval.vcproj interval.lst interval.loc interval.rus.loc interval_loc.cpp interval_loc.bin interval_loc.rus.bin

Среди параметров идет сначала префикс, потом файлы, связанные с локализацией. Смысл файла определяется его расширением:

  • *.lst - список файлов проекта (по одному имени на строку, относительные пути или просто имена файлов, если они в текущем каталоге).
  • *.vcproj - проект Visual Studio. Если он указан, то из .vcproj вытаскивается список файлов проекта и кладется в файл с расширением .lst.
  • *.loc (первый) - файл эталонной (английской) локализации в формате: идентификатор строки, содержимое строки, признак конца /END/. Если в списке параметров есть файл *.lst или *.vsproj, то этот *.loc-файл создается или модифицируется, согласно содержимому исходников проекта.
  • *.loc - файлы локализации на других языках. Если в списке есть еще файлы с расширением .loc, то считается, что это локализации на других языках. Они будут синхронизированы с эталоном, все новые строки, нуждающиеся в переводе, будут помечены маркером /!TRANSLATE!/.
  • *.cpp - этот файл надо будет добавить в свой проект, в нем определены идентификаторы строк.
  • *.bin (первый) - этот файл надо будет положить где-то рядом с готовой программой, в нем сами локализованные строки, которые будут подгружаться на runtime.
  • *.bin - если в списке есть еще файлы с расширением .bin, то считается, что они соответствуют локализациям на других языках.

После того, как вы вызвали локализатор в первый раз, в исходном коде проекта произойдут изменения. Вместо литералов вида

LS"this string"
появятся указатели типа (const char *) вида
LS__this_string
и объявления вида
extern const char *LS__this_string;

Теперь добавьте в проект файл *.cpp, упомянутый выше, и еще вот эти файлы загрузчика (всего в проект надо добавить три файла - два *.cpp и один *.h).

Добавьте куда-нибудь в начало загрузку строк из одного из сгенерированных *.bin-файлов (по вашему выбору) примерно вот так:

#include "localizer.h"
...
static Localizer localizer;
...
extern const char **LS_all[];
if (!localizer.load("interval_loc.bin", LS_all))
    (обработка ошибки)

Теперь добейтесь успешной компиляции вашего проекта. Все, на этом локализация закончена.

После этого вы можете время от времени переводить строки в *.loc-файлах (в дополнительных, в эталонном переводить не надо) или исправлять их и запускать локализатор с теми же параметрами. Также вы можете добавлять в программу новые модули и помечать в них строки префиксом, и при очередном запуске локализатора эти строки будут извлечены и распределены по файлам локализации.

Рекомендуется такой порядок действий. Сначала программируете как обычно, в кавычках пишете текст не английском и помечаете префиксом то, что потребует перевода. Когда таких строк накопится много, вызываете локализатор. Потом смотрите в дополнительные файлы и переводите все, что помечено маркером /!TRANSLATE!/, убирая маркеры. Потом еще раз запускаете локализатор и компилируете проект.

Вот и весь "быстрый старт". Дальше идут детали и подробности.

Префикс

Префикс - это короткий идентификатор, например, дальше для определенности используется префикс LS. По префиксу локализатор распознает локализованные строки и строки, подлежащие локализации.

Префикс однозначно определяет локализацию. В одной программе может быть несколько локализаций, которые отличаются по префиксам.

Префикс должен быть объявлен где-нибудь в общем хэдере как пустой define:

#define LS

Файлы

Следующие файлы используются для локализатора.

[proj]. Файл проекта vcproj. Нужен для того, чтобы извлечь из него список файлов проекта.

[lst]. Список файлов, подлежащих локализации (просто имена файлов, каждый на отдельной строке). Расширение .lst. Обычно извлекается локализатором из [proj].

[src]. Исходные файлы проекта. Обычные исходники, в которых могут быть локализованные строки. Локализатор сканирует такие файлы, а их имена берет из [lst].

[loc]. Главный файл локализации. Расширение .loc. Этот файл содержит идентификаторы локализованных строк и их содержимое. Формат файла:

/<комментарий>
<идентификатор>
<содержимое>
/END/
/<комментарий>
<идентификатор>
<содержимое>
/END/
...

Идентификатор - это последовательность символов, среди которых могут быть латинские буквы, цифры и знак подчеркивания. Последовательность может начинаться с цифры. Внутри программы к этим идентификаторам добавляется префикс и два знака подчеркивания. Например, идентификатор 'OK' превращается в 'LS__OK'.

Содержимое - произвольная строка. Здесь допускаются любые символы, включая '\0', переводы строк и прочее. При загрузке в конец будет добавлен еще один '\0', так что вручную этого делать не нужно.

Комментарий - необязательная строка комментария. Каждая строка может сопровождаться одним комметарием перед ней. Также программа может генерировать специальные комментарии вида:

/!текст!/

Строка "\r\n/END/\r\n" - признак конца содержимого, такая строка не может присутствовать в содержимом.

Выше приведен так называемый "raw"-формат файла. В строках все спец-символы, включая нулевой, записываются "as is". Это может быть иногда удобно, а иногда - нет (не всякий текстовый редактор сможет корректно работать с таким файлом). Можно использовать альтернативный "escape"-формат:

/<комментарий>
<идентификатор>=<содержимое>
/<комментарий>
<идентификатор>=<содержимое>
...

Здесь содержимое строки кодируется обычной C/C++ строкой с применением escape-символа "\". Обрамляющие кавычки не нужны, пробелы вокруг разделителя "=" оставлять не следует. При желании в одном файле локализации можно смешивать строки в обоих форматах.

Главный файл локализации должен содержать содержимое локализованных строк для базового языка. Очень желательно, чтобы базовым языком был английский. Тогда локализатор сможет автоматически сгенерировать осмысленные идентификаторы, приемлемые с точки зрения синтаксиса C++. Также можно использовать русский язык в кодировке Windows-1251, в этом случае идентификаторы будут сгенерированы с применением транслита.

[loc+]. Дополнительный файл локализации. Расширение .loc. Все аналогично [loc], но содержимое строк идет на другом языке (перевод). Идентификаторы переводить нельзя. Дополнительные файлы локализации получаются из [loc] и затем синхронизируются с ним.

[cpp]. cpp-файл локализации. Расширение .cpp. Этот файл содержит все локализованные строки - по отдельности и списком. Его надо включить в проект. Для всех языков применяется один и тот же cpp-файл локализации.

[bin]. Бинарный файл локализации. Расширение .bin. В нем находится содержимое строк. Для каждого языка - свой [bin]. Бинарый файл должен соответствовать [cpp], порядок строк и количество строк в нем те же самые.

Формат:

DWORD N - число строк
DWORD SZ - длина блока строк
DWORD OFFSET[N] - блок смещений - смещение каждой из N строк в блоке строк относительно начала блока
BYTE DATA[SZ] - блок строк

Локализованная строка

Локализованная строка - это просто указатель const char *, с которым работают как обычно. При запуске программы локализованные строки загружаются из [bin], и каждый указатель настраиваются на нужную точку в памяти. Конкретнее из [bin] в память грузится 'блок строк', а j-й указатель настраивается на адрес: DATA + OFFSET[j]

Имена локализованных строк имеют вид: <префикс>__<идентификатор> Например: LS__OK, LS__It_is_a__0.

Массив локализованных строк

Это статический массив указателей на указатели на локализованные строки. Он имеет тип const char **[] и используется только один раз - при загрузке локализации на старте программы.

Его имя имеет вид: <префикс>_all.

Например: LS_all.

Определен в [cpp].

Определение локализованных строк

Все локализованные строки данной локализации определены в [cpp]. Этот файл надо включить в проект. В том же файле определен и массив локализованных строк.

Объявление (декларация) локализованных строк

Было решено отказаться от какого-либо хэдера, где перечислены имена локализованных строк. Такой хэдер пришлось бы включать во многие файлы и малейшие изменения в нем приводили бы к перекомпилированию значительной части проекта. Вместо этого используются объявления 'extern' в каждом файле, но их не надо добавлять вручную, это делает локализатор. Единственное (и однократное) исключение - объявление массива локализованных строк перед вызовом Localizer::load (см. ниже).

Строки, подлежащие локализации

Имеют вид: <префикс><литерал>

Например: LS"OK"

Таким методом надо отметить те строки, которые подлежат локализации (этот процесс отчасти автоматизирован).

Исходник с такими отметками нормально компилируется, поскольку LS - это #define, определенный как пустышка. Таким образом, можно заранее отмечать места локализации, но саму локализацию отложить до подходящего момента.

Если в проекте есть несколько частей, для каждой из которых свой модуль локализации, то надо сделать разные префиксы для них.

Загрузка локализации приложения

Локализация собственной программы загружается через объект Localizer, функцию load.

Объект Localizer должен существовать, пока требуются локализованные строки, поэтому лучше его сделать статическим.

1-й параметр функции - имя бинарного файла локализации.

2-й параметр функции - массив локализованных строк (упоминается выше и см. пример ниже).

Возвращаемое значение - true при успехе, false при ошибке. Вызов load надо поместить в начало программы.

Пример:

#include "localizer.h"
...
static Localizer localizer;
...
extern const char **LSI_all[];
if (!localizer.load("interval_loc.bin", LSI_all))
{
	printf("Error of localization.\n")
    return -1;
}

В этом примере программа использует локализацию с префиксом LSI и загружает ее из файла interval_loc.bin.

Автоматизация процесса локализации по шагам

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

Шаг 0. Добавить localizer.cpp и localizer.h в проект.

Шаг 1. Придумать уникальный префикс, который будет идентифицировать локализацию. Выберите короткий префикс, т.к. его придется писать много раз. Но это должен быть униакльный идентификатор, который не используется в программе.

Шаг 2. Определить префикс. Например:

#define LSI

Эту директиву надо вставить в какой-то хэдер, желательно 'precompiled'.

Составление списка файлов, подлежащих локализации

Шаг 3. Теперь надо составить список файлов, подлежащих локализации. В список должны войти все файлы проекта, где встречается или может встретиться в будущем метка LS. Список можно составить вручную или автоматически.

Можно использовать стандартную команду dir, например: dir /B *.cpp >my.pr.loc

Но лучше использовать сам локализатор, указав ему путь к файлу проекта *.vcproj. Это лучше, поскольку тогда в список не попадут случайные файлы - которые находятся в папке, но не относятся к проекту, либо в проекте, но исключены из сборки. Их пришлось бы убирать вручную.

Пример вызова локализатора для составления списка:

localizer.exe -list greenwin.vcproj greenwin.lst

Формат:

localizer.exe -list [proj] [lst]

Шаг 4. Указать строки, подлежащие локализации. Надо выполнить поиск по всем файлам проекта литералов (по символу кавычки) и отметить префиксом все литералы, которые надо локализовать. Конечно, можно отметить так вообще все строки, но это излишне. Следует отмечать только те строки, которые могут выглядеть по-разному на разных языках.

Процесс можно ускорить, применив локализатор:

localizer.exe -mark LS greenwin.lst

Формат:

localizer.exe -mark префикс [lst]

При этом префиксы будут автоматически расставлены перед всеми строками, содержащими латинские буквы, и останется только удалить лишнее.

Создание главного файла локализации

Шаг 5. Создание главного файла локализации:

localizer.exe -get LS greenwin.lst greenwin.loc

Формат:

localizer.exe -get префикс [lst] [loc]

На этом этапе происходит анализ исходников [src] (из списка [lst]), и сбор строк, подлежащих локализации в главный файл локализации [loc]. Весь процесс полностью автоматический.

Возможны следующие ситуации:

- Главный файл локализации [loc] еще не создан. Тогда он считается пустым и создается заново.

- Главный файл локализации [loc] уже есть. Тогда его содержимое загружается и сравнивается с результатами сканирования.

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

- При сканировании обнаружена уже локализованная строка, которая есть в файле локализации. Это нормальная ситуация. Значит, файл уже локализовывался раньше, и содержимое сторки хранится в [loc].

- При сканировании обнаружена строка, подлежащая локализации. Ее содержимое эквивалентно одной из строк в [loc]. Это нормальная ситуация. Для всех одинаковых строк используется одно хранилище, так что эта строка просто будет ссылаться на существующую строку, и для нее будет использован тот же идентификатор.

- При сканировании обнаружена строка, подлежащая локализации. Ее содержимое непохоже ни на одну из строк в [loc]. Это нормальная ситуация. Для такой строки будет автоматически сгенерирован уникальный идентификатор (по буквам и цифрам из начала строки) и ее содержимое будет сохранено в [loc].

- В [loc] есть строка, которая не упоминается в проекте, и ни одна из строк, подлежащих локализации, не содержит такого текста. Причина может быть связана с тем, что эта строка была найдена раньше, но с тех пор файл, из которого она была взята, был удален. Или был удален фрагмент текста, откуда она взята. Такие строки будут удалены из [loc], чтобы не занимать лишнее место. Будет выдано предупреждение о том, что строка удалена.

Шаг 6. Корректировка главного файла локализации.

Теперь вы можете внести в [loc] ручные исправления, если они нужны. В основном это имеет смысл для автоматически сгенерированных идентификаторов - если они недостаточно "красивы". Если данный идентификатор уже используется в программе, его надо исправить и в [src]. При исправлении соблюдайте уникальность идентификаторов, иначе программа выдаст. А вот сортировку можно не делать, она будет восстановлена при очередном вызове get.

Локализация строк

Шаг 7. Локализация строк

localizer.exe -put LS greenwin.lst greenwin.loc

Формат:

localizer.exe -put префикс [lst] [loc]

На этом этапе происходит модификация исходников программы [src]. Все строки, подлежащие локализации, вида LS"..." заменяются на указатели вида LS__... Кроме того, в каждый файл, где есть такие строки, добавляется их объявление вида:

/*--LOCALIZER DECLARATIONS--  Localizer: LS --BEGIN-- */
extern const char 
	*LS__..., *LS__...;
/*--LOCALIZER DECLARATIONS--  Localizer: LS --END-- */

Эти объявления генерируются автоматически и автоматически поддерживаются в правильном состоянии при каждом вызове localizer.exe -put... Место для таких деклараций также подбирается автоматически - перед первой функцией или объявлением, но после первоначальных комментариев, пустых строк и директив (вроде #include). Если вас не удовлетворяет автоматически выбраннео место, этот кусок кода можно переместить ниже или выше, и последующие вызовы localizer.exe -put... станут писать декларации именно туда.

Программа отслеживает, какие файлы действительно надо изменить, и не трогает остальные. Это снижает объем перекомпиляции.

Вместо -put можно использовать команду -puttest, тогда исходные файлы не будут изменены, а вместо них будут сгенерированы файлы с расширением .rez. Это может пригодиться, если вы не хотите пока локализовать проект, но хотите посмотреть, что получится в результате генерации.

Шаг 8. Компиляция программы

Теперь необходимо избавиться от ошибок компиляции, которые могли возникнуть. Основная причина может быть в том, что литералы были заменены на указатели. При том, что это почти эквивалентные вещи, есть некоторые тонкости, которые могут сыграть роль. Исправьте программу в нужных местах, добейтесь того, чтобы она компилировалась (линковаться она пока не будет).

Учтите, что локализация загружается в момент исполнения из функции main/WinMain/DllMain. Не следует использовать локализованные строки в статических объектах, которые создаются до вызова main/WinMain/DllMain, поскольку в момент создания статических объектов все локализованные строки указывают на NULL. Однако можно инициализировать статические объекты указателями на указатели локализованных строк, которые не изменятся.

Например, пусть дана локализованная строка с идентификатором OK и содержимым "&OK". Это значит, что:

- В [cpp] определен указатель

const char *LS__OK;
- В [loc] есть фрагмент:
OK
&OK
/END/

Сначала указатель LS__OK NULL, но после закрузки локализации будет указывать на строку "&OK". В статическом объекте можно сохранить &LS__OK, а потом сделать разыменование указателя, когда локализация уже загружена.

Наиболее обычные случаи:

static char mystring[]= LS"mystring";
- превращается в:
static char mystring[]= LS__mystring; 
- и это compile error.

Для исправления эта строка просто убирается, и везде вместо mystring пишется LS__mystring.

Другой случай:

struct Pupseg
{
   char *text;
   int id;
};
static Pupseg pups = {LS"blin", 12 };
- превращается в:
static Pupseg pups = {LS__blin, 12 };
- и это неприятно, поскольку указатель LS__blin инициализируется слишком поздно.

Это исправляется так:

struct Pupseg
{
   char **text;
   int id;
};
static Pupseg pups = {&LS__blin, 12 };

Генерация cpp-модуля

Шаг 9. Генерация cpp-модуля

Для успешной линковки не хватает [cpp]. Сгенерируйте его:

localizer.exe -cpp LS greenwin.loc greenwin_loc.cpp

Формат:

localizer.exe -cpp префикс [loc] [cpp]

Добавьте этот файл в проект. Теперь линковка должна пройти нормально.

Генерация bin-модуля

Шаг 10. Генерация бинарного файла

localizer.exe -bin LS greenwin.loc greenwin_loc.bin

Формат:

localizer.exe -bin префикс [loc] [bin]

Этот файл надо добавить в дистрибутив. В установленной программе он должен находиться рядом с исполняемым файлом (в том же каталоге).

Шаг 11. Загрузка локализации

Теперь нужно добавить в программу код загрузки локализованных строк. Пример уже приводился выше:

#include "localizer.h"
...
static Localizer localizer;
...
extern const char **LSI_all[];
if (!localizer.load("interval_loc.bin", LSI_all))
    throw GInitException();

В общем, надо где-то определить объект Localizer и вызвать у него функцию load. На вход дается имя [bin] и массив вида <префикс>_all, который определен в [cpp].

Шаг 12. Отладка

После этого локализованная программа готова к запуску. убедитесь, что все работает.

Обновления

Шаг 13. Обновление локализации.

Если программа изменилась - например, появились новые строки, подлежащие локализации, они были изменены или убраны, надо выполнить следующие шаги:

- Шаг 3 - составить новый список файлов. Это шаг можно пропустить, если проект [vcproj] не изменялся. - Шаг 5 - обновить главный файл локализации. - Шаг 7 - провести локализацию строк. Программа проведет все необходимые правки - если они не нужны, то ни один файл не будет затронут и перекомпиляция не потребуется. - Шаг 9 - сгенерировать cpp-модуль. В данном случае файл изменится, но перекомпиляция одного файла не потребует много времени. - Шаг 10 - сгенерировать bin-модуль.

Для удобства все эти шаги можно собрать в один пакетный ('bat'-файл), например:

localizer.exe -list greenwin.vcproj greenwin.lst
localizer.exe -get LS greenwin.lst greenwin.loc
localizer.exe -put LS greenwin.lst greenwin.loc
localizer.exe -cpp LS greenwin.loc greenwin_loc.cpp
localizer.exe -bin LS greenwin.loc greenwin_loc.bin
Вместо greenwin используйте название своего проекта и свой префикс вместо LS.

Перевод

Шаг 14. Перевод на другие языки.

После того, как программа отлажена, можно выполнить перевод на другие языки. Для этого надо создать варианты файла [loc]. В них должны быть те же идентификаторы, но содержимое строк - другое.

Шаг 15. Изменение языка программы.

С полученным переведенным файлом надо выполнить только один шаг (10) - сгенерировать bin-модуль. Потом надо либо заменить этим bin-модулем прежний, либо модифицировать загрузку локализации так, чтобы загружался один из bin-модулей в зависимости от нужного языка.

Синхронизация обновлений

Шаг 16. Синхронизация обновлений

Если программа изменилась и, как следствие, изменился главный файл локализации [loc], тогда и переводы тоже должны измениться соответственно. После выполнения шага 13 надо синхронизировать локализации:

localizer.exe -merge greenwin.loc greenwin.rus.loc

Формат:

localizer.exe -merge [loc] [loc+]

Локализатор сравнит два файла локализаций между собой.

Все идентификаторы, которые есть в главном файле, но которых нет в переведенном, будут добавлены в переведенный, и их надо будет перевести. Для облегчения поиска таких мест, перед идентификатором будет добавлен комментарий /!TRANSLATE!/

Все идентификаторы, которых нет в главном файле, но которые есть в переведенном, будут удалены из переведенного.

После этого надо перегенерировать bin-модуль для этого языка (шаг 10).

Программа без двоичного файла

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

Но может возникнуть желание игнорировать отсутствие файла локализации и работать нормально. В этом случае надо добавить опцию "-default" перед командой "-auto" или "-cpp". В результате в файл cpp будут записаны все строки из [loc]. Всем переменным эти строки будут присвоены "по умолчанию". Тогда ошибку загрузки файла локализации можно просто игнорировать и продолжать исполнение программы с этими строками.

Дополнительные опции

Дополнительные опции можно указывать перед командой в любом порядке:

  • "-backup". Каждый раз, когда программа меняет файл локализации ([loc], [loc+]), она будет создавать его страховочную копию с расширением .bak.
  • "-verbose". Опция включает более подробные сообщения.
  • "-remove". Опция удаляет из файла локализации все строки, которые больше не используются в программе. Если не выставить эту опцию, тогда все подобные строки будут помечены комментарием /!REMOVE!/, и вам надо будет удалить их вручную. По-умолчанию эта опция отключена, чтобы избежать случайного удаления строк.
  • "-rawout". Записывает все строки в "raw"-формате. По-умолчанию строки записываются в том формате, в котором были изначально.
  • "-escout". Записывает все строки в "escape"-формате. По-умолчанию строки записываются в том формате, в котором были изначально.
  • "-raw". Создает новые строки в "raw"-формате. По-умолчанию новые строки создаются в "escape"-формате.
  • "-default". Записывает в [cpp] не только идентификаторы строк, но и их содержимое для главного файла локализации. Это позволяет запускать программу без ошибок даже при отсутствии файла локализации. Размер исполняемого файла программы при этом немного увеличивается (приблизительно на размер строк).
  • "-regenid". Работает только с командой -auto. Запускает процесс генерации идентификаторов строк заново. Эта опция может быть полезна для тех, кто любит содержать код в идеальном порядке. Если какие-то строки были удалены или изменены, то первоначально сгенерированные идентификаторы могут не совсем соответствовать содержимому строк, также в нумерации похожих строк могут возникнуть пропуски.
        При запуске локализатор постарается оптимизировать идентификаторы и корректно исправить их в файлах локализации и в исходниках. Поскольку эта опция может затронуть сразу множество файлов, рекомендуется сделать страховочную копию проекта перед ее запуском. Настоятельно рекомендуется указывать в командной строке все файлы локализации, чтобы не произошло их рассинхронизации.

Особенности локализации библиотеки GreenWin

Это раздел написан "для себя", "на память", он касается того проекта, над которым я работаю. Это читать не нужно.

Локализация библиотеки GreenWin (на которой сделан локализатор) использует префикс LS. Ее бинарный файл локализации - greenwin_loc.bin. Файл должен находиться в том же каталоге, что и exe-файл программы.

Локализация библиотеки GreenWin загружается автоматически ею самой, когда выполняется инициализация библиотеки. Сама инициализация происходит в функции GSystem::start, либо в функции GConsoleSystem::start(). Для оконных приложений вы должны вызвать первую, а для консольных - вторую. В том же каталоге, что и приложение, должен находиться бинарный файл локализации greenwin_loc.bin

Если это оконное приложение GreenWin, тогда есть смысл поместить вызов 'load' в функцию инициализации первого модуля (GUnit::create). В случае ошибки лучше выбросить GInitException(), чтобы отменить запуск программы:

#include "gf_localizer.h"
...
static GLocalizer localizer;
...
extern const char **LSI_all[];
if (!localizer.load("interval_loc.bin", LSI_all))
    throw GInitException();

Если это консольное приложение GreenWin, есть смысл поместить вызов 'load' в функцию main, сразу после вызова GConsoleSystem::start(). В случае ошибки лучше выйти из программы (exit(-1) или return -1).

Реализация GLocalizer отличается от Localizer тем, что принимает путь относительно исполняемого файла и сама генерирует сообщение об ошибке. Для консольного приложения - в stderr, а для оконного - в message box.