Current Version: 2.3.8
The program allows you to perform automated localization of projects.
Features:
As usual, no warranties is given. However, the program has been used almost every day, and serious
bugs have not been noticed.
This section describes how to localize in the simplest form. It is anticipated that many projects
this will be enough. If not, all the subtleties and all the incomprehensible terminology
explained further.
You must have a project file for Microsoft Visual Studio 2003, 2005, 2008, 2010.
Either should be just a list of files in a file with extension .lst.
Either you have to build list of your "sources" by hand (you can use wildcards).
Determine the special prefix:
Call the localizer:
Example, suppose your project is called "interval":
Do not be afraid of a large number of parameters. In almost all cases have to call the same command
so just create a .bat-file and use.
Among the options are first prefix, then the list of "sources" with the symbol "+", then the files
associated with localization.
The meaning is determined by its file extension:
Once you call localizer for the first time in the source code of the project there will be changes.
Instead of a literal kind
Now add in the project generated file interval_loc.cpp, and loader files
(see "loaders" folder in zip). In total, the project must be added the
three files - two .cpp and one .h.
Add somewhere in the beginning write loading strings for one of the generated *.bin-files (at your option)
something like this:
Now build until successful compilation of your project. Everything on this localization is completed.
Then you can from time to time to translate the strings in *.loc-files and run the localizer with
the same parameters. You can also add new modules to the program to mark them with 'LS' prefix, and
the next start of a localizer these strings will be extracted and distributed to the localization file.
We recommend a course of action. First, programming a usual.
Quoted write text in English and mark with prefix that will require translation. When
these strings accumulate a lot, call the localizer. Then see .loc files
and translate all that marked marker /!TRANSLATE!/, removing markers. Then again start
localizer and compile the project.
That's the whole "quick start". Next come the details.
In general, the call localizer is:
All options begin with "-" character, they are slightly alter the execution.
complete list of options here.
The command starts with "-" character, it is obligatory and the only one.
Here all commands with their syntax specification.
About prefix is written here.
[list_of_sources] - a list of the files in your project to be localized.
A list of sources is formed by a series of statements beginning with the characters "+", "-" and "=".
Once found the argument without such a character in the beginning, it is considered that
[list_of_sources] was over and [other_files] started.
Operators
After the icon +or - may be:
Between +/-/= character and file name should be no space. But before the character
space should be. Combining operators can make very complicated lists
combining many different parts of the project.
The meaning of each command is explained in detail in subsequent
sections.
Prefix is a short identifier, for example to be specific "LS".
By prefix localizer recognizes strings to be localized.
Prefix uniquely determines localization. One program can have several localizations
those differ by prefix.
Prefix should be declared somewhere in the general header as empty define:
The following files are used for the localizer.
[proj] .vcproj or .vcxproj project file. It is need to get from it a list of sources,
be analyzed. Localizer understands projects of Visual Studio versions 2003, 2005, 2008, 2010.
[lst] .lst file contains list of files to be analyzed (just filenames, each on a separate string).
[src] The project source files which may contain localized strings.
Localizer scans these files and their names are taken from [lst] or [proj].
[loc] Main .loc file. This file contains the IDs of localized
strings and their contents in two formats "raw" and "escape".
details see here.
[loc+] Additional .loc files. All the same [loc], but the content is in another language.
Identifiers can not be translated. Additional localization files are synchronized with main.
[cpp] Generated .cpp-file. This file contains all the localized strings individually
and list. It must be included in the project. For all languages use the same [cpp] file.
[bin] Binary localization file (extension .bin). It is the contents of strings. It is separate [bin]
for each language. Binary file must conform to [cpp], the order and number of strings in it are the same.
detailssee here.
The "raw" format:
The "escape" format:
If you want a single localization file can be filled with strings in both formats.
Identifier - a sequence of characters, which may include letters, digits and
underscore. The sequence may begin with a digit. Inside the program to these identifiers
add a prefix and two with an underscore. For example, the identifier 'OK' turns into 'LS__OK'.
Content - an arbitrary string.
For the "raw" format any characters are allowed, including '\0', newlines and so on.
The string "\r\n/END/\r\n" is indicator of the end of the content, this string can not
present in the Contents.
For the "escape" format the Ñontents of string encoded regular C/C++ string using the escape-character "\".
Frame the quotes are not needed, gaps around the delimiter '=' leave should not be. For multi-string strings
can use the sign \ at the end of the string (as in the usual C/C++ sources).
At the end of each string will be added one character '\0', so that the hand not necessary.
Comment - optional comment string. Each string can be accompanied by one comment before.
Also the program can generate a special sort of comments:
The main localization file should contain the contents of the localized strings for the base language. Very
it is desirable that the basic language was English. Then, localization can automatically generate
meaningful identifiers that are acceptable in terms of syntax C++. You can also use
Russian language in Windows-1251, in this case, identifiers will be generated with the
use of transliteration.
Format:
For all numbers endianness is x86 (high byte - high address).
Localized String it is simply a pointer const char*, which operate as usual. When running
program localized strings are loaded from the [bin] and each pointer adjust to the desired point
memory. Specifically from the [bin] in the memory load 'block of strings', and j-th pointer is set to address:
DATA + OFFSET[j]
The names of localized strings have the form:
It's a static array of pointers to pointers to localized strings. He has the type
const char ** [] and is used only once when downloading localization at the start of the program.
His name is: prefix_all.
For example: LS_all.
Defined in [cpp].
All localized strings of this localization are defined in [cpp]. This file must be included in the project.
Localized strings array is defined in the same file.
It was decided to abandon any headers, which lists the IDs of localized strings.
Such header would include many files, and the slightest change in it would lead
to recompile a large part of the project. Instead, the 'extern' declarations uses
in each file, but they do not have to manually add, it localizer makes. The only (and single)
exception the declaration of the localized strings array before calling Localizer::load (see below).
Have the form: prefix"literal"
For example: LS"OK"
This method should be marked those strings that are subject to localization. If you have
old project, where many such strings, the prefix insertion can be automated
with command "localizer -mark".
Source with such marks will be normally compiled since LS is a empty #define. Thus, you can
mark strings for localization, but real localization delay until the right moment.
If the project has several mixed parts, each of parts should has separate localization module with
different prefix.
Localization of your own program is loaded with the object "Localizer", the function "load". In the folder
"loaders" there are several loaders:
"Localizer" object must exist as long as localized strings, so it's best to make it static.
1-st function parameter - the name of binary localization (for "RLocalizer" - integer resource identifier).
2-nd function parameter - an localized strings array (mentioned above and see example below).
Return Value - true if successful, false on error. Calling "load" should be placed at the beginning of the program.
Example:
In this example, the program uses the localization with the prefix LS and loads it from file interval_loc.bin.
List of steps is long, but it's not terrible, as most of them fit into one bat-file. Process
is divided into these fragments to show details. In our daily work on the project is only bat-file,
and think about the many small steps do not need.
Step 0. Add localizer.cpp and localizer.h to the project.
Step 1. Contrive a unique prefix that will identify the localization. Choose a short prefix
as it will have to write many times. But it must be a unique identifier that is not used in
program.
Step 2. Define prefix. Example:
This directive must be inserted in a header, preferably 'precompiled'.
Step 3. Now we have to make a list of files to be localized. The list should include all project files,
which occurs or may occur in the future with tag "LS". The list can be made manually or automatically.
You can use the standard command "dir", to create a list file, for example:
But it is better to use the project file .vcproj or .vcxproj. Then the list will not get random files
are in the folder, but do not belong to the project, either in the project, but excluded from the build.
Example call localizer to list:
File greenwin.lst here optional, just if you want to see what files get into treatment.
Step 4. Specify the strings to be localized. It is necessary to search for all literals of the project file (for example,
the symbol ") and mark with prefix all literals that must be localized. Of course, it may be marked as
general, all strings, but it is unnecessary. It should mark only those strings that can appear differently in different languages.
The process can be accelerated by applying a localizer:
This prefix will be automatically placed in front of all literals containing letters, and
will only remove the excess.
Step 5. Main Localization File Creation:
At this stage the analysis of the sources and the collection of strings to be localized in the main
.loc file (in this case greenwin.eng.loc). The whole process is fully automatic.
It is possible the following situations:
- The main language file is not created. He is considered empty and is re-created.
- The main language file already exists. Then its content is downloaded and compared with the scan results.
- When scanning is already discovered a localized string that is not in the .loc file. For example, occurs
ID LS__OK. Localizer will warn you about this. The reason may be that was taken out of date
version of the source where this string is used. It is desirable to get rid of such identifiers.
- When scanning is already discovered a localized string that is in the .loc file. This is a normal situation.
This means that the file already localized before and contents of the string is stored in greenwin.eng.loc.
- When you scan revealed a string to be localized. Its content is equivalent to one of the strings in greenwin.eng.loc.
This is a normal situation. For all the same strings used by a single repository, so that this string will simply
refer to the existing string, and it will use the same identifier.
- When you scan revealed a string to be localized. Its contents do not appear on any of the strings in greenwin.eng.loc.
This is a normal situation. For such a string will be automatically generated unique identifier (letter by letter
and figures from the beginning of the string) and its contents will be stored in greenwin.eng.loc.
- In greenwin.eng.loc is a string that is not mentioned in the project, and none of the strings to be localized, does not contain
such a text. The reason may be due to the fact that this string has been found before, but since the file from which
it was taken, was removed. Or was removed a piece of text, where it was taken. Such strings should be removed from greenwin.eng.loc,
not to occupy too much space. Will be issued a warning that the string is deleted. The file greenwin.eng.loc before this
string will comment /!REMOVE!/. Remove it from there manually, or run the localizer with the option "-remove". Default
such strings are not removed from greenwin.eng.loc just in case you edit the file back, and it reappears
this identifier. Such strings will not be loaded into memory during execution.
Step 6. Adjusting the main localization file.
Now you can make in greenwin.eng.loc manual corrections, if needed. Basically it makes sense to automatically
generated identifiers - if they are not "beautiful". If this ID is already in use
in the program, it must be corrected. But the sort you should not do, it will be restored
the next time you call a localizer.
Step 7. String Localization
At this stage the modification sources. All strings subject to localization, like
LS"..." are replaced by pointers like LS__... In addition, in each file, where there are strings added
declarations:
These declarations are automatically generated and automatically maintained in the correct position for each
call "localizer.exe -put..." The place for such declarations also set automatically before the first function
or announcement, but after the initial comments, blank strings and directives (like #include). If you
not satisfied automatically selected location, this piece of code can be moved above or below, and subsequent
calls "localizer.exe -put..." will write the declaration is there.
The program keeps track of which files really need to change, and does not touch the rest. This reduces the amount
recompilation.
Instead "-put", you can use command "-puttest", then the original files will not be changed, and instead
are generated with the extension ".rez". This is useful if you do not want yet to localize
project, but want to see what happens as a result of the generation.
Step 8. Compile program
Now you need to get rid of compilation errors that might occur. The main reason may be that,
that literals have been replaced by pointers. Given that it's almost apples to apples, there are some subtleties
which may play a role. The most common case:
To fix this string simply removed, and everywhere instead "mystring" written "LS__mystring".
Fix the program in the right places, until you get to compiled (linking it still will not).
Please note that the localization is loaded at the time of execution "Localizer::load" function in
the "main/WinMain/DllMain" (or where you are there insert a call). You should not use
localized strings in the static objects that are created before the call "Localizer::load", because
at the time of the creation of static objects of all the localized strings point to "".
However, you can initialize static objects are pointers to pointers localized strings that do not change.
For example, suppose given a localized string identifier OK and the content "&OK".
This means that:
- The source file specified ID:
- In .loc is a fragment:
First LS__OK pointer points to "", but after localization loading will point to the string "&OK". In the static object
You can save &LS__OK, and then make pointer dereference when the localization is already loaded.
Another case:
This is corrected as follows:
Step 9. cpp-module Generation.
A successful linking lacks generated [cpp] files. Do it:
Add this file to the project. Now Linking to take place normally.
Step 10. Generate binary.
This [bin]-file to be added to the distributive. In the installed program must
be somewhere close to an executable file, so the program can find it
and load the calling "Localizer::load".
Step 11. Download localization
Now you need to add to the code loading localized strings. Example already given above:
In general, it is necessary to determine where a Localizer object and call the function load. The input is given by
name [bin]-file and the array type prefix_all, which is defined in the generated [cpp]-file.
Step 12. Debugging
After this localized program is ready to launch. Make sure that everything works.
Step 13. Update localization.
All of these commands can be combined into one:
If your project has changed for example, new strings to be localized, they have changed
or removed, you must run this command. The program will conduct all the necessary changes if they are not needed
then no file will not be affected, and recompilation is not required.
Step 14. Translation into other languages.
Once the program is debugged, you can translate into other languages. For this we must create additional
files with the extension .loc. They should contain the same identifiers, but differebt contents of strings.
Step 15. Changing the language of the program.
Suppose you have created a version of greenwin.rus.loc, where all strings are translated into Russian.
For him the need corresponding to a binary file, for example, greenwin.rus.bin.
Add these files to a normal localizer call:
Then we need to either replace the old file greenwin.eng.bin with this greenwin.rus.bin, or modify the loader
call, so that loads a bin-modules depending on the desired language.
Step 16. Merge
If the program has changed and, consequently, changed the main language file [loc], and then translations the same
must change accordingly. The same call to make and synchronize translations. If desired, this can be done
as a specific command "-merge":
Localizer compare the two file locations to each other. In this case the first file has a higher priority
considered a model.
All identifiers that are in the main file, but which are not in second, will be added to the second,
and they must be translated. To facilitate the search of such places, before the identifier is added comment
/!TRANSLATE!/
All identifiers that are not in the main file, but which is in second, will be removed from the second.
After this you should regenerate bin-module for that language (in the same universal calling or "localizer -auto"
or special command "localizer -bin").
If your application can not load language file, the program is likely to be unworkable, because instead of
many rows will be empty strings. In this case, you have the program exit. Error message
(if any) must be non-localized string.
But you may want to ignore the absence of the localization file and work fine. In this case,
add the option "-default" before the command "-auto" or "-cpp". As a result, in the cpp file will be written to all
strings from [loc]. All variables are assigned to the strings from the main [loc]. Then an error loading the file
can just ignore and continue executing the program with these strings.
Additional Options can be specified before the command in any order:
Localized strings can be stored directly in the exe-file, but when the program starts
load them from there. That course of action for such a project.
1. Create resource header (this is usually a file with extension .rh) add identifiers for resources. Something
like:
2. Create resource file (this is usually a file with extension .rc), add resources, indicating [bin]-localization files.
Something like:
3. To load the correct localization use the loader "RLocalizer" and code like this:
Localization of Unicode project has the following differences:
Localization of Qt projects have the following differences:
If you want change prefix use command like this:
Files
Utility (in the subdirectory exe), examples of loaders, source.
No installation is required. This program is free. The project is partially
of Open Source (most important sources are included to zip).
General
Quick Start
#define LS
- This or the other, if only unique. Mark with this prefix all strings to be localized
e.g. LS"this string" or LS("this string").
localizer -auto LS file1 file2 ...
localizer -auto LS +interval.vcproj interval.eng.loc interval.rus.loc interval_loc.cpp interval.eng.bin interval.rus.bin
Or if you do not have a project, but there is only a list of interval.lst, then:
localizer -auto LS +interval.lst interval.eng.loc interval.rus.loc interval_loc.cpp interval.eng.bin interval.rus.bin
Or if you do not even have a list, but all .cpp/.h files are in the current directory, then:
localizer -auto LS +*.cpp +*.h interval.eng.loc interval.rus.loc interval_loc.cpp interval.eng.bin interval.rus.bin
identifier_string_content=string
identifier_string_content=string
...
(in the normal format of C/C++with all kinds of \n, \r only without framing quotes).
LS"this string"
will pointers (const char *) like
LS__this_string
and declarations like extern const char *LS__this_string;
#include "localizer.h"
...
static Localizer localizer;
...
extern const char **LS_all[];
if (! localizer.load ("interval_loc.bin", LS_all))
(error processing)
Command-string Syntax
path\localizer.exe [options] command [prefix] [list_of_sources] [other_files]
- in this case a list of paths is taken from the file. Assumed
it is a plain text file, on each string one path. If there
path is not absolute, it is considered relative .lst file.
- this file is supposed to project file of Visual Studio. It is parsed
and files from there added to the list. If there path is not absolute, it is
considered to be relative project file.
Commands List
localizer.exe [options] -auto prefix [source_list] cpp_file
localization_file localization_file... bin_file bin_file...
- The main command. Combines the effects of commands list, get, put, cpp, bin and merge.
localizer.exe [options] -list [source_list]
- Check the list of sources.
localizer.exe [options] -mark prefix [source_list]
- Performs automatic prefix insertion for the project, which has not previously localized.
localizer.exe [options] -get prefix [source_list] localization_file
- Scans the source code, collects the marked strings in a text file.
localizer.exe [options] -put prefix [source_list] localization_file
- Plus to modify the source code, replacing the marked strings.
localizer.exe [options] -puttest prefix [source_list] localization_file
- For very cautious: instead of modifying the source files created new with extension .rez
localizer.exe [options] -cpp prefix localization_file cpp_file
- Creates a cpp-file to be included in the project.
localizer.exe [options] -bin localization_file bin_file
- Creates a bin-file to be included in the distributive or resources.
localizer.exe [options] -test bin_file
- Shows the contents of the bin-file in a readable form.
localizer.exe [options] -merge localization_file localization_file ...
- Merge the localization files in other languages with the first file as a standard.
Prefix
#define LS
Files
.loc-file Format
/Comment
Identifier
Contents
/END/
/Comment
Identifier
Contents
/END/
...
/Comment
Identifier=content
/Comment
Identifier=content
...
/!Text!/
.bin-file Format
DWORD N - number of rows
DWORD SZ - the size of block of strings
DWORD OFFSET[N] - block of offsets
- Offset of each of the N rows in a block of strings from the beginning of the block of strings
BYTE DATA [SZ] - block of strings
Localized String
Localized Strings Array
Localized Strings Definitions
Localized Strings Declarations
Strings for Localization
Localization Loading
#include "localizer.h"
...
static Localizer localizer;
...
extern const char **LS_all[];
if (!localizer.load ("interval_loc.bin", LS_all))
(
printf ("Error of localization.\n")
return -1;
)
Localization Step-by-Step
#define LS
List of Sources Creation
dir /B *.cpp> my.lst
dir /B *.h>> my.lst
dir /B *.hpp>> my.lst
localizer.exe -list +greenwin.vcproj =greenwin.lst
localizer.exe -mark LS +greenwin.vcproj
Main Localization File Creation
localizer.exe -get LS +greenwin.vcproj greenwin.eng.loc
String Localization
localizer.exe -put LS +greenwin.vcproj greenwin.eng.loc
/*--LOCALIZER DECLARATIONS-- Localizer: LS --BEGIN-- */
extern const char
*LS__..., *LS__...;
/*--LOCALIZER DECLARATIONS-- Localizer: LS --END-- */
static char mystring[] = LS"mystring";
- Becomes:
static char mystring[] = LS__mystring;
- And this compile error.
extern const char * LS__OK;
OK=&OK
struct SomeClass
(
char * text;
int id;
)
static SomeClass bups = (LS "blin", 12);
- Becomes:
static SomeClass bups = (LS__blin, 12);
- And it is unpleasant, because the pointer LS__blin initialized too late.
struct SomeClass
(
char **text;
int id;
)
static SomeClass bups = (&LS__blin, 12);
cpp-module Generation
localizer.exe -cpp LS greenwin.eng.loc greenwin_loc.cpp
bin-module Generation
localizer.exe -bin greenwin.eng.loc greenwin.eng.bin
#include "localizer.h"
...
static Localizer localizer;
...
extern const char **LS_all[];
if (!localizer.load ("greenwin.eng.bin", LS_all))
throw GInitException ();
Updates
localizer.exe -auto LS +greenwin.vcproj greenwin.eng.loc greenwin_loc.cpp greenwin.eng.bin
Translation
localizer.exe -auto LS +greenwin.vcproj greenwin_loc.cpp
greenwin.eng.loc greenwin.rus.loc greenwin.eng.bin greenwin.rus.bin
Merge
localizer.exe -merge greenwin.eng.loc greenwin.rus.loc
Project without bin-s
Additional Options
When you run the localizer will try to optimize the IDs and correctly
correct them in the localization file and the source. Since this option can affect multiple files at once,
recommended to make a safety copy of the project before its launch. It is strongly recommended to specify in
command prompt all localization files to avoid their desync.
-prepend #include""my_pch.h""
Loading from Resources
#define IDLOC_ENGLISH 4000
#define IDLOC_RUSSIAN 4001
IDLOC_ENGLISH BINARY "interval_loc.bin"
IDLOC_RUSSIAN BINARY "interval_loc.rus.bin"
#include "rlocalizer.h"
#include "resource.rh"
...
static RLocalizer localizer;
...
extern const char **LS_all[];
if (! localizer.load (IDLOC_RUSSIAN, LS_all))
(error processing)
Unicode Localization
Qt Localization
Prefix replacement
localizer -prefix LS LSN +interval.vcproj