diff options
author | ptomulik <ptomulik@meil.pw.edu.pl> | 2012-06-06 20:14:26 (GMT) |
---|---|---|
committer | ptomulik <ptomulik@meil.pw.edu.pl> | 2012-06-06 20:14:26 (GMT) |
commit | 045bb7d4cfc3e1a4c0c41619248211c7c3b9ca5a (patch) | |
tree | ce81b8f9455c354c8a85e77134b0ece9b5903c66 | |
parent | 69ec58de81fae315449b1f6f425526977a7a2699 (diff) | |
download | SCons-045bb7d4cfc3e1a4c0c41619248211c7c3b9ca5a.zip SCons-045bb7d4cfc3e1a4c0c41619248211c7c3b9ca5a.tar.gz SCons-045bb7d4cfc3e1a4c0c41619248211c7c3b9ca5a.tar.bz2 |
Added gettext tools
42 files changed, 5491 insertions, 0 deletions
diff --git a/doc/user/MANIFEST b/doc/user/MANIFEST index 0994f2b..21c63b0 100644 --- a/doc/user/MANIFEST +++ b/doc/user/MANIFEST @@ -18,6 +18,7 @@ example.xml factories.xml file-removal.xml functions.xml +gettext.xml hierarchy.xml install.xml java.xml diff --git a/doc/user/gettext.in b/doc/user/gettext.in new file mode 100644 index 0000000..63c1d20 --- /dev/null +++ b/doc/user/gettext.in @@ -0,0 +1,351 @@ +<!-- + + __TOOL_COPYRIGHT__ + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--> + + <para> + The &t-link-gettext; toolset supports internationalization and localization + of SCons-based projects. The tools provided within &t-link-gettext; by + automatize generation and updates of translation files. You can manage + translations and translation templates simillary as it was done with + autotools. + </para> + + <section> + <title>Prerequisites</title> + <para> + Setup your operating system, so you can use several languages. In following + examples we use locales <literal>en_US</literal>, <literal>de_DE</literal>, + and <literal>pl_PL</literal>. + </para> + + <para> + Ensure, that you have <ulink + url="http://www.gnu.org/software/gettext/manual/gettext.html">GNU gettext + utilities</ulink> installed on your system. + </para> + + <para> + To edit translation files, you may install <ulink + url="http://www.poedit.net/">poedit</ulink> editor. + </para> + </section> + + <section> + <title>Simple project</title> + <para> + Let's start with some simple project, the "Hello world" program + for example + <scons_example name="ex1"> + <file name="hello.c" printme="1"> + /* hello.c */ + #include <stdio.h> + int main(int argc, char* argv[]) + { + printf("Hello world\n"); + return 0; + } + </file> + </scons_example> + + Prepare simple <filename>SConstruct</filename> script to compile the + program. + <scons_example name="ex2"> + <file name="SConstruct" printme="1"> + # SConstruct + env = Environment() + hello = Program(["hello.c"]) + </file> + </scons_example> + </para> + + <para> + Now we'll convert the project to multi-lingual one. I assume, that you + already have <ulink + url="http://www.gnu.org/software/gettext/manual/gettext.html">GNU gettext + utilities</ulink> installed. If not, install it from repository, or + download from <ulink url="http://ftp.gnu.org/gnu/gettext/"> + http://ftp.gnu.org/gnu/gettext/</ulink>. For the purpose of this example, + you should have following three locales installed on your system + <literal>en_US</literal>, <literal>de_DE</literal> and + <literal>pl_PL</literal>. On debian, for example, you may enable certain + locales through <command>dpkg-reconfigure locales</command>. + </para> + + <para> + We first prepare the <filename>hello.c</filename> program, for + internationalization. Change the previous code so it reads as follows: + <scons_example name="ex3"> + <file name="hello.c" printme="1"> + /* hello.c */ + #include <stdio.h> + #include <libintl.h> + #include <locale.h> + int main(int argc, char* argv[]) + { + bindtextdomain("hello", "locale"); + setlocale(LC_ALL, ""); + textdomain("hello"); + printf(gettext("Hello world\n")); + return 0; + } + </file> + </scons_example> + This way we prepared source code. Detailed recipes for such preparation can + be found at <ulink + url="http://www.gnu.org/software/gettext/manual/gettext.html#Sources"> + http://www.gnu.org/software/gettext/manual/gettext.html#Sources</ulink>. + The <function>gettext("...")</function> in above source has two purposes. + First is is recognized by the <command>xgettext(1)</command> program, which + we will use to extract from the sources the messages for localization. + Second, it calls the <literal>gettext</literal> library internals to + translate the message at runtime. + </para> + + <para> + Now we shall instruct SCons how to generate and maintain translation files. + For that, we use &b-link-Translate; builder and &b-link-MOFiles; builder. + First one takes a couple of source files, extracts internationalized + messages from them, creates so-called <literal>POT</literal> file + (translation template), and then creates <literal>PO</literal> translation + files, one for each requested language. Later, during the development + lifecycle, the builder keeps all these files up-to date. The + &b-link-MOFiles; builder compiles the <literal>PO</literal> files to binary + form. After all, we install the <literal>MO</literal> files under directory + called <filename>locale</filename>. + </para> + + <para> The complete code of + <filename>SConstruct</filename> script for multi-lingual "Hello world" will + be following: + <scons_example name="ex4"> + <file name="SConstruct" printme="1"> + # SConstruct + env = Environment( tools = ['default', 'gettext'] ) + hello = env.Program(["hello.c"]) + env['XGETTEXTFLAGS'] = [ + '--package-name=%s' % 'hello', + '--package-version=%s' % '1.0', + ] + po = env.Translate(["pl","en", "de"], ["hello.c"], POAUTOINIT = 1) + mo = env.MOFiles(po) + InstallAs(["locale/en/LC_MESSAGES/hello.mo"], ["en.mo"]) + InstallAs(["locale/pl/LC_MESSAGES/hello.mo"], ["pl.mo"]) + InstallAs(["locale/de/LC_MESSAGES/hello.mo"], ["de.mo"]) + </file> + </scons_example> + </para> + <para> + Generate translation files with <command>scons po-update</command>. + You should see the output from SCons simillar to this: + <screen> + ptomulik@:$ scons po-update + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + Entering '/home/ptomulik/projects/tmp' + xgettext --package-name=hello --package-version=1.0 -o - hello.c + Leaving '/home/ptomulik/projects/tmp' + Writting 'messages.pot' (new file) + msginit --no-translator -l pl -i messages.pot -o pl.po + Created pl.po. + msginit --no-translator -l en -i messages.pot -o en.po + Created en.po. + msginit --no-translator -l de -i messages.pot -o de.po + Created de.po. + scons: done building targets. + </screen> + </para> + + <para> + If everything is right, you shall see following new files. + <screen> + ptomulik@:$ ls *.po* + de.po en.po messages.pot pl.po + </screen> + </para> + + <para> + Open <filename>en.po</filename> in <command>poedit</command> and provide + english "translation" to message <literal>"Hello world\n"</literal>. Do the + same for <filename>de.po</filename> (deutsch) and + <filename>pl.po</filename> (polish). Let the translations be, for example: + <itemizedlist> + <listitem><para> + <literal>en: "Welcome to beautiful world!\n"</literal> + </para></listitem> + <listitem><para> + <literal>de: "Hallo Welt!\n"</literal> + </para></listitem> + <listitem><para> + <literal>pl: "Witaj swiecie!\n"</literal> + </para></listitem> + </itemizedlist> + </para> + <para> + Now compile the project by executing <command>scons</command> command. The + output should be similar to this: + <screen> + ptomulik@:$ scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + msgfmt -c -o de.mo de.po + msgfmt -c -o en.mo en.po + gcc -o hello.o -c hello.c + gcc -o hello hello.o + Install file: "de.mo" as "locale/de/LC_MESSAGES/hello.mo" + Install file: "en.mo" as "locale/en/LC_MESSAGES/hello.mo" + msgfmt -c -o pl.mo pl.po + Install file: "pl.mo" as "locale/pl/LC_MESSAGES/hello.mo" + scons: done building targets. + </screen> + SCons automatically compiled <literal>PO</literal> files to binary format + <literal>MO</literal>, and the <literal>InstallAs</literal> lines installed + these files under <filename>locale</filename> folder. + </para> + <para> + Your program should be now ready. You may try it as follows (linux): + <screen> + ptomulik@:$ LANG=en_US.UTF-8 ./hello + Welcome to beautiful world + </screen> + <screen> + ptomulik@:$ LANG=de_DE.UTF-8 ./hello + Hallo Welt + </screen> + <screen> + ptomulik@:$ LANG=pl_PL.UTF-8 ./hello + Witaj swiecie + </screen> + </para> + <para> + To demonstrate further life of translation files, let's change polish + translation (<command>poedit pl.po</command>) to <literal>"Witaj drogi + swiecie\n"</literal>. Run <command>scons</command> to see how scons + reacts to this + <screen> + ptomulik@:$scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + msgfmt -c -o pl.mo pl.po + Install file: "pl.mo" as "locale/pl/LC_MESSAGES/hello.mo" + scons: done building targets. + </screen> + </para> + <para> + Now, open <filename>hello.c</filename> and add another one + <literal>printf</literal> line with new message. + <scons_example name="ex5"> + <file name="hello.c" printme="1"> + /* hello.c */ + #include <stdio.h> + #include <libintl.h> + #include <locale.h> + int main(int argc, char* argv[]) + { + bindtextdomain("hello", "locale"); + setlocale(LC_ALL, ""); + textdomain("hello"); + printf(gettext("Hello world\n")); + printf(gettext("and good bye\n")); + return 0; + } + </file> + </scons_example> + </para> + <para> + Compile project with <command>scons</command>. This time, the + <command>msgmerge(1)</command> program is used by SCons to update + <literal>PO</literal> file. The output from compilation is like: + <screen> + ptomulik@:$scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + Entering '/home/ptomulik/projects/tmp' + xgettext --package-name=hello --package-version=1.0 -o - hello.c + Leaving '/home/ptomulik/projects/tmp' + Writting 'messages.pot' (messages in file were outdated) + msgmerge --update de.po messages.pot + ... done. + msgfmt -c -o de.mo de.po + msgmerge --update en.po messages.pot + ... done. + msgfmt -c -o en.mo en.po + gcc -o hello.o -c hello.c + gcc -o hello hello.o + Install file: "de.mo" as "locale/de/LC_MESSAGES/hello.mo" + Install file: "en.mo" as "locale/en/LC_MESSAGES/hello.mo" + msgmerge --update pl.po messages.pot + ... done. + msgfmt -c -o pl.mo pl.po + Install file: "pl.mo" as "locale/pl/LC_MESSAGES/hello.mo" + scons: done building targets. + </screen> + </para> + <para> + The last example demonstrates what happens, if we change the source code + in such way, that the internationalized messages do not change. The answer + is, that none of translation files (<literal>POT</literal>, + <literal>PO</literal>) is touched (i.e. no content changes, no + creation/modification time changed and so on). Let's append another one + instruction to the program (after the last printf), so its code becomes: + <scons_example name="ex6"> + <file name="hello.c" printme="1"> + /* hello.c */ + #include <stdio.h> + #include <libintl.h> + #include <locale.h> + int main(int argc, char* argv[]) + { + bindtextdomain("hello", "locale"); + setlocale(LC_ALL, ""); + textdomain("hello"); + printf(gettext("Hello world\n")); + printf(gettext("and good bye\n")); + printf("----------------\n"); + return a; + } + </file> + </scons_example> + Compile project. You'll see on your screen + <screen> + ptomulik@:$scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + Entering '/home/ptomulik/projects/tmp' + xgettext --package-name=hello --package-version=1.0 -o - hello.c + Leaving '/home/ptomulik/projects/tmp' + Not writting 'messages.pot' (messages in file found to be up-to-date) + gcc -o hello.o -c hello.c + gcc -o hello hello.o + scons: done building targets. + </screen> + As you see, the internationalized messages ditn't change, so the + <literal>POT</literal> and the rest of translation files have not + even been touched. + </para> + </section> diff --git a/doc/user/gettext.xml b/doc/user/gettext.xml new file mode 100644 index 0000000..9b1b631 --- /dev/null +++ b/doc/user/gettext.xml @@ -0,0 +1,335 @@ +<!-- + + __TOOL_COPYRIGHT__ + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--> + + <para> + The &t-link-gettext; toolset supports internationalization and localization + of SCons-based projects. The tools provided within &t-link-gettext; by + automatize generation and updates of translation files. You can manage + translations and translation templates simillary as it was done with + autotools. + </para> + + <section> + <title>Prerequisites</title> + <para> + Setup your operating system, so you can use several languages. In following + examples we use locales <literal>en_US</literal>, <literal>de_DE</literal>, + and <literal>pl_PL</literal>. + </para> + + <para> + Ensure, that you have <ulink url="http://www.gnu.org/software/gettext/manual/gettext.html">GNU gettext + utilities</ulink> installed on your system. + </para> + + <para> + To edit translation files, you may install <ulink url="http://www.poedit.net/">poedit</ulink> editor. + </para> + </section> + + <section> + <title>Simple project</title> + <para> + Let's start with some simple project, the "Hello world" program + for example + <programlisting> + /* hello.c */ + #include <stdio.h> + int main(int argc, char* argv[]) + { + printf("Hello world\n"); + return 0; + } + </programlisting> + + Prepare simple <filename>SConstruct</filename> script to compile the + program. + <programlisting> + # SConstruct + env = Environment() + hello = Program(["hello.c"]) + </programlisting> + </para> + + <para> + Now we'll convert the project to multi-lingual one. I assume, that you + already have <ulink url="http://www.gnu.org/software/gettext/manual/gettext.html">GNU gettext + utilities</ulink> installed. If not, install it from repository, or + download from <ulink url="http://ftp.gnu.org/gnu/gettext/"> + http://ftp.gnu.org/gnu/gettext/</ulink>. For the purpose of this example, + you should have following three locales installed on your system + <literal>en_US</literal>, <literal>de_DE</literal> and + <literal>pl_PL</literal>. On debian, for example, you may enable certain + locales through <command>dpkg-reconfigure locales</command>. + </para> + + <para> + We first prepare the <filename>hello.c</filename> program, for + internationalization. Change the previous code so it reads as follows: + <programlisting> + /* hello.c */ + #include <stdio.h> + #include <libintl.h> + #include <locale.h> + int main(int argc, char* argv[]) + { + bindtextdomain("hello", "locale"); + setlocale(LC_ALL, ""); + textdomain("hello"); + printf(gettext("Hello world\n")); + return 0; + } + </programlisting> + This way we prepared source code. Detailed recipes for such preparation can + be found at <ulink url="http://www.gnu.org/software/gettext/manual/gettext.html#Sources"> + http://www.gnu.org/software/gettext/manual/gettext.html#Sources</ulink>. + The <function>gettext("...")</function> in above source has two purposes. + First is is recognized by the <command>xgettext(1)</command> program, which + we will use to extract from the sources the messages for localization. + Second, it calls the <literal>gettext</literal> library internals to + translate the message at runtime. + </para> + + <para> + Now we shall instruct SCons how to generate and maintain translation files. + For that, we use &b-link-Translate; builder and &b-link-MOFiles; builder. + First one takes a couple of source files, extracts internationalized + messages from them, creates so-called <literal>POT</literal> file + (translation template), and then creates <literal>PO</literal> translation + files, one for each requested language. Later, during the development + lifecycle, the builder keeps all these files up-to date. The + &b-link-MOFiles; builder compiles the <literal>PO</literal> files to binary + form. After all, we install the <literal>MO</literal> files under directory + called <filename>locale</filename>. + </para> + + <para> The complete code of + <filename>SConstruct</filename> script for multi-lingual "Hello world" will + be following: + <programlisting> + # SConstruct + env = Environment( tools = ['default', 'gettext'] ) + hello = env.Program(["hello.c"]) + env['XGETTEXTFLAGS'] = [ + '--package-name=%s' % 'hello', + '--package-version=%s' % '1.0', + ] + po = env.Translate(["pl","en", "de"], ["hello.c"], POAUTOINIT = 1) + mo = env.MOFiles(po) + InstallAs(["locale/en/LC_MESSAGES/hello.mo"], ["en.mo"]) + InstallAs(["locale/pl/LC_MESSAGES/hello.mo"], ["pl.mo"]) + InstallAs(["locale/de/LC_MESSAGES/hello.mo"], ["de.mo"]) + </programlisting> + </para> + <para> + Generate translation files with <command>scons po-update</command>. + You should see the output from SCons simillar to this: + <screen> + ptomulik@:$ scons po-update + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + Entering '/home/ptomulik/projects/tmp' + xgettext --package-name=hello --package-version=1.0 -o - hello.c + Leaving '/home/ptomulik/projects/tmp' + Writting 'messages.pot' (new file) + msginit --no-translator -l pl -i messages.pot -o pl.po + Created pl.po. + msginit --no-translator -l en -i messages.pot -o en.po + Created en.po. + msginit --no-translator -l de -i messages.pot -o de.po + Created de.po. + scons: done building targets. + </screen> + </para> + + <para> + If everything is right, you shall see following new files. + <screen> + ptomulik@:$ ls *.po* + de.po en.po messages.pot pl.po + </screen> + </para> + + <para> + Open <filename>en.po</filename> in <command>poedit</command> and provide + english "translation" to message <literal>"Hello world\n"</literal>. Do the + same for <filename>de.po</filename> (deutsch) and + <filename>pl.po</filename> (polish). Let the translations be, for example: + <itemizedlist> + <listitem><para> + <literal>en: "Welcome to beautiful world!\n"</literal> + </para></listitem> + <listitem><para> + <literal>de: "Hallo Welt!\n"</literal> + </para></listitem> + <listitem><para> + <literal>pl: "Witaj swiecie!\n"</literal> + </para></listitem> + </itemizedlist> + </para> + <para> + Now compile the project by executing <command>scons</command> command. The + output should be similar to this: + <screen> + ptomulik@:$ scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + msgfmt -c -o de.mo de.po + msgfmt -c -o en.mo en.po + gcc -o hello.o -c hello.c + gcc -o hello hello.o + Install file: "de.mo" as "locale/de/LC_MESSAGES/hello.mo" + Install file: "en.mo" as "locale/en/LC_MESSAGES/hello.mo" + msgfmt -c -o pl.mo pl.po + Install file: "pl.mo" as "locale/pl/LC_MESSAGES/hello.mo" + scons: done building targets. + </screen> + SCons automatically compiled <literal>PO</literal> files to binary format + <literal>MO</literal>, and the <literal>InstallAs</literal> lines installed + these files under <filename>locale</filename> folder. + </para> + <para> + Your program should be now ready. You may try it as follows (linux): + <screen> + ptomulik@:$ LANG=en_US.UTF-8 ./hello + Welcome to beautiful world + </screen> + <screen> + ptomulik@:$ LANG=de_DE.UTF-8 ./hello + Hallo Welt + </screen> + <screen> + ptomulik@:$ LANG=pl_PL.UTF-8 ./hello + Witaj swiecie + </screen> + </para> + <para> + To demonstrate further life of translation files, let's change polish + translation (<command>poedit pl.po</command>) to <literal>"Witaj drogi + swiecie\n"</literal>. Run <command>scons</command> to see how scons + reacts to this + <screen> + ptomulik@:$scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + msgfmt -c -o pl.mo pl.po + Install file: "pl.mo" as "locale/pl/LC_MESSAGES/hello.mo" + scons: done building targets. + </screen> + </para> + <para> + Now, open <filename>hello.c</filename> and add another one + <literal>printf</literal> line with new message. + <programlisting> + /* hello.c */ + #include <stdio.h> + #include <libintl.h> + #include <locale.h> + int main(int argc, char* argv[]) + { + bindtextdomain("hello", "locale"); + setlocale(LC_ALL, ""); + textdomain("hello"); + printf(gettext("Hello world\n")); + printf(gettext("and good bye\n")); + return 0; + } + </programlisting> + </para> + <para> + Compile project with <command>scons</command>. This time, the + <command>msgmerge(1)</command> program is used by SCons to update + <literal>PO</literal> file. The output from compilation is like: + <screen> + ptomulik@:$scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + Entering '/home/ptomulik/projects/tmp' + xgettext --package-name=hello --package-version=1.0 -o - hello.c + Leaving '/home/ptomulik/projects/tmp' + Writting 'messages.pot' (messages in file were outdated) + msgmerge --update de.po messages.pot + ... done. + msgfmt -c -o de.mo de.po + msgmerge --update en.po messages.pot + ... done. + msgfmt -c -o en.mo en.po + gcc -o hello.o -c hello.c + gcc -o hello hello.o + Install file: "de.mo" as "locale/de/LC_MESSAGES/hello.mo" + Install file: "en.mo" as "locale/en/LC_MESSAGES/hello.mo" + msgmerge --update pl.po messages.pot + ... done. + msgfmt -c -o pl.mo pl.po + Install file: "pl.mo" as "locale/pl/LC_MESSAGES/hello.mo" + scons: done building targets. + </screen> + </para> + <para> + The last example demonstrates what happens, if we change the source code + in such way, that the internationalized messages do not change. The answer + is, that none of translation files (<literal>POT</literal>, + <literal>PO</literal>) is touched (i.e. no content changes, no + creation/modification time changed and so on). Let's append another one + instruction to the program (after the last printf), so its code becomes: + <programlisting> + /* hello.c */ + #include <stdio.h> + #include <libintl.h> + #include <locale.h> + int main(int argc, char* argv[]) + { + bindtextdomain("hello", "locale"); + setlocale(LC_ALL, ""); + textdomain("hello"); + printf(gettext("Hello world\n")); + printf(gettext("and good bye\n")); + printf("----------------\n"); + return a; + } + </programlisting> + Compile project. You'll see on your screen + <screen> + ptomulik@:$scons + scons: Reading SConscript files ... + scons: done reading SConscript files. + scons: Building targets ... + Entering '/home/ptomulik/projects/tmp' + xgettext --package-name=hello --package-version=1.0 -o - hello.c + Leaving '/home/ptomulik/projects/tmp' + Not writting 'messages.pot' (messages in file found to be up-to-date) + gcc -o hello.o -c hello.c + gcc -o hello hello.o + scons: done building targets. + </screen> + As you see, the internationalized messages ditn't change, so the + <literal>POT</literal> and the rest of translation files have not + even been touched. + </para> + </section> diff --git a/doc/user/main.in b/doc/user/main.in index 4b0807d..0f8e305 100644 --- a/doc/user/main.in +++ b/doc/user/main.in @@ -65,6 +65,7 @@ <!ENTITY factories SYSTEM "factories.xml"> <!ENTITY file-removal SYSTEM "file-removal.xml"> <!ENTITY functions SYSTEM "functions.xml"> + <!ENTITY gettext SYSTEM "gettext.xml"> <!ENTITY hierarchy SYSTEM "hierarchy.xml"> <!ENTITY java SYSTEM "java.xml"> <!ENTITY install SYSTEM "install.xml"> @@ -253,6 +254,11 @@ &variants; </chapter> + <chapter id="chap-gettext"> + <title>Internaionalization and Localization with Gettext</title> + &gettext; + </chapter> + <!-- <chapter id="chap-builders-built-in"> diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index 377b7b7..15b3cb4 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -183,3 +183,14 @@ SCons/Variables/ListVariable.py SCons/Variables/PackageVariable.py SCons/Variables/PathVariable.py SCons/Warnings.py +SCons/Tool/msgfmt.py +SCons/Tool/GettextCommon.py +SCons/Tool/gettext.py +SCons/Tool/msginit.py +SCons/Tool/msgmerge.py +SCons/Tool/xgettext.py +SCons/Tool/msgfmt.xml +SCons/Tool/xgettext.xml +SCons/Tool/msgmerge.xml +SCons/Tool/msginit.xml +SCons/Tool/gettext.xml diff --git a/src/engine/SCons/Tool/GettextCommon.py b/src/engine/SCons/Tool/GettextCommon.py new file mode 100644 index 0000000..d786015 --- /dev/null +++ b/src/engine/SCons/Tool/GettextCommon.py @@ -0,0 +1,444 @@ +"""SCons.Tool.GettextCommon module + +Used by several tools of `gettext` toolset. +""" + +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Warnings +import re + +############################################################################# +class XgettextToolWarning(SCons.Warnings.Warning): pass +class XgettextNotFound(XgettextToolWarning): pass +class MsginitToolWarning(SCons.Warnings.Warning): pass +class MsginitNotFound(MsginitToolWarning): pass +class MsgmergeToolWarning(SCons.Warnings.Warning): pass +class MsgmergeNotFound(MsgmergeToolWarning): pass +class MsgfmtToolWarning(SCons.Warnings.Warning): pass +class MsgfmtNotFound(MsgfmtToolWarning): pass +############################################################################# +SCons.Warnings.enableWarningClass(XgettextToolWarning) +SCons.Warnings.enableWarningClass(XgettextNotFound) +SCons.Warnings.enableWarningClass(MsginitToolWarning) +SCons.Warnings.enableWarningClass(MsginitNotFound) +SCons.Warnings.enableWarningClass(MsgmergeToolWarning) +SCons.Warnings.enableWarningClass(MsgmergeNotFound) +SCons.Warnings.enableWarningClass(MsgfmtToolWarning) +SCons.Warnings.enableWarningClass(MsgfmtNotFound) +############################################################################# + +############################################################################# +class _POTargetFactory(object): + """ A factory of `PO` target files. + + Factory defaults differ from these of `SCons.Node.FS.FS`. We set `precious` + (this is required by builders and actions in `SConsToolGettext`) and + `noclean` flags by default for all produced nodes. + """ + def __init__( self, env, nodefault = True, alias = None, precious = True + , noclean = True ): + """ Object constructor. + + **Arguments** + + - *env* (`SCons.Environment.Environment`) + - *nodefault* (`boolean`) - if `True`, produced nodes will be ignored + from default target `'.'` + - *alias* (`string`) - if provided, produced nodes will be automatically + added to this alias, and alias will be set as `AlwaysBuild` + - *precious* (`boolean`) - if `True`, the produced nodes will be set as + `Precious`. + - *noclen* (`boolean`) - if `True`, the produced nodes will be excluded + from `Clean`. + """ + self.env = env + self.alias = alias + self.precious = precious + self.noclean = noclean + self.nodefault = nodefault + + def _create_node(self, name, factory, directory = None, create = 1): + """ Create node, and set it up to factory settings. """ + import SCons.Util + node = factory(name, directory, create) + node.set_noclean(self.noclean) + node.set_precious(self.precious) + if self.nodefault: + self.env.Ignore('.', node) + if self.alias: + self.env.AlwaysBuild(self.env.Alias(self.alias, node)) + return node + + def Entry(self, name, directory = None, create = 1): + """ Create `SCons.Node.FS.Entry` """ + return self._create_node(name, self.env.fs.Entry, directory, create) + + def File(self, name, directory = None, create = 1): + """ Create `SCons.Node.FS.File` """ + return self._create_node(name, self.env.fs.File, directory, create) +############################################################################# + +############################################################################# +_re_comment = re.compile(r'(#[^\n\r]+)$', re.M) +_re_lang = re.compile(r'([a-zA-Z0-9_]+)', re.M) +############################################################################# +def _read_linguas_from_files(env, linguas_files = None): + """ Parse `LINGUAS` file and return list of extracted languages """ + import SCons.Util + import SCons.Environment + global _re_comment + global _re_lang + if not SCons.Util.is_List(linguas_files) \ + and not SCons.Util.is_String(linguas_files) \ + and not isinstance(linguas_files, SCons.Node.FS.Base) \ + and linguas_files: + # If, linguas_files==True or such, then read 'LINGUAS' file. + linguas_files = [ 'LINGUAS' ] + if linguas_files is None: + return [] + fnodes = env.arg2nodes(linguas_files) + linguas = [] + for fnode in fnodes: + contents = _re_comment.sub("", fnode.get_text_contents()) + ls = [ l for l in _re_lang.findall(contents) if l ] + linguas.extend(ls) + return linguas +############################################################################# + +############################################################################# +from SCons.Builder import BuilderBase +############################################################################# +class _POFileBuilder(BuilderBase): + """ `PO` file builder. + + This is multi-target single-source builder. In typical situation the source + is single `POT` file, e.g. `messages.pot`, and there are multiple `PO` + targets to be updated from this `POT`. We must run + `SCons.Builder.BuilderBase._execute()` separatelly for each target to track + dependencies separatelly for each target file. + + **NOTE**: if we call `SCons.Builder.BuilderBase._execute(.., target, ...)` + with target being list of all targets, all targets would be rebuilt each time + one of the targets from this list is missing. This would happen, for example, + when new language `ll` enters `LINGUAS_FILE` (at this moment there is no + `ll.po` file yet). To avoid this, we override + `SCons.Builder.BuilerBase._execute()` and call it separatelly for each + target. Here we also append to the target list the languages read from + `LINGUAS_FILE`. + """ + # + #* The argument for overriding _execute(): We must use environment with + # builder overrides applied (see BuilderBase.__init__(). Here it comes for + # free. + #* The argument against using 'emitter': The emitter is called too late + # by BuilderBase._execute(). If user calls, for example: + # + # env.POUpdate(LINGUAS_FILE = 'LINGUAS') + # + # the builder throws error, because it is called with target=None, + # source=None and is trying to "generate" sources or target list first. + # If user calls + # + # env.POUpdate(['foo', 'baz'], LINGUAS_FILE = 'LINGUAS') + # + # the env.BuilderWrapper() calls our builder with target=None, + # source=['foo', 'baz']. The BuilderBase._execute() then splits execution + # and execute iterativelly (recursion) self._execute(None, source[i]). + # After that it calls emitter (which is quite too late). The emitter is + # also called in each iteration, what makes things yet worse. + def __init__(self, env, **kw): + if not 'suffix' in kw: + kw['suffix'] = '$POSUFFIX' + if not 'src_suffix' in kw: + kw['src_suffix'] = '$POTSUFFIX' + if not 'src_builder' in kw: + kw['src_builder'] = '_POTUpdateBuilder' + if not 'single_source' in kw: + kw['single_source'] = True + alias = None + if 'target_alias' in kw: + alias = kw['target_alias'] + del kw['target_alias'] + if not 'target_factory' in kw: + kw['target_factory'] = _POTargetFactory(env, alias=alias).File + BuilderBase.__init__(self, **kw) + + def _execute(self, env, target, source, *args, **kw): + """ Execute builder's actions. + + Here we append to `target` the languages read from `$LINGUAS_FILE` and + apply `SCons.Builder.BuilderBase._execute()` separatelly to each target. + The arguments and return value are same as for + `SCons.Builder.BuilderBase._execute()`. + """ + import SCons.Util + import SCons.Node + linguas_files = None + if env.has_key('LINGUAS_FILE') and env['LINGUAS_FILE']: + linguas_files = env['LINGUAS_FILE'] + # This prevents endless recursion loop (we'll be invoked once for + # each target appended here, we must not extend the list again). + env['LINGUAS_FILE'] = None + linguas = _read_linguas_from_files(env,linguas_files) + if SCons.Util.is_List(target): + target.extend(linguas) + elif target is not None: + target = [target] + linguas + else: + target = linguas + if not target: + # Let the SCons.BuilderBase to handle this patologic situation + return BuilderBase._execute( self, env, target, source, *args, **kw) + # The rest is ours + if not SCons.Util.is_List(target): + target = [ target ] + result = [] + for tgt in target: + r = BuilderBase._execute( self, env, [tgt], source, *args, **kw) + result.extend(r) + if linguas_files is not None: + env['LINGUAS_FILE'] = linguas_files + return SCons.Node.NodeList(result) +############################################################################# + +import SCons.Environment +############################################################################# +def _translate(env, target=[], source=SCons.Environment._null, *args, **kw): + """ Function for `Translate()` pseudo-builder """ + pot = env.POTUpdate(None, source, *args, **kw) + po = env.POUpdate(target, pot, *args, **kw) + return po +############################################################################# + +############################################################################# +class RPaths(object): + """ Callable object, which returns pathnames relative to SCons current + working directory. + + It seems like `SCons.Node.FS.Base.get_path()` returns absolute paths + for nodes that are outside of current working directory (`env.fs.getcwd()`). + In `SConsToolGettext` way we often have `SConscript`, `POT` and `PO` files + within `po/` directory and source files (e.g. `*.c`) outside of it. When + generating `POT` template file, references to source files are written to + `POT` template, so a translator may later quickly jump to appropriate source + file and line from its `PO` editor (e.g. `poedit`). Relative paths in + `PO` file are usually interpreted by `PO` editor as paths relative to the + place, where `PO` file lives. The absolute paths would make resultant `POT` + file nonportable, as the references would be correct only on the machine, + where `POT` file was recently re-created. For such reason, we need a + function, which always returns relative paths. This is the purpose of + `RPaths` callable object. + + The `__call__` method returns paths relative to current woking directory, but + we assume, that *xgettext(1)* is run from the directory, where target file is + going to be created. + + Note, that this may not work for files distributed over several hosts or + across different drives on windows. We assume here, that single local + filesystem holds both source files and target `POT` templates. + + Intended use of `RPaths` - in `xgettext.py`:: + + def generate(env): + from GettextCommon import RPaths + ... + sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET, SOURCES)} $)' + env.Append( + ... + XGETTEXTCOM = 'XGETTEXT ... ' + sources, + ... + XgettextRPaths = RPaths(env) + ) + """ + # NOTE: This callable object returns pathnames of dirs/files relative to + # current working directory. The pathname remains relative also for entries + # that are outside of current working directory (node, that + # SCons.Node.FS.File and siblings return absolute path in such case). For + # simplicity we compute path relative to current working directory, this + # seems be enough for our purposes (don't need TARGET variable and + # SCons.Defaults.Variable_Caller stuff). + + def __init__(self, env): + """ Initialize `RPaths` callable object. + + **Arguments**: + + - *env* - a `SCons.Environment.Environment` object, defines *current + working dir*. + """ + self.env = env + + # FIXME: I'm not sure, how it should be implemented (what the *args are in + # general, what is **kw). + def __call__(self, nodes, *args, **kw): + """ Return nodes' paths (strings) relative to current working directory. + + **Arguments**: + + - *nodes* ([`SCons.Node.FS.Base`]) - list of nodes. + - *args* - currently unused. + - *kw* - currently unused. + + **Returns**: + + - Tuple of strings, which represent paths relative to current working + directory (for given environment). + """ + # os.path.relpath is available only on python >= 2.6. We use our own + # implementation. It's taken from BareNecessities package: + # http://jimmyg.org/work/code/barenecessities/index.html + from posixpath import curdir + def relpath(path, start=curdir): + import posixpath + """Return a relative version of a path""" + if not path: + raise ValueError("no path specified") + start_list = posixpath.abspath(start).split(posixpath.sep) + path_list = posixpath.abspath(path).split(posixpath.sep) + # Work out how much of the filepath is shared by start and path. + i = len(posixpath.commonprefix([start_list, path_list])) + rel_list = [posixpath.pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return posixpath.curdir + return posixpath.join(*rel_list) + import os + import SCons.Node.FS + rpaths = () + cwd = self.env.fs.getcwd().get_abspath() + for node in nodes: + rpath = None + if isinstance(node, SCons.Node.FS.Base): + rpath = relpath(node.get_abspath(), cwd) + # FIXME: Other types possible here? + if rpath is not None: + rpaths += (rpath,) + return rpaths +############################################################################# + +############################################################################# +def _init_po_files(target, source, env): + """ Action function for `POInit` builder. """ + nop = lambda target, source, env : 0 + if env.has_key('POAUTOINIT'): + autoinit = env['POAUTOINIT'] + else: + autoinit = False + # Well, if everything outside works well, this loop should do single + # iteration. Otherwise we are rebuilding all the targets even, if just + # one has changed (but is this out fault?). + for tgt in target: + if not tgt.exists(): + if autoinit: + action = SCons.Action.Action('$MSGINITCOM', '$MSGINITCOMSTR') + else: + msg = 'File ' + repr(str(tgt)) + ' does not exist. ' \ + + 'If you are a translator, you can create it through: \n' \ + + '$MSGINITCOM' + action = SCons.Action.Action(nop, msg) + status = action([tgt], source, env) + if status: return status + return 0 +############################################################################# + +############################################################################# +def _install_mo_files( env, localedir, source, domain, category="LC_MESSAGES" + , *args, **kw): + """ Function for `InstallMOFiles` pseudo-builder """ + import SCons.Util + import os + nodes = [] + for src in source: + lang = SCons.Util.splitext(os.path.basename(str(src)))[0] + tgt = os.path.join(localedir, lang, category, domain + "$MOSUFFIX") + nodes.extend(env.InstallAs(tgt, src, *args, **kw)) + return nodes +############################################################################# + +############################################################################# +def _detect_xgettext(env): + """ Detects *xgettext(1)* binary """ + if env.has_key('XGETTEXT'): + return env['XGETTEXT'] + xgettext = env.Detect('xgettext'); + if xgettext: + return xgettext + raise SCons.Errors.StopError(XgettextNotFound,"Could not detect xgettext") + return None +############################################################################# +def _xgettext_exists(env): + return _detect_xgettext(env) +############################################################################# + +############################################################################# +def _detect_msginit(env): + """ Detects *msginit(1)* program. """ + if env.has_key('MSGINIT'): + return env['MSGINIT'] + msginit = env.Detect('msginit'); + if msginit: + return msginit + raise SCons.Errors.StopError(MsginitNotFound, "Could not detect msginit") + return None +############################################################################# +def _msginit_exists(env): + return _detect_msginit(env) +############################################################################# + +############################################################################# +def _detect_msgmerge(env): + """ Detects *msgmerge(1)* program. """ + if env.has_key('MSGMERGE'): + return env['MSGMERGE'] + msgmerge = env.Detect('msgmerge'); + if msgmerge: + return msgmerge + raise SCons.Errors.StopError(MsgmergeNotFound, "Could not detect msgmerge") + return None +############################################################################# +def _msgmerge_exists(env): + return _detect_msgmerge(env) +############################################################################# + +############################################################################# +def _detect_msgfmt(env): + """ Detects *msgmfmt(1)* program. """ + if env.has_key('MSGFMT'): + return env['MSGFMT'] + msgfmt = env.Detect('msgfmt'); + if msgfmt: + return msgfmt + raise SCons.Errors.StopError(MsgfmtNotFound, "Could not detect msgfmt") + return None +############################################################################# +def _msgfmt_exists(env): + return _detect_msgfmt(env) +############################################################################# + +############################################################################# +def tool_list(platform, env): + """ List tools that shall be generated by top-level `gettext` tool """ + return [ 'xgettext', 'msginit', 'msgmerge', 'msgfmt' ] +############################################################################# + diff --git a/src/engine/SCons/Tool/gettext.py b/src/engine/SCons/Tool/gettext.py new file mode 100644 index 0000000..1055087 --- /dev/null +++ b/src/engine/SCons/Tool/gettext.py @@ -0,0 +1,47 @@ +"""gettext tool +""" + + +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +############################################################################# +def generate(env,**kw): + import SCons.Tool + from SConsToolGettext.GettextCommon \ + import _translate, _install_mo_files, tool_list + for t in tool_list(env['PLATFORM'], env): + env.Tool(t) + env.AddMethod(_translate, 'Translate') + # This is not ready yet + # env.AddMethod(_install_mo_files, 'InstallMOFiles') +############################################################################# + +############################################################################# +def exists(env): + from SConsToolGettext.GettextCommon \ + import _xgettext_exists, _msginit_exists, \ + _msgmerge_exists, _msgfmt_exists + return _xgettext_exists(env) and _msginit_exists(env) \ + and _msgmerge_exists(env) and _msgfmt_exists(env) +############################################################################# diff --git a/src/engine/SCons/Tool/gettext.xml b/src/engine/SCons/Tool/gettext.xml new file mode 100644 index 0000000..db76cc9 --- /dev/null +++ b/src/engine/SCons/Tool/gettext.xml @@ -0,0 +1,239 @@ +<!-- +__TOOL_COPYRIGHT__ + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="gettext"> +<summary> +This is actually a toolset, which supports internationalization and +localization of sofware being constructed with SCons. The toolset loads +following tools: + +<itemizedlist mark='opencircle'> + <listitem><para> + &t-link-xgettext; - to extract internationalized messages from source code to + <literal>POT</literal> file(s), + </para></listitem> + <listitem><para> + &t-link-msginit; - may be optionally used to initialize <literal>PO</literal> + files, + </para></listitem> + <listitem><para> + &t-link-msgmerge; - to update <literal>PO</literal> files, that already contain + translated messages,</para></listitem> + <listitem><para> + &t-link-msgfmt; - to compile textual <literal>PO</literal> file to binary + installable <literal>MO</literal> file. + </para></listitem> +</itemizedlist> + +When you enable &t-gettext;, it internally loads all abovementioned tools, +so you're encouraged to see their individual documentation. + +Each of the above tools provides its own builder(s) which may be used to +perform particular activities related to software internationalization. You +may be however interested in <emphasis>top-level</emphasis> builders +&b-Translate; and &b-InstallMOFiles; described few paragraphs later. + +To use &t-gettext; tools, copy <filename>SConsToolGettext</filename> +folder to your <filename>site_scons/</filename> and simply add +<literal>'gettext'</literal> tool to your environment: +<example> + env = Environment( tools = ['default', 'gettext'] ) +</example> +</summary> +<sets> +</sets> +<uses> +<!-- PLATFORM --> +</uses> +</tool> + +<builder name="Translate"> +<summary> +This pseudo-builder belongs to &t-link-gettext; toolset. The builder extracts +internationalized messages from source files, updates <literal>POT</literal> +template (if necessary) and then updates <literal>PO</literal> translations (if +necessary). If &cv-link-POAUTOINIT; is set, missing <literal>PO</literal> files +will be automatically created (i.e. without translator person intervention). +The variables &cv-link-LINGUAS_FILE; and &cv-link-POTDOMAIN; are taken into +acount too. All other construction variables used by &b-link-POTUpdate;, and +&b-link-POUpdate; work here too. + +<emphasis>Example 1</emphasis>. +The simplest way is to specify input files and output languages inline in +a SCons script when invoking &b-Translate; +<example> +# SConscript in 'po/' directory +env = Environment( tools = ["default", "gettext"] ) +env['POAUTOINIT'] = 1 +env.Translate(['en','pl'], ['../a.cpp','../b.cpp']) +</example> + +<emphasis>Example 2</emphasis>. +If you wish, you may also stick to conventional style known from +<productname>autotools</productname>, i.e. using +<filename>POTFILES.in</filename> and <filename>LINGUAS</filename> files +<example> +# LINGUAS +en pl +#end +</example> + +<example> +# POTFILES.in +a.cpp +b.cpp +# end +</example> + +<example> +# SConscript +env = Environment( tools = ["default", "gettext"] ) +env['POAUTOINIT'] = 1 +env['XGETTEXTPATH'] = ['../'] +env.Translate(LINGUAS_FILE = 1, XGETTEXTFROM = 'POTFILES.in') +</example> + +The last approach is perhaps the recommended one. It allows easily split +internationalization/localization onto separate SCons scripts, where a script +in source tree is responsible for translations (from sources to +<literal>PO</literal> files) and script(s) under variant directories are +responsible for compilation of <literal>PO</literal> to <literal>MO</literal> +files to and for installation of <literal>MO</literal> files. The "gluing +factor" synchronizing these two scripts is then the content of +<filename>LINGUAS</filename> file. Note, that the updated +<literal>POT</literal> and <literal>PO</literal> files are usually going to be +committed back to the repository, so they must be updated within the source +directory (and not in variant directories). Additionaly, the file listing of +<filename>po/</filename> directory contains <filename>LINGUAS</filename> file, +so the source tree looks familiar to translators, and they may work with the +project in their usual way. + +<emphasis>Example 3</emphasis>. +Let's prepare a development tree as below +<example> + project/ + + SConstruct + + build/ + + src/ + + po/ + + SConscript + + SConscript.i18n + + POTFILES.in + + LINGUAS +</example> +with <filename>build</filename> being variant directory. Write the top-level +<filename>SConstruct</filename> script as follows +<example> + # SConstruct + env = Environment( tools = ["default", "gettext"] ) + VariantDir('build', 'src', duplicate = 0) + env['POAUTOINIT'] = 1 + SConscript('src/po/SConscript.i18n', exports = 'env') + SConscript('build/po/SConscript', exports = 'env') +</example> +the <filename>src/po/SConscript.i18n</filename> as +<example> + # src/po/SConscript.i18n + Import('env') + env.Translate(LINGUAS_FILE=1, XGETTEXTFROM='POTFILES.in', XGETTEXTPATH=['../']) +</example> +and the <filename>src/po/SConscript</filename> +<example> + # src/po/SConscript + Import('env') + env.MOFiles(LINGUAS_FILE = 1) +</example> +Such setup produces <literal>POT</literal> and <literal>PO</literal> files +under source tree in <filename>src/po/</filename> and binary +<literal>MO</literal> files under variant tree in +<filename>build/po/</filename>. This way the <literal>POT</literal> and +<literal>PO</literal> files are separated from other output files, which must +not be committed back to source repositories (e.g. <literal>MO</literal> +files). + +<note><para>In above example, the <literal>PO</literal> files are not updated, +nor created automatically when you issue <command>scons '.'</command> command. +The files must be updated (created) by hand via <command>scons +po-update</command> and then <literal>MO</literal> files can be compiled by +running <command>scons '.'</command>.</para></note> + +</summary> +</builder> + +<!-- +<builder name="InstallMOFiles"> +<summary> +This is not implemented yet. +Install <literal>MO</literal> catalog files into system directories. + +The parameters are: +- <literal>localedir</literal> - system locale base directory, e.g. <literal>/usr/share/locale</literal> +- <literal>source</literal> - list of <literal>MO</literal> files to install +- <literal>domain</literal> - domain, i.e. your package/program name +- <literal>category</literal> - locale category, e.g. <literal>LC_MESSAGES</literal> + +The installation goes in standard way. For example, if +<literal>localedir="/usr/share/locale"</literal>, <literal>domain="program1"</literal>, +<literal>category="LC_MESSAGES"</literal>, <literal>sources=['en.mo', 'fr.mo']</literal>, then the +installation goes as follows: +<example> +en.mo ===> /usr/share/locale/en/LC_MESSAGES/program1.mo +fr.mo ===> /usr/share/locale/fr/LC_MESSAGES/program1.mo +</example> +The <literal>InstallMOFiles</literal> builder uses internaly <literal>InstallAs</literal> builder, so all +the features of <literal>InstallAs</literal> (e.g. <literal>xxinstall-sandbox</literal>) should work. +<example> +TODO: +</example> +</summary> +</builder> +--> + +<cvar name="POTDOMAIN"> +<summary> +The &cv-POTDOMAIN; defines default domain, used to generate +<literal>POT</literal> filename as <filename>&cv-POTDOMAIN;.pot</filename> when +no <literal>POT</literal> file name is provided by the user. This applies to +&b-link-POTUpdate;, &b-link-POInit; and &b-link-POUpdate; builders (and +builders, that use them, e.g. &b-Translate;). Normally (if &cv-POTDOMAIN; is +not defined), the builders use <filename>messages.pot</filename> as default +<literal>POT</literal> file name. +</summary> +</cvar> + +<cvar name="POAUTOINIT"> +<summary> +The &cv-POAUTOINIT; variable, if set to <literal>True</literal> (on non-zero +numeric value), let the SConsToolGettext to automatically initialize +<emphasis>missing</emphasis> <literal>PO</literal> files with +<command>msginit(1)</command>. This applies to both, +&b-link-POInit; and &b-link-POUpdate; builders (and others that use any of +them). +</summary> +</cvar> + +<cvar name="LINGUAS_FILE"> +<summary> +The &cv-LINGUAS_FILE; defines file(s) containing list of additional linguas +to be processed by &b-link-POInit;, &b-link-POUpdate; or &b-link-MOFiles; +builders. It also affects &b-link-Translate; builder. If the variable contains +a string, it defines name of the list file. The &cv-LINGUAS_FILE; may be a +list of file names as well. If &cv-LINGUAS_FILE; is set to +<literal>True</literal> (or non-zero numeric value), the list will be read from +default file named +<filename>LINGUAS</filename>. + +</summary> +</cvar> + +<scons_function name="Dummy"> +<arguments> +TODO: Try to remove me. +</arguments> +<summary> +TODO: Try to remove me. +</summary> +</scons_function> diff --git a/src/engine/SCons/Tool/msgfmt.py b/src/engine/SCons/Tool/msgfmt.py new file mode 100644 index 0000000..ce8cff8 --- /dev/null +++ b/src/engine/SCons/Tool/msgfmt.py @@ -0,0 +1,101 @@ +""" msgfmt tool """ + +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +from SCons.Builder import BuilderBase +############################################################################# +class _MOFileBuilder(BuilderBase): + """ The builder class for `MO` files. + + The reason for this builder to exists and its purpose is quite simillar + as for `SConsToolGettext._POFileBuilder`. This time, we extend list of + sources, not targets, and call `BuilderBase._execute()` only once (as we + assume single-target here). + """ + + def _execute(self, env, target, source, *args, **kw): + # Here we add support for 'LINGUAS_FILE' keyword. Emitter is not suitable + # in this case, as it is called too late (after multiple sources + # are handled single_source builder. + import SCons.Util + from SCons.Tool.GettextCommon import _read_linguas_from_files + linguas_files = None + if env.has_key('LINGUAS_FILE') and env['LINGUAS_FILE'] is not None: + linguas_files = env['LINGUAS_FILE'] + # This should prevent from endless recursion. + env['LINGUAS_FILE'] = None + # We read only languages. Suffixes shall be added automatically. + linguas = _read_linguas_from_files(env, linguas_files) + if SCons.Util.is_List(source): + source.extend(linguas) + elif source is not None: + source = [source] + linguas + else: + source = linguas + result = BuilderBase._execute(self,env,target,source,*args, **kw) + if linguas_files is not None: + env['LINGUAS_FILE'] = linguas_files + return result +############################################################################# + +############################################################################# +def _create_mo_file_builder(env, **kw): + """ Create builder object for `MOFiles` builder """ + import SCons.Action + # FIXME: What factory use for source? Ours or their? + kw['action'] = SCons.Action.Action('$MSGFMTCOM','$MSGFMTCOMSTR') + kw['suffix'] = '$MOSUFFIX' + kw['src_suffix'] = '$POSUFFIX' + kw['src_builder'] = '_POUpdateBuilder' + kw['single_source'] = True + return _MOFileBuilder(**kw) +############################################################################# + +############################################################################# +def generate(env,**kw): + """ Generate `msgfmt` tool """ + import SCons.Util + from SCons.Tool.GettextCommon import _detect_msgfmt + env['MSGFMT'] = _detect_msgfmt(env) + env.SetDefault( + MSGFMTFLAGS = [ SCons.Util.CLVar('-c') ], + MSGFMTCOM = '$MSGFMT $MSGFMTFLAGS -o $TARGET $SOURCE', + MSGFMTCOMSTR = '', + MOSUFFIX = '.mo' + ) + env.Append( BUILDERS = { 'MOFiles' : _create_mo_file_builder(env) } ) +############################################################################# + +############################################################################# +def exists(env): + """ Check if the tool exists """ + from SCons.Tool.GettextCommon import _msgfmt_exists + return _msgfmt_exists(env) +############################################################################# + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/msgfmt.xml b/src/engine/SCons/Tool/msgfmt.xml new file mode 100644 index 0000000..93e6e02 --- /dev/null +++ b/src/engine/SCons/Tool/msgfmt.xml @@ -0,0 +1,101 @@ +<!-- +__TOOL_COPYRIGHT__ + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="msgfmt"> +<summary> +This scons tool is a part of scons &t-link-gettext; toolset. It provides scons +interface to <command>msgfmt(1)</command> command, which generates binary +message catalog (<literal>MO</literal>) from a textual translation description +(<literal>PO</literal>). +</summary> +<sets> +MOSUFFIX +MSGFMT +MSGFMTCOM +MSGFMTCOMSTR +MSGFMTFLAGS +</sets> +<uses> +LINGUAS_FILE +</uses> +</tool> + +<builder name="MOFiles"> +<summary> +This builder belongs to &t-link-msgfmt; tool. The builder compiles +<literal>PO</literal> files to <literal>MO</literal> files. + +<emphasis>Example 1</emphasis>. +Create <filename>pl.mo</filename> and <filename>en.mo</filename> by compiling +<filename>pl.po</filename> and <filename>en.po</filename>: +<example> + # ... + env.MOFiles(['pl', 'en']) +</example> + +<emphasis>Example 2</emphasis>. +Compile files for languages defined in <filename>LINGUAS</filename> file: +<example> + # ... + env.MOFiles(LINGUAS_FILE = 1) +</example> + +<emphasis>Example 3</emphasis>. +Create <filename>pl.mo</filename> and <filename>en.mo</filename> by compiling +<filename>pl.po</filename> and <filename>en.po</filename> plus files for +languages defined in <filename>LINGUAS</filename> file: +<example> + # ... + env.MOFiles(['pl', 'en'], LINGUAS_FILE = 1) +</example> + +<emphasis>Example 4</emphasis>. +Compile files for languages defined in <filename>LINGUAS</filename> file +(another version): +<example> + # ... + env['LINGUAS_FILE'] = 1 + env.MOFiles() +</example> +</summary> +</builder> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MOSUFFIX"> +<summary> +Suffix used for <literal>MO</literal> files (default: <literal>'.mo'</literal>). +See &t-link-msgfmt; tool and &b-link-MOFiles; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGFMT"> +<summary> +Absolute path to <command>msgfmt(1)</command> binary, found by +<function>Detect()</function>. +See &t-link-msgfmt; tool and &b-link-MOFiles; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGFMTCOM"> +<summary> +Complete command line to run <command>msgfmt(1)</command> program. +See &t-link-msgfmt; tool and &b-link-MOFiles; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGFMTCOMSTR"> +<summary> +String to display when <command>msgfmt(1)</command> is invoked +(default: <literal>''</literal>, which means ``print &cv-link-MSGFMTCOM;''). +See &t-link-msgfmt; tool and &b-link-MOFiles; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGFMTFLAGS"> +<summary> +Additional flags to <command>msgfmt(1)</command>. +See &t-link-msgfmt; tool and &b-link-MOFiles; builder. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/msginit.py b/src/engine/SCons/Tool/msginit.py new file mode 100644 index 0000000..164215b --- /dev/null +++ b/src/engine/SCons/Tool/msginit.py @@ -0,0 +1,111 @@ +""" msginit tool + +Tool specific initialization of msginit tool. +""" + +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Warnings +import SCons.Builder +import re + +############################################################################# +def _optional_no_translator_flag(env): + """ Return '--no-translator' flag if we run *msginit(1)* in non-interactive + mode.""" + import SCons.Util + if env.has_key('POAUTOINIT'): + autoinit = env['POAUTOINIT'] + else: + autoinit = False + if autoinit: + return [SCons.Util.CLVar('--no-translator')] + else: + return [SCons.Util.CLVar('')] +############################################################################# + +############################################################################# +def _POInitBuilder(env, **kw): + """ Create builder object for `POInit` builder. """ + import SCons.Action + from SCons.Tool.GettextCommon import _init_po_files, _POFileBuilder + action = SCons.Action.Action(_init_po_files, None) + return _POFileBuilder(env, action=action, target_alias='$POCREATE_ALIAS') +############################################################################# + +############################################################################# +from SCons.Environment import _null +############################################################################# +def _POInitBuilderWrapper(env, target=None, source=_null, **kw): + """ Wrapper for _POFileBuilder. We use it to make user's life easier. + + This wrapper checks for `$POTDOMAIN` construction variable (or override in + `**kw`) and treats it appropriatelly. + """ + if source is _null: + if 'POTDOMAIN' in kw: + domain = kw['POTDOMAIN'] + elif env.has_key('POTDOMAIN'): + domain = env['POTDOMAIN'] + else: + domain = 'messages' + source = [ domain ] # NOTE: Suffix shall be appended automatically + return env._POInitBuilder(target, source, **kw) +############################################################################# + +############################################################################# +def generate(env,**kw): + """ Generate the `msginit` tool """ + import SCons.Util + from SCons.Tool.GettextCommon import _detect_msginit + env['MSGINIT'] = _detect_msginit(env) + msginitcom = '$MSGINIT ${_MSGNoTranslator(__env__)} -l ${_MSGINITLOCALE}' \ + + ' $MSGINITFLAGS -i $SOURCE -o $TARGET' + env.SetDefault( + POSUFFIX = '.po', + _MSGINITLOCALE = '${TARGET.filebase}', + _MSGNoTranslator = _optional_no_translator_flag, + MSGINITCOM = msginitcom, + MSGINITCOMSTR = '', + MSGINITFLAGS = [ ], + POAUTOINIT = False, + POCREATE_ALIAS = 'po-create' + ) + env.Append( BUILDERS = { '_POInitBuilder' : _POInitBuilder(env) } ) + env.AddMethod(_POInitBuilderWrapper, 'POInit') + env.AlwaysBuild(env.Alias('$POCREATE_ALIAS')) +############################################################################# + +############################################################################# +def exists(env): + """ Check if the tool exists """ + from SCons.Tool.GettextCommon import _msginit_exists + return _msginit_exists(env) +############################################################################# + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/msginit.xml b/src/engine/SCons/Tool/msginit.xml new file mode 100644 index 0000000..527a168 --- /dev/null +++ b/src/engine/SCons/Tool/msginit.xml @@ -0,0 +1,167 @@ +<!-- +__TOOL_COPYRIGHT__ + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="msginit"> +<summary> +This scons tool is a part of scons &t-link-gettext; toolset. It provides +scons interface to <command>msginit(1)</command> program, which creates new +<literal>PO</literal> file, initializing the meta information with values from +user's environment (or options). +</summary> +<sets> +MSGINIT +MSGINITCOM +MSGINITCOMSTR +MSGINITFLAGS +POAUTOINIT +POCREATE_ALIAS +POSUFFIX +_MSGINITLOCALE +</sets> +<uses> +POTDOMAIN +LINGUAS_FILE +POAUTOINIT +</uses> +</tool> + +<builder name="POInit"> +<summary> +This builder belongs to &t-link-msginit; tool. The builder initializes missing +<literal>PO</literal> file(s) if &cv-link-POAUTOINIT; is set. If +&cv-link-POAUTOINIT; is not set (default), &b-POInit; prints instruction for +user (that is supposed to be a translator), telling how the +<literal>PO</literal> file should be initialized. In normal projects +<emphasis>you should not use &b-POInit; and use &b-link-POUpdate; +instead</emphasis>. &b-link-POUpdate; chooses intelligently between +<command>msgmerge(1)</command> and <command>msginit(1)</command>. &b-POInit; +always uses <command>msginit(1)</command> and should be regarded as builder for +special purposes or for temporary use (e.g. for quick, one time initialization +of a bunch of <literal>PO</literal> files) or for tests. + +Target nodes defined through &b-POInit; are not built by default (they're +<literal>Ignore</literal>d from <literal>'.'</literal> node) but are added to +special <literal>Alias</literal> (<literal>'po-create'</literal> by default). +The alias name may be changed through the &cv-link-POCREATE_ALIAS; +construction variable. All <literal>PO</literal> files defined through +&b-POInit; may be easily initialized by <command>scons po-create</command>. + +<emphasis>Example 1</emphasis>. +Initialize <filename>en.po</filename> and <filename>pl.po</filename> from +<filename>messages.pot</filename>: +<example> + # ... + env.POInit(['en', 'pl']) # messages.pot --> [en.po, pl.po] +</example> + +<emphasis>Example 2</emphasis>. +Initialize <filename>en.po</filename> and <filename>pl.po</filename> from +<filename>foo.pot</filename>: +<example> + # ... + env.POInit(['en', 'pl'], ['foo']) # foo.pot --> [en.po, pl.po] +</example> + +<emphasis>Example 3</emphasis>. +Initialize <filename>en.po</filename> and <filename>pl.po</filename> from +<filename>foo.pot</filename> but using &cv-link-POTDOMAIN; construction +variable: +<example> + # ... + env.POInit(['en', 'pl'], POTDOMAIN='foo') # foo.pot --> [en.po, pl.po] +</example> + +<emphasis>Example 4</emphasis>. +Initialize <literal>PO</literal> files for languages defined in +<filename>LINGUAS</filename> file. The files will be initialized from template +<filename>messages.pot</filename>: +<example> + # ... + env.POInit(LINGUAS_FILE = 1) # needs 'LINGUAS' file +</example> + +<emphasis>Example 5</emphasis>. +Initialize <filename>en.po</filename> and <filename>pl.pl</filename> +<literal>PO</literal> files plus files for languages defined in +<filename>LINGUAS</filename> file. The files will be initialized from template +<filename>messages.pot</filename>: +<example> + # ... + env.POInit(['en', 'pl'], LINGUAS_FILE = 1) +</example> + +<emphasis>Example 6</emphasis>. +You may preconfigure your environment first, and then initialize +<literal>PO</literal> files: +<example> + # ... + env['POAUTOINIT'] = 1 + env['LINGUAS_FILE'] = 1 + env['POTDOMAIN'] = 'foo' + env.POInit() +</example> +which has same efect as: +<example> + # ... + env.POInit(POAUTOINIT = 1, LINGUAS_FILE = 1, POTDOMAIN = 'foo') +</example> +</summary> +</builder> + +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="POCREATE_ALIAS"> +<summary> +Common alias for all <literal>PO</literal> files created with &b-POInit; +builder (default: <literal>'po-create'</literal>). +See &t-link-msginit; tool and &b-link-POInit; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="POSUFFIX"> +<summary> +Suffix used for <literal>PO</literal> files (default: <literal>'.po'</literal>) +See &t-link-msginit; tool and &b-link-POInit; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGINIT"> +<summary> +Path to <command>msginit(1)</command> program (found via +<literal>Detect()</literal>). +See &t-link-msginit; tool and &b-link-POInit; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGINITCOM"> +<summary> +Complete command line to run <command>msginit(1)</command> program. +See &t-link-msginit; tool and &b-link-POInit; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGINITCOMSTR"> +<summary> +String to display when <command>msginit(1)</command> is invoked +(default: <literal>''</literal>, which means ``print &cv-link-MSGINITCOM;''). +See &t-link-msginit; tool and &b-link-POInit; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGINITFLAGS"> +<summary> +List of additional flags to <command>msginit(1)</command> (default: +<literal>[]</literal>). +See &t-link-msginit; tool and &b-link-POInit; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="_MSGINITLOCALE"> +<summary> +Internal ``macro''. Computes locale (language) name based on target filename +(default: <literal>'${TARGET.filebase}' </literal>). +</summary> +See &t-link-msginit; tool and &b-link-POInit; builder. +</cvar> diff --git a/src/engine/SCons/Tool/msgmerge.py b/src/engine/SCons/Tool/msgmerge.py new file mode 100644 index 0000000..19db36c --- /dev/null +++ b/src/engine/SCons/Tool/msgmerge.py @@ -0,0 +1,97 @@ +""" msgmerget tool + +Tool specific initialization for `msgmerge` tool. +""" + +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +############################################################################# +def _update_or_init_po_files(target, source, env): + """ Action function for `POUpdate` builder """ + import SCons.Action + from SCons.Tool.GettextCommon import _init_po_files + for tgt in target: + if tgt.rexists(): + action = SCons.Action.Action('$MSGMERGECOM', '$MSGMERGECOMSTR') + else: + action = _init_po_files + status = action([tgt], source, env) + if status : return status + return 0 +############################################################################# + +############################################################################# +def _POUpdateBuilder(env, **kw): + """ Create an object of `POUpdate` builder """ + import SCons.Action + from SCons.Tool.GettextCommon import _POFileBuilder + action = SCons.Action.Action(_update_or_init_po_files, None) + return _POFileBuilder(env, action=action, target_alias='$POUPDATE_ALIAS') +############################################################################# + +############################################################################# +from SCons.Environment import _null +############################################################################# +def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): + """ Wrapper for `POUpdate` builder - make user's life easier """ + if source is _null: + if 'POTDOMAIN' in kw: + domain = kw['POTDOMAIN'] + elif env.has_key('POTDOMAIN') and env['POTDOMAIN']: + domain = env['POTDOMAIN'] + else: + domain = 'messages' + source = [ domain ] # NOTE: Suffix shall be appended automatically + return env._POUpdateBuilder(target, source, **kw) +############################################################################# + +############################################################################# +def generate(env,**kw): + """ Generate the `xgettext` tool """ + from SCons.Tool.GettextCommon import _detect_msgmerge + env['MSGMERGE'] = _detect_msgmerge(env) + env.SetDefault( + POSUFFIX = '.po', + MSGMERGECOM = '$MSGMERGE $MSGMERGEFLAGS --update $TARGET $SOURCE', + MSGMERGECOMSTR = '', + MSGMERGEFLAGS = [ ], + POUPDATE_ALIAS = 'po-update' + ) + env.Append(BUILDERS = { '_POUpdateBuilder':_POUpdateBuilder(env) }) + env.AddMethod(_POUpdateBuilderWrapper, 'POUpdate') + env.AlwaysBuild(env.Alias('$POUPDATE_ALIAS')) +############################################################################# + +############################################################################# +def exists(env): + """ Check if the tool exists """ + from SCons.Tool.GettextCommon import _msgmerge_exists + return _msgmerge_exists(env) +############################################################################# + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/msgmerge.xml b/src/engine/SCons/Tool/msgmerge.xml new file mode 100644 index 0000000..1c567a1 --- /dev/null +++ b/src/engine/SCons/Tool/msgmerge.xml @@ -0,0 +1,157 @@ +<!-- +__TOOL_COPYRIGHT__ + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="msgmerge"> +<summary> +This scons tool is a part of scons &t-link-gettext; toolset. It provides +scons interface to <command>msgmerge(1)</command> command, which merges two +Uniform style <filename>.po</filename> files together. +</summary> +<sets> +MSGMERGE +MSGMERGECOM +MSGMERGECOMSTR +MSGMERGEFLAGS +POSUFFIX +POUPDATE_ALIAS +</sets> +<uses> +POTDOMAIN +LINGUAS_FILE +POAUTOINIT +</uses> +</tool> + +<builder name="POUpdate"> +<summary> +The builder belongs to &t-link-msgmerge; tool. The builder updates +<literal>PO</literal> files with <command>msgmerge(1)</command>, or initializes +missing <literal>PO</literal> files as described in documentation of +&t-link-msginit; tool and &b-link-POInit; builder (see also +&cv-link-POAUTOINIT;). Note, that &b-POUpdate; <emphasis>does not add its +targets to <literal>po-create</literal> alias</emphasis> as &b-link-POInit; +does. + +Target nodes defined through &b-POUpdate; are not built by default +(they're <literal>Ignore</literal>d from <literal>'.'</literal> node). Instead, +they are added automatically to special <literal>Alias</literal> +(<literal>'po-update'</literal> by default). The alias name may be changed +through the &cv-link-POUPDATE_ALIAS; construction variable. You can easilly +update <literal>PO</literal> files in your project by <command>scons +po-update</command>. + +<emphasis>Example 1.</emphasis> +Update <filename>en.po</filename> and <filename>pl.po</filename> from +<filename>messages.pot</filename> template (see also &cv-link-POTDOMAIN;), +assuming that the later one exists or there is rule to build it (see +&b-link-POTUpdate;): +<example> + # ... + env.POUpdate(['en','pl']) # messages.pot --> [en.po, pl.po] +</example> + +<emphasis>Example 2.</emphasis> +Update <filename>en.po</filename> and <filename>pl.po</filename> from +<filename>foo.pot</filename> template: +<example> + # ... + env.POUpdate(['en', 'pl'], ['foo']) # foo.pot --> [en.po, pl.pl] +</example> + +<emphasis>Example 3.</emphasis> +Update <filename>en.po</filename> and <filename>pl.po</filename> from +<filename>foo.pot</filename> (another version): +<example> + # ... + env.POUpdate(['en', 'pl'], POTDOMAIN='foo') # foo.pot -- > [en.po, pl.pl] +</example> + +<emphasis>Example 4.</emphasis> +Update files for languages defined in <filename>LINGUAS</filename> file. The +files are updated from <filename>messages.pot</filename> template: +<example> + # ... + env.POUpdate(LINGUAS_FILE = 1) # needs 'LINGUAS' file +</example> + +<emphasis>Example 5.</emphasis> +Same as above, but update from <filename>foo.pot</filename> template: +<example> + # ... + env.POUpdate(LINGUAS_FILE = 1, source = ['foo']) +</example> + +<emphasis>Example 6.</emphasis> +Update <filename>en.po</filename> and <filename>pl.po</filename> plus files for +languages defined in <filename>LINGUAS</filename> file. The files are updated +from <filename>messages.pot</filename> template: +<example> + # produce 'en.po', 'pl.po' + files defined in 'LINGUAS': + env.POUpdate(['en', 'pl' ], LINGUAS_FILE = 1) +</example> + +<emphasis>Example 7.</emphasis> +Use &cv-link-POAUTOINIT; to automatically initialize <literal>PO</literal> file +if it doesn't exist: +<example> + # ... + env.POUpdate(LINGUAS_FILE = 1, POAUTOINIT = 1) +</example> + +<emphasis>Example 8.</emphasis> +Update <literal>PO</literal> files for languages defined in +<filename>LINGUAS</filename> file. The files are updated from +<filename>foo.pot</filename> template. All necessary settings are +pre-configured via environment. +<example> + # ... + env['POAUTOINIT'] = 1 + env['LINGUAS_FILE'] = 1 + env['POTDOMAIN'] = 'foo' + env.POUpdate() +</example> + +</summary> +</builder> + +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="POUPDATE_ALIAS"> +<summary> +Common alias for all <literal>PO</literal> files being defined with +&b-link-POUpdate; builder (default: <literal>'po-update'</literal>). +See &t-link-msgmerge; tool and &b-link-POUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGMERGE"> +<summary> +Absolute path to <command>msgmerge(1)</command> binary as found by +<function>Detect()</function>. +See &t-link-msgmerge; tool and &b-link-POUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGMERGECOM"> +<summary> +Complete command line to run <command>msgmerge(1)</command> command. +See &t-link-msgmerge; tool and &b-link-POUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGMERGECOMSTR"> +<summary> +String to be displayed when <command>msgmerge(1)</command> is invoked +(default: <literal>''</literal>, which means ``print &cv-link-MSGMERGECOM;''). +See &t-link-msgmerge; tool and &b-link-POUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="MSGMERGEFLAGS"> +<summary> +Additional flags to <command>msgmerge(1)</command> command. +See &t-link-msgmerge; tool and &b-link-POUpdate; builder. +</summary> +</cvar> diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py new file mode 100644 index 0000000..0495174 --- /dev/null +++ b/src/engine/SCons/Tool/xgettext.py @@ -0,0 +1,331 @@ +""" xgettext tool + +Tool specific initialization of `xgettext` tool. +""" + +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +############################################################################# +class _CmdRunner(object): + """ Callabe object, which runs shell command storing its stdout and stderr to + variables. It also provides `strfunction()` method, which shall be used by + scons Action objects to print command string. """ + + def __init__( self, command, commandstr = None): + self.out = None + self.err = None + self.status = None + self.command = command + self.commandstr = commandstr + + def __call__(self, target, source, env): + import SCons.Action + import subprocess + import os + import sys + kw = { + 'stdin' : 'devnull', + 'stdout' : subprocess.PIPE, + 'stderr' : subprocess.PIPE, + 'universal_newlines' : True, + 'shell' : True + } + command = env.subst(self.command, target = target, source = source) + proc = SCons.Action._subproc(env, command, **kw) + self.out, self.err = proc.communicate() + self.status = proc.wait() + if self.err: sys.stderr.write(unicode(self.err)) + return self.status + + def strfunction(self, target, source, env): + import os + comstr = self.commandstr + if env.subst(comstr, target = target, source = source) == "": + comstr = self.command + s = env.subst(comstr, target = target, source = source) + return s +############################################################################# + +############################################################################# +def _update_pot_file(target, source, env): + """ Action function for `POTUpdate` builder """ + import re + import os + import SCons.Action + nop = lambda target, source, env : 0 + + # Save scons cwd and os cwd (NOTE: they may be different. After the job, we + # revert ech one to its original state). + save_cwd = env.fs.getcwd() + save_os_cwd = os.getcwd() + chdir = target[0].dir + chdir_str = repr(chdir.get_abspath()) + # Print chdir message (employ SCons.Action.Action for that. It knows better + # than me how to to this correctly). + env.Execute(SCons.Action.Action(nop, "Entering " + chdir_str)) + # Go to target's directory and do our job + env.fs.chdir(chdir, 1) # Go into target's directory + try: + cmd = _CmdRunner('$XGETTEXTCOM', '$XGETTEXTCOMSTR') + action = SCons.Action.Action(cmd, strfunction=cmd.strfunction) + status = action([ target[0] ], source, env) + except: + # Something went wrong. + env.Execute(SCons.Action.Action(nop, "Leaving " + chdir_str)) + # Revert working dirs to previous state and re-throw exception. + env.fs.chdir(save_cwd, 0) + os.chdir(save_os_cwd) + raise + # Print chdir message. + env.Execute(SCons.Action.Action(nop, "Leaving " + chdir_str)) + # Revert working dirs to previous state. + env.fs.chdir(save_cwd, 0) + os.chdir(save_os_cwd) + # If the command was not successfull, return error code. + if status: return status + + new_content = cmd.out + + if not new_content: + # When xgettext finds no internationalized messages, no *.pot is created + # (because we don't want to bother translators with empty POT files). + needs_update = False + explain = "no internationalized messages encountered" + else: + if target[0].exists(): + # If the file already exists, it's left unaltered unless its messages + # are outdated (w.r.t. to these recovered by xgettext from sources). + old_content = target[0].get_text_contents() + re_cdate = re.compile(r'^"POT-Creation-Date: .*"$[\r\n]?', re.M) + old_content_nocdate = re.sub(re_cdate,"",old_content) + new_content_nocdate = re.sub(re_cdate,"",new_content) + if(old_content_nocdate == new_content_nocdate): + # Messages are up-to-date + needs_update = False + explain = "messages in file found to be up-to-date" + else: + # Messages are outdated + needs_update = True + explain = "messages in file were outdated" + else: + # No POT file found, create new one + needs_update = True + explain = "new file" + if needs_update: + # Print message employing SCons.Action.Action for that. + msg = "Writting " + repr(str(target[0])) + " (" + explain + ")" + env.Execute(SCons.Action.Action(nop, msg)) + f = open(str(target[0]),"w") + f.write(new_content) + f.close() + return 0 + else: + # Print message employing SCons.Action.Action for that. + msg = "Not writting " + repr(str(target[0])) + " (" + explain + ")" + env.Execute(SCons.Action.Action(nop, msg)) + return 0 +############################################################################# + +############################################################################# +from SCons.Builder import BuilderBase +############################################################################# +class _POTBuilder(BuilderBase): + def _execute(self, env, target, source, *args): + if not target: + if env.has_key('POTDOMAIN') and env['POTDOMAIN']: + domain = env['POTDOMAIN'] + else: + domain = 'messages' + target = [ domain ] + return BuilderBase._execute(self, env, target, source, *args) +############################################################################# + +############################################################################# +def _scan_xgettext_from_files(target, source, env, files = None, path = None): + """ Parses `POTFILES.in`-like file and returns list of extracted file names. + """ + import re + import SCons.Util + import SCons.Node.FS + + if files is None: + return 0 + if not SCons.Util.is_List(files): + files = [ files ] + + if path is None: + if env.has_key('XGETTEXTPATH'): + path = env['XGETTEXTPATH'] + else: + path = [] + if not SCons.Util.is_List(path): + path = [ path ] + + dirs = () + for p in path: + if not isinstance(p, SCons.Node.FS.Base): + if SCons.Util.is_String(p): + p = env.subst(p, source = source, target = target) + p = env.arg2nodes(p, env.fs.Dir) + if SCons.Util.is_List(p): + dirs = dirs + tuple(p) + else: + dirs += (p,) + if not dirs: + dirs = (env.fs.getcwd(),) + + re_comment = re.compile(r'^#[^\n\r]*$\r?\n?', re.M) + re_emptyln = re.compile(r'^[ \t\r]*$\r?\n?', re.M) + re_trailws = re.compile(r'[ \t\r]+$') + for f in files: + # Find files in search path $XGETTEXTPATH + if isinstance(f, SCons.Node.FS.Base) and f.rexists(): + contents = f.get_text_contents() + contents = re_comment.sub("", contents) + contents = re_emptyln.sub("", contents) + contents = re_trailws.sub("", contents) + depnames = contents.splitlines() + for depname in depnames: + depfile = SCons.Node.FS.find_file(depname, dirs) + if not depfile: + depfile = env.arg2nodes(depname, dirs[0].File) + env.Depends(target, depfile) + return 0 +############################################################################# + +############################################################################# +def _pot_update_emitter(target, source, env): + """ Emitter function for `POTUpdate` builder """ + from SCons.Tool.GettextCommon import _POTargetFactory + import SCons.Util + import SCons.Node.FS + + if env.has_key('XGETTEXTFROM'): + xfrom = env['XGETTEXTFROM'] + else: + return target, source + if not SCons.Util.is_List(xfrom): + xfrom = [ xfrom ] + + files = [] + for xf in xfrom: + if not isinstance(xf, SCons.Node.FS.Base): + if SCons.Util.is_String(xf): + xf = env.subst(xf, source = source, target = target) + xf = env.arg2nodes(xf) + if SCons.Util.is_List(xf): + files.extend(xf) + else: + files.append(xf) + if files: + env.Depends(target, files) + _scan_xgettext_from_files(target, source, env, files) + return target, source +############################################################################# + +############################################################################# +from SCons.Environment import _null +############################################################################# +def _POTUpdateBuilderWrapper(env, target=None, source=_null, **kw): + return env._POTUpdateBuilder(target, source, **kw) +############################################################################# + +############################################################################# +def _POTUpdateBuilder(env, **kw): + """ Creates `POTUpdate` builder object """ + import SCons.Action + from SCons.Tool.GettextCommon import _POTargetFactory + kw['action'] = SCons.Action.Action(_update_pot_file, None) + kw['suffix'] = '$POTSUFFIX' + kw['target_factory'] = _POTargetFactory(env, alias='$POTUPDATE_ALIAS').File + kw['emitter'] = _pot_update_emitter + return _POTBuilder(**kw) +############################################################################# + +############################################################################# +def generate(env,**kw): + """ Generate `xgettext` tool """ + import SCons.Util + from SCons.Tool.GettextCommon import RPaths, _detect_xgettext + + env['XGETTEXT'] = _detect_xgettext(env) + # NOTE: sources="$SOURCES" would work as well. However, we use following + # construction to convert absolute paths provided by scons onto paths + # relative to current working dir. Note, that scons expands $SOURCE(S) to + # absolute paths for sources $SOURCE(s) outside of current subtree (e.g. in + # "../"). With source=$SOURCE these absolute paths would be written to the + # resultant *.pot file (and its derived *.po files) as references to lines in + # source code (e.g. referring lines in *.c files). Such references would be + # correct (e.g. in poedit) only on machine on which *.pot was generated and + # would be of no use on other hosts (having a copy of source code located + # in different place in filesystem). + sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET' \ + + ', SOURCES)} $)' + + # NOTE: the output from $XGETTEXTCOM command must go to stdout, not to a file. + # This is required by the POTUpdate builder's action. + xgettextcom = '$XGETTEXT $XGETTEXTFLAGS $_XGETTEXTPATHFLAGS' \ + + ' $_XGETTEXTFROMFLAGS -o - ' + sources + + xgettextpathflags = '$( ${_concat( XGETTEXTPATHPREFIX, XGETTEXTPATH' \ + + ', XGETTEXTPATHSUFFIX, __env__, RDirs, TARGET, SOURCES)} $)' + xgettextfromflags = '$( ${_concat( XGETTEXTFROMPREFIX, XGETTEXTFROM' \ + + ', XGETTEXTFROMSUFFIX, __env__, target=TARGET, source=SOURCES)} $)' + + env.SetDefault( + _XGETTEXTDOMAIN = '${TARGET.filebase}', + XGETTEXTFLAGS = [ ], + XGETTEXTCOM = xgettextcom, + XGETTEXTCOMSTR = '', + XGETTEXTPATH = [ ], + XGETTEXTPATHPREFIX = '-D', + XGETTEXTPATHSUFFIX = '', + XGETTEXTFROM = None, + XGETTEXTFROMPREFIX = '-f', + XGETTEXTFROMSUFFIX = '', + _XGETTEXTPATHFLAGS = xgettextpathflags, + _XGETTEXTFROMFLAGS = xgettextfromflags, + POTSUFFIX = ['.pot'], + POTUPDATE_ALIAS = 'pot-update', + XgettextRPaths = RPaths(env) + ) + env.Append( BUILDERS = { + '_POTUpdateBuilder' : _POTUpdateBuilder(env) + } ) + env.AddMethod(_POTUpdateBuilderWrapper, 'POTUpdate') + env.AlwaysBuild(env.Alias('$POTUPDATE_ALIAS')) +############################################################################# + +############################################################################# +def exists(env): + """ Check, whether the tool exists """ + from SCons.Tool.GettextCommon import _xgettext_exists + return _xgettext_exists(env) +############################################################################# + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/src/engine/SCons/Tool/xgettext.xml b/src/engine/SCons/Tool/xgettext.xml new file mode 100644 index 0000000..0a919d6 --- /dev/null +++ b/src/engine/SCons/Tool/xgettext.xml @@ -0,0 +1,288 @@ +<!-- +__TOOL_COPYRIGHT__ + +This file is processed by the bin/SConsDoc.py module. +See its __doc__ string for a discussion of the format. +--> +<tool name="xgettext"> +<summary> +This scons tool is a part of scons &t-link-gettext; toolset. It provides +scons interface to <command>xgettext(1)</command> +program, which extracts internationalized messages from source code. The tool +provides &b-POTUpdate; builder to make <literal>PO</literal> +<emphasis>Template</emphasis> files. +</summary> +<sets> +POTSUFFIX +POTUPDATE_ALIAS +XGETTEXTCOM +XGETTEXTCOMSTR +XGETTEXTFLAGS +XGETTEXTFROM +XGETTEXTFROMPREFIX +XGETTEXTFROMSUFFIX +XGETTEXTPATH +XGETTEXTPATHPREFIX +XGETTEXTPATHSUFFIX +_XGETTEXTDOMAIN +_XGETTEXTFROMFLAGS +_XGETTEXTPATHFLAGS +</sets> +<uses> +POTDOMAIN +</uses> +</tool> + +<builder name="POTUpdate"> +<summary> +The builder belongs to &t-link-xgettext; tool. The builder updates target +<literal>POT</literal> file if exists or creates one if it doesn't. The node is +not built by default (i.e. it is <literal>Ignore</literal>d from +<literal>'.'</literal>), but only on demand (i.e. when given +<literal>POT</literal> file is required or when special alias is invoked). This +builder adds its targe node (<filename>messages.pot</filename>, say) to a +special alias (<literal>pot-update</literal> by default, see +&cv-link-POTUPDATE_ALIAS;) so you can update/create them easily with +<command>scons pot-update</command>. The file is not written until there is no +real change in internationalized messages (or in comments that enter +<literal>POT</literal> file). + +<note> <para>You may see <command>xgettext(1)</command> being invoked by the +&t-link-xgettext; tool even if there is no real change in internationalized +messages (so the <literal>POT</literal> file is not being updated). This +happens every time a source file has changed. In such case we invoke +<command>xgettext(1)</command> and compare its output with the content of +<literal>POT</literal> file to decide whether the file should be updated or +not.</para></note> + +<emphasis>Example 1.</emphasis> +Let's create <filename>po/</filename> directory and place following +<filename>SConstruct</filename> script there: +<example> + # SConstruct in 'po/' subdir + env = Environment( tools = ['default', 'xgettext'] ) + env.POTUpdate(['foo'], ['../a.cpp', '../b.cpp']) + env.POTUpdate(['bar'], ['../c.cpp', '../d.cpp']) +</example> +Then invoke scons few times: +<example> + user@host:$ scons # Does not create foo.pot nor bar.pot + user@host:$ scons foo.pot # Updates or creates foo.pot + user@host:$ scons pot-update # Updates or creates foo.pot and bar.pot + user@host:$ scons -c # Does not clean foo.pot nor bar.pot. +</example> +the results shall be as the comments above say. + +<emphasis>Example 2.</emphasis> +The &b-POTUpdate; builder may be used with no target specified, in which +case default target <filename>messages.pot</filename> will be used. The +default target may also be overriden by setting &cv-link-POTDOMAIN; construction +variable or providing it as an override to &b-POTUpdate; builder: +<example> + # SConstruct script + env = Environment( tools = ['default', 'xgettext'] ) + env['POTDOMAIN'] = "foo" + env.POTUpdate(source = ["a.cpp", "b.cpp"]) # Creates foo.pot ... + env.POTUpdate(POTDOMAIN = "bar", source = ["c.cpp", "d.cpp"]) # and bar.pot +</example> + +<emphasis>Example 3.</emphasis> +The sources may be specified within separate file, for example +<filename>POTFILES.in</filename>: +<example> + # POTFILES.in in 'po/' subdirectory + ../a.cpp + ../b.cpp + # end of file +</example> +The name of the file (<filename>POTFILES.in</filename>) containing the list of +sources is provided via &cv-link-XGETTEXTFROM;: +<example> + # SConstruct file in 'po/' subdirectory + env = Environment( tools = ['default', 'xgettext'] ) + env.POTUpdate(XGETTEXTFROM = 'POTFILES.in') +</example> + +<emphasis>Example 4.</emphasis> +You may use &cv-link-XGETTEXTPATH; to define source search path. Assume, for +example, that you have files <filename>a.cpp</filename>, +<filename>b.cpp</filename>, <filename>po/SConstruct</filename>, +<filename>po/POTFILES.in</filename>. Then your <literal>POT</literal>-related +files could look as below: +<example> + # POTFILES.in in 'po/' subdirectory + a.cpp + b.cpp + # end of file +</example> + +<example> + # SConstruct file in 'po/' subdirectory + env = Environment( tools = ['default', 'xgettext'] ) + env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH='../') +</example> + +<emphasis>Example 5.</emphasis> +Multiple search directories may be defined within a list, i.e. +<literal>XGETTEXTPATH = ['dir1', 'dir2', ...]</literal>. The order in the list +determines the search order of source files. The path to the first file found +is used. + +Let's create <filename>0/1/po/SConstruct</filename> script: +<example> + # SConstruct file in '0/1/po/' subdirectory + env = Environment( tools = ['default', 'xgettext'] ) + env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH=['../', '../../']) +</example> +and <filename>0/1/po/POTFILES.in</filename>: +<example> + # POTFILES.in in '0/1/po/' subdirectory + a.cpp + # end of file +</example> +Write two <filename>*.cpp</filename> files, the first one is +<filename>0/a.cpp</filename>: +<example> + /* 0/a.cpp */ + gettext("Hello from ../../a.cpp") +</example> +and the second is <filename>0/1/a.cpp</filename>: +<example> + /* 0/1/a.cpp */ + gettext("Hello from ../a.cpp") +</example> +then run scons. You'll obtain <literal>0/1/po/messages.pot</literal> with the +message <literal>"Hello from ../a.cpp"</literal>. When you reverse order in +<varname>$XGETTEXTFOM</varname>, i.e. when you write SConscript as +<example> + # SConstruct file in '0/1/po/' subdirectory + env = Environment( tools = ['default', 'xgettext'] ) + env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH=['../../', '../']) +</example> then the <filename>messages.pot</filename> will contain +<literal>msgid "Hello from ../../a.cpp"</literal> line and not +<literal>msgid "Hello from ../a.cpp"</literal>. + +</summary> + +</builder> + +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="POTSUFFIX"> +<summary> +Suffix used for PO Template files (default: <literal>'.pot'</literal>). +See &t-link-xgettext; tool and &b-link-POTUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="POTUPDATE_ALIAS"> +<summary> +Name of the common phony target for all PO Templates created with +&b-link-POUpdate; (default: <literal>'pot-update'</literal>). +See &t-link-xgettext; tool and &b-link-POTUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXT"> +<summary> +Path to <command>xgettext(1)</command> program (found via +<function>Detect()</function>). +See &t-link-xgettext; tool and &b-link-POTUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXTCOM"> +<summary> +Complete xgettext command line. +See &t-link-xgettext; tool and &b-link-POTUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXTCOMSTR"> +<summary> +A string that is shown when <command>xgettext(1)</command> command is invoked +(default: <literal>''</literal>, which means "print &cv-link-XGETTEXTCOM;"). +See &t-link-xgettext; tool and &b-link-POTUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXTFLAGS"> +<summary> +Additional flags to <command>xgettext(1)</command>. +See &t-link-xgettext; tool and &b-link-POTUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXTFROM"> +<summary> +Name of file containing list of <command>xgettext(1)</command>'s source +files. Autotools' users know this as <filename>POTFILES.in</filename> so they +will in most cases set <literal>XGETTEXTFROM="POTFILES.in"</literal> here. +The &cv-XGETTEXTFROM; files have same syntax and semantics as the well known +GNU <filename>POTFILES.in</filename>. +See &t-link-xgettext; tool and &b-link-POTUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXTPATH"> +<summary> +List of directories, there <command>xgettext(1)</command> will look for +source files (default: <literal>[]</literal>). +<note><para> +This variable works only together with &cv-link-XGETTEXTFROM; +</para></note> +See also &t-link-xgettext; tool and &b-link-POTUpdate; builder. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXTPATHPREFIX"> +<summary> +This flag is used to add single search path to +<command>xgettext(1)</command>'s commandline (default: +<literal>'-D'</literal>). +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXTPATHSUFFIX"> +<summary> +(default: <literal>''</literal>) +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXTFROMPREFIX"> +<summary> +This flag is used to add single &cv-link-XGETTEXTFROM; file to +<command>xgettext(1)</command>'s commandline (default: +<literal>'-f'</literal>). +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="XGETTEXTFROMSUFFIX"> +<summary> +(default: <literal>''</literal>) +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="_XGETTEXTDOMAIN"> +<summary> +Internal "macro". Generates <command>xgettext</command> domain name +form source and target (default: <literal>'${TARGET.filebase}'</literal>). +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="_XGETTEXTFROMFLAGS"> +<summary> +Internal "macro". Genrates list of <literal>-D<dir></literal> flags +from the &cv-link-XGETTEXTPATH; list. +</summary> +</cvar> +<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --> +<cvar name="_XGETTEXTPATHFLAGS"> +<summary> +Internal "macro". Generates list of <literal>-f<file></literal> flags +from &cv-link-XGETTEXTFROM;. +</summary> +</cvar> + +<!-- + +--> diff --git a/test/GETTEXT/Translate_doc_user_examples1.py b/test/GETTEXT/Translate_doc_user_examples1.py new file mode 100644 index 0000000..946f18b --- /dev/null +++ b/test/GETTEXT/Translate_doc_user_examples1.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +# NOTE: When integrating into upstream SCons development tree, remove the next +# line, and the "toolpath = ..." line +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.subdir('po/') +test.write('po/SConstruct', +""" +env = Environment( + toolpath = ['""" + site_scons + """/SConsToolGettext'] +, tools = ["default", "gettext"] +) +env['POAUTOINIT'] = 1 +env.Translate(['en','pl'], ['../a.cpp','../b.cpp']) +""") +# +test.write('a.cpp', """ gettext("Hello from a.cpp") """) +test.write('b.cpp', """ gettext("Hello from b.cpp") """) + +# NOTE: msginit(1) prints all its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None, chdir = 'po') +test.must_exist('po/messages.pot') +test.must_exist('po/en.po', 'po/pl.po') +test.must_contain('po/en.po', "Hello from a.cpp") +test.must_contain('po/en.po', "Hello from b.cpp") +test.must_contain('po/pl.po', "Hello from a.cpp") +test.must_contain('po/pl.po', "Hello from b.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/GETTEXT/Translate_doc_user_examples2.py b/test/GETTEXT/Translate_doc_user_examples2.py new file mode 100644 index 0000000..51464d4 --- /dev/null +++ b/test/GETTEXT/Translate_doc_user_examples2.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +# NOTE: When integrating into upstream SCons development tree, remove the next +# line, and the "toolpath = ..." line +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.subdir('po/') +test.write('po/SConstruct', +""" +env = Environment( + toolpath = ['""" + site_scons + """/SConsToolGettext'] +, tools = ["default", "gettext"] +) +env['POAUTOINIT'] = 1 +env['XGETTEXTPATH'] = ['../'] +env.Translate(LINGUAS_FILE = 1, XGETTEXTFROM = 'POTFILES.in') +""") +# +test.write('po/LINGUAS', """\ +en pl +""") +# +test.write('po/POTFILES.in', """\ +# POTFILES.in +a.cpp +b.cpp +# end +""") +# +test.write('a.cpp', """ gettext("Hello from a.cpp") """) +test.write('b.cpp', """ gettext("Hello from b.cpp") """) + +# NOTE: msginit(1) prints all its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None, chdir = 'po') +test.must_exist('po/messages.pot') +test.must_exist('po/en.po', 'po/pl.po') +test.must_contain('po/en.po', "Hello from a.cpp") +test.must_contain('po/en.po', "Hello from b.cpp") +test.must_contain('po/pl.po', "Hello from a.cpp") +test.must_contain('po/pl.po', "Hello from b.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/GETTEXT/Translate_doc_user_examples3.py b/test/GETTEXT/Translate_doc_user_examples3.py new file mode 100644 index 0000000..6a93b5e --- /dev/null +++ b/test/GETTEXT/Translate_doc_user_examples3.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +# NOTE: When integrating into upstream SCons development tree, remove the next +# line, and the "toolpath = ..." line +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.subdir('src', ['src', 'po'], 'build') +test.write('SConstruct', +""" +env = Environment( + toolpath = ['""" + site_scons + """/SConsToolGettext'] +, tools = ["default", "gettext"] +) +VariantDir('build', 'src', duplicate = 0) +env['POAUTOINIT'] = 1 +SConscript('src/po/SConscript.i18n', exports = 'env') +SConscript('build/po/SConscript', exports = 'env') +""") +# +test.write('src/po/SConscript.i18n', """\ +# src/po/SConscript.i18n +Import('env') +env.Translate(LINGUAS_FILE=1, XGETTEXTFROM='POTFILES.in', XGETTEXTPATH=['../']) +""") +# +test.write('src/po/SConscript',"""\ +# src/po/SConscript +Import('env') +env.MOFiles(LINGUAS_FILE = 1) +""") +test.write('src/po/LINGUAS', """\ +en pl +""") +# +test.write('src/po/POTFILES.in', """\ +# POTFILES.in +a.cpp +b.cpp +# end +""") +# +test.write('src/a.cpp', """ gettext("Hello from a.cpp") """) +test.write('src/b.cpp', """ gettext("Hello from b.cpp") """) + +# NOTE: msginit(1) prints all its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None) +test.must_exist('src/po/messages.pot') +test.must_exist('src/po/en.po', 'src/po/pl.po') +test.must_not_exist('build/po/en.po', 'build/po/pl.po') +test.must_contain('src/po/en.po', "Hello from a.cpp") +test.must_contain('src/po/en.po', "Hello from b.cpp") +test.must_contain('src/po/pl.po', "Hello from a.cpp") +test.must_contain('src/po/pl.po', "Hello from b.cpp") + +test.run(arguments = '.', stderr = None) +test.must_exist('build/po/en.mo', 'build/po/pl.mo') +test.must_not_exist('src/po/en.mo', 'src/po/pl.mo') + +test.run(arguments = '-c', stderr = None) +test.must_exist('src/po/messages.pot') +test.must_exist('src/po/en.po', 'src/po/pl.po') +test.must_not_exist('build/po/en.mo', 'build/po/pl.mo') + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/GETTEXT/doc_user_examples1.py b/test/GETTEXT/doc_user_examples1.py new file mode 100644 index 0000000..3d05a21 --- /dev/null +++ b/test/GETTEXT/doc_user_examples1.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +# NOTE: When integrating into upstream SCons development tree, remove the next +# line, and the "toolpath = ..." line +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( + toolpath = ['""" + site_scons + """/SConsToolGettext'] +, tools = ["default", "gettext"] +) +""") +test.run(arguments = '.') + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGFMT/MOFile_doc_user_examples1.py b/test/MSGFMT/MOFile_doc_user_examples1.py new file mode 100644 index 0000000..71b5996 --- /dev/null +++ b/test/MSGFMT/MOFile_doc_user_examples1.py @@ -0,0 +1,114 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env.MOFiles(['pl', 'en']) +""") +# +##test.write('LINGUAS', +##""" +##en +##pl +##""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") + +test.run(arguments = '.') +test.must_exist('en.mo', 'pl.mo') + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGFMT/MOFile_doc_user_examples2.py b/test/MSGFMT/MOFile_doc_user_examples2.py new file mode 100644 index 0000000..ad67b3e --- /dev/null +++ b/test/MSGFMT/MOFile_doc_user_examples2.py @@ -0,0 +1,114 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env.MOFiles(LINGUAS_FILE = 1) +""") +# +test.write('LINGUAS', +""" +en +pl +""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") + +test.run(arguments = '.') +test.must_exist('en.mo', 'pl.mo') + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGFMT/MOFile_doc_user_examples3.py b/test/MSGFMT/MOFile_doc_user_examples3.py new file mode 100644 index 0000000..e7cc0ff --- /dev/null +++ b/test/MSGFMT/MOFile_doc_user_examples3.py @@ -0,0 +1,163 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env.MOFiles(['en', 'pl'], LINGUAS_FILE = 1) +""") +test.write('LINGUAS', +""" +de +fr +""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") +# +test.write('de.po',"""\ +# German translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: de\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "" +""") +# +test.write('fr.po',"""\ +# French translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: fr\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "" +""") + +test.run(arguments = '.') +test.must_exist('en.mo', 'pl.mo', 'de.mo', 'fr.mo') + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGFMT/MOFile_doc_user_examples4.py b/test/MSGFMT/MOFile_doc_user_examples4.py new file mode 100644 index 0000000..8737b2b --- /dev/null +++ b/test/MSGFMT/MOFile_doc_user_examples4.py @@ -0,0 +1,115 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env['LINGUAS_FILE'] = 1 +env.MOFiles() +""") +# +test.write('LINGUAS', +""" +en +pl +""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: dummypkg 1.0\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") + +test.run(arguments = '.') +test.must_exist('en.mo', 'pl.mo') + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGINIT/POinit_doc_user_examples1.py b/test/MSGINIT/POinit_doc_user_examples1.py new file mode 100644 index 0000000..9082a11 --- /dev/null +++ b/test/MSGINIT/POinit_doc_user_examples1.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env['POAUTOINIT'] = 1 +env.POInit(['en','pl']) # messages.pot --> [en.po, pl.po] +""") +# +test.write('messages.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") + +# NOTE: msginit(1) prints all its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-create', stderr = None) +test.must_exist('en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGINIT/POinit_doc_user_examples2.py b/test/MSGINIT/POinit_doc_user_examples2.py new file mode 100644 index 0000000..a96d921 --- /dev/null +++ b/test/MSGINIT/POinit_doc_user_examples2.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env['POAUTOINIT'] = 1 +env.POInit(['en','pl'], ['foo']) # foo.pot --> [en.po, pl.po] +""") +# +test.write('foo.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") + +# NOTE: msginit(1) prints all its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-create', stderr = None) +test.must_exist('en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGINIT/POinit_doc_user_examples3.py b/test/MSGINIT/POinit_doc_user_examples3.py new file mode 100644 index 0000000..f21f874 --- /dev/null +++ b/test/MSGINIT/POinit_doc_user_examples3.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env['POAUTOINIT'] = 1 +env.POInit(['en','pl'], POTDOMAIN='foo') # foo.pot --> [en.po, pl.po] +""") +# +test.write('foo.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") + +# NOTE: msginit(1) prints all its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-create', stderr = None) +test.must_exist('en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGINIT/POinit_doc_user_examples4.py b/test/MSGINIT/POinit_doc_user_examples4.py new file mode 100644 index 0000000..2bcb68e --- /dev/null +++ b/test/MSGINIT/POinit_doc_user_examples4.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env['POAUTOINIT'] = 1 +env.POInit(LINGUAS_FILE = 1) # needs 'LINGUAS' file +""") +test.write('LINGUAS',""" +en +pl +""") +# +test.write('messages.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") + +# NOTE: msginit(1) prints all its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-create', stderr = None) +test.must_exist('en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGINIT/POinit_doc_user_examples5.py b/test/MSGINIT/POinit_doc_user_examples5.py new file mode 100644 index 0000000..c3971e7 --- /dev/null +++ b/test/MSGINIT/POinit_doc_user_examples5.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env['POAUTOINIT'] = 1 +env.POInit(['en', 'pl'], LINGUAS_FILE = 1) # needs 'LINGUAS' file +""") +test.write('LINGUAS',""" +de +fr +""") +# +test.write('messages.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") + +# NOTE: msginit(1) prints all its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-create', stderr = None) +test.must_exist('en.po', 'pl.po', 'de.po', 'fr.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") +test.must_contain('de.po', "Hello from a.cpp") +test.must_contain('fr.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGINIT/POinit_doc_user_examples6.py b/test/MSGINIT/POinit_doc_user_examples6.py new file mode 100644 index 0000000..bf694fa --- /dev/null +++ b/test/MSGINIT/POinit_doc_user_examples6.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env['POAUTOINIT'] = 1 +env['LINGUAS_FILE'] = 1 +env['POTDOMAIN'] = 'foo' +env.POInit() +""") +test.write('LINGUAS',""" +en +pl +""") +# +test.write('foo.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") + +# NOTE: msginit(1) prints all its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-create', stderr = None) +test.must_exist('en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGMERGE/POUpdate_doc_user_examples1.py b/test/MSGMERGE/POUpdate_doc_user_examples1.py new file mode 100644 index 0000000..d925568 --- /dev/null +++ b/test/MSGMERGE/POUpdate_doc_user_examples1.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env.POUpdate(['en','pl']) # messages.pot --> [en.po, pl.po] +""") +# +test.write('messages.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") + +# NOTE: msgmerge(1) prints its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None) +test.must_exist('en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGMERGE/POUpdate_doc_user_examples2.py b/test/MSGMERGE/POUpdate_doc_user_examples2.py new file mode 100644 index 0000000..0126391 --- /dev/null +++ b/test/MSGMERGE/POUpdate_doc_user_examples2.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env.POUpdate(['en','pl'], ['foo']) # foo.pot --> [en.po, pl.po] +""") +# +test.write('foo.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") + +# NOTE: msgmerge(1) prints all messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None) +test.must_exist('en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGMERGE/POUpdate_doc_user_examples3.py b/test/MSGMERGE/POUpdate_doc_user_examples3.py new file mode 100644 index 0000000..31c09c5 --- /dev/null +++ b/test/MSGMERGE/POUpdate_doc_user_examples3.py @@ -0,0 +1,138 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env.POUpdate(['en','pl'], POTDOMAIN='foo') # foo.pot --> [en.po, pl.po] +""") +# +test.write('foo.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") + +# NOTE: msgmerge(1) prints its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None) +test.must_exist('en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGMERGE/POUpdate_doc_user_examples4.py b/test/MSGMERGE/POUpdate_doc_user_examples4.py new file mode 100644 index 0000000..51d944f --- /dev/null +++ b/test/MSGMERGE/POUpdate_doc_user_examples4.py @@ -0,0 +1,144 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env.POUpdate(LINGUAS_FILE = 1) # needs 'LINGUAS' file +""") +# +test.write('LINGUAS', +""" +en +pl +""") +# +test.write('messages.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") + +# NOTE: msgmerge(1) prints all messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None) +test.must_exist('messages.pot', 'en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGMERGE/POUpdate_doc_user_examples5.py b/test/MSGMERGE/POUpdate_doc_user_examples5.py new file mode 100644 index 0000000..07751ca --- /dev/null +++ b/test/MSGMERGE/POUpdate_doc_user_examples5.py @@ -0,0 +1,143 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env.POUpdate(LINGUAS_FILE = 1, source = ['foo']) +""") +test.write('LINGUAS', +""" +en +pl +""") +# +test.write('foo.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") + +# NOTE: msgmerge(1) prints its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None) +test.must_exist('en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGMERGE/POUpdate_doc_user_examples6.py b/test/MSGMERGE/POUpdate_doc_user_examples6.py new file mode 100644 index 0000000..bd71acf --- /dev/null +++ b/test/MSGMERGE/POUpdate_doc_user_examples6.py @@ -0,0 +1,194 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) +env.POUpdate(['en', 'pl'], LINGUAS_FILE = 1) +""") +test.write('LINGUAS', +""" +de +fr +""") +test.write('messages.pot',"""\ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n" +"Language-Team: LANGUAGE <LL@li.org>\\n" +"Language: \\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=CHARSET\\n" +"Content-Transfer-Encoding: 8bit\\n" +# +#: a.cpp:1 +msgid "Hello from a.cpp" +msgstr "" +""") +# +test.write('en.po',"""\ +# English translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Pawel Tomulik <ptomulik@meil.pw.edu.pl>, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:37+0200\\n" +"Last-Translator: Pawel Tomulik <ptomulik@meil.pw.edu.pl>\\n" +"Language-Team: English\\n" +"Language: en\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Old message from a.cpp" +""") +# +test.write('pl.po',"""\ +# Polish translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: pl\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "Stara wiadomosc z a.cpp" +""") +# +test.write('de.po',"""\ +# German translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: de\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "" +""") +# +test.write('fr.po',"""\ +# French translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\\n" +"Report-Msgid-Bugs-To: \\n" +"POT-Creation-Date: 2012-05-27 00:35+0200\\n" +"PO-Revision-Date: 2012-05-27 00:35+0200\\n" +"Last-Translator: Automatically generated\\n" +"Language-Team: none\\n" +"Language: fr\\n" +"MIME-Version: 1.0\\n" +"Content-Type: text/plain; charset=ASCII\\n" +"Content-Transfer-Encoding: 8bit\\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\\n" + +#: a.cpp:1 +msgid "Old message from a.cpp" +msgstr "" +""") + +# Note: msgmerge(1) prints its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None) +test.must_exist('en.po', 'pl.po', 'de.po', 'fr.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") +test.must_contain('de.po', "Hello from a.cpp") +test.must_contain('fr.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSGMERGE/POUpdate_doc_user_examples8.py b/test/MSGMERGE/POUpdate_doc_user_examples8.py new file mode 100644 index 0000000..e113e2c --- /dev/null +++ b/test/MSGMERGE/POUpdate_doc_user_examples8.py @@ -0,0 +1,74 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +# Trivial example. Just load the tool. +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ["default", "gettext"] ) + +# script-wise settings +env['POAUTOINIT'] = 1 +env['LINGUAS_FILE'] = 1 +env['POTDOMAIN'] = 'foo' +env.POTUpdate(source = 'a.cpp') +env.POUpdate() +""") +test.write('LINGUAS', +""" +en +pl +""") +test.write('a.cpp', """ gettext("Hello from a.cpp") """) + +# Note: msgmerge(1) prints its messages to stderr, we must ignore them, +# So, stderr=None is crucial here. It is no point to match stderr to some +# specific valuse; the messages are internationalized :) ). +test.run(arguments = 'po-update', stderr = None) +test.must_exist('foo.pot', 'en.po', 'pl.po') +test.must_contain('en.po', "Hello from a.cpp") +test.must_contain('pl.po', "Hello from a.cpp") + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/XGETTEXT/POTUpdate_doc_user_examples1.py b/test/XGETTEXT/POTUpdate_doc_user_examples1.py new file mode 100644 index 0000000..63bdfdb --- /dev/null +++ b/test/XGETTEXT/POTUpdate_doc_user_examples1.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +test = TestSCons.TestSCons() + +test.subdir('po') +test.write('po/SConstruct', +""" +env = Environment( tools = ['default', 'xgettext'] ) +env.POTUpdate(['foo'], ['../a.cpp', '../b.cpp']) +env.POTUpdate(['bar'], ['../c.cpp', '../d.cpp']) +""") +test.write('a.cpp', """ gettext("Hello from a.cpp") """) +test.write('b.cpp', """ gettext("Hello from b.cpp") """) +test.write('c.cpp', """ gettext("Hello from c.cpp") """) +test.write('d.cpp', """ gettext("Hello from d.cpp") """) + +# scons '.' does not create foo.pot nor bar.pot +test.run(arguments = '.', chdir = 'po') +test.must_not_exist('po/foo.pot', 'po/bar.pot') + +# scons 'foo.pot' creates foo.pot +test.run(arguments = 'foo.pot', chdir = 'po') +test.must_exist('po/foo.pot') +test.must_not_exist('po/bar.pot') +test.must_contain('po/foo.pot',"Hello from a.cpp") +test.must_contain('po/foo.pot',"Hello from b.cpp") +test.must_not_contain('po/foo.pot',"Hello from c.cpp") +test.must_not_contain('po/foo.pot',"Hello from d.cpp") + +# scons 'pot-update' creates foo.pot and bar.pot +test.run(arguments = 'pot-update', chdir = 'po') +test.must_exist('po/foo.pot', 'po/bar.pot') +test.must_not_contain('po/bar.pot',"Hello from a.cpp") +test.must_not_contain('po/bar.pot',"Hello from b.cpp") +test.must_contain('po/bar.pot',"Hello from c.cpp") +test.must_contain('po/bar.pot',"Hello from d.cpp") + +# scons -c does not clean anything +test.run(arguments = '-c', chdir = 'po') +test.must_exist('po/foo.pot', 'po/bar.pot') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/XGETTEXT/POTUpdate_doc_user_examples2.py b/test/XGETTEXT/POTUpdate_doc_user_examples2.py new file mode 100644 index 0000000..3698d24 --- /dev/null +++ b/test/XGETTEXT/POTUpdate_doc_user_examples2.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +test = TestSCons.TestSCons() + +test.write('SConstruct', +""" +env = Environment( tools = ['default', 'xgettext'] ) +env['POTDOMAIN'] = "foo" +env.POTUpdate(source = ["a.cpp", "b.cpp"]) # Creates foo.pot ... +env.POTUpdate(POTDOMAIN = "bar", source = ["c.cpp", "d.cpp"]) # and bar.pot +""") +test.write('a.cpp', """ gettext("Hello from a.cpp") """) +test.write('b.cpp', """ gettext("Hello from b.cpp") """) +test.write('c.cpp', """ gettext("Hello from c.cpp") """) +test.write('d.cpp', """ gettext("Hello from d.cpp") """) + +test.run(arguments = 'pot-update') + +test.must_exist('foo.pot') +test.must_contain('foo.pot', "Hello from a.cpp") +test.must_contain('foo.pot', "Hello from b.cpp") +test.must_not_contain('foo.pot', "Hello from c.cpp") +test.must_not_contain('foo.pot', "Hello from d.cpp") + +test.must_exist('bar.pot') +test.must_not_contain('bar.pot', "Hello from a.cpp") +test.must_not_contain('bar.pot', "Hello from b.cpp") +test.must_contain('bar.pot', "Hello from c.cpp") +test.must_contain('bar.pot', "Hello from d.cpp") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/XGETTEXT/POTUpdate_doc_user_examples3.py b/test/XGETTEXT/POTUpdate_doc_user_examples3.py new file mode 100644 index 0000000..de9687e --- /dev/null +++ b/test/XGETTEXT/POTUpdate_doc_user_examples3.py @@ -0,0 +1,67 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +test = TestSCons.TestSCons() + +test.subdir('po') +test.write('po/SConstruct', +""" +# SConstruct file in 'po/' subdirectory +env = Environment( tools = ['default', 'xgettext'] ) +env.POTUpdate(XGETTEXTFROM = 'POTFILES.in') +""") +test.write('po/POTFILES.in', +""" +# POTFILES.in in 'po/' subdirectory +../a.cpp +../b.cpp +# end of file +""") +test.write('a.cpp', """ gettext("Hello from a.cpp") """) +test.write('b.cpp', """ gettext("Hello from b.cpp") """) + +# scons 'pot-update' creates messages.pot +test.run(arguments = 'pot-update', chdir = 'po') +test.must_exist('po/messages.pot') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/XGETTEXT/POTUpdate_doc_user_examples4.py b/test/XGETTEXT/POTUpdate_doc_user_examples4.py new file mode 100644 index 0000000..881f65e --- /dev/null +++ b/test/XGETTEXT/POTUpdate_doc_user_examples4.py @@ -0,0 +1,67 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +test = TestSCons.TestSCons() + +test.subdir('po') +test.write('po/SConstruct', +""" +# SConstruct file in 'po/' subdirectory +env = Environment( tools = ['default', 'xgettext'] ) +env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH='../') +""") +test.write('po/POTFILES.in', +""" +# POTFILES.in in 'po/' subdirectory +a.cpp +b.cpp +# end of file +""") +test.write('a.cpp', """ gettext("Hello from a.cpp") """) +test.write('b.cpp', """ gettext("Hello from b.cpp") """) + +# scons 'pot-update' creates messages.pot +test.run(arguments = 'pot-update', chdir = 'po') +test.must_exist('po/messages.pot') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/XGETTEXT/POTUpdate_doc_user_examples5.py b/test/XGETTEXT/POTUpdate_doc_user_examples5.py new file mode 100644 index 0000000..4afb3cf --- /dev/null +++ b/test/XGETTEXT/POTUpdate_doc_user_examples5.py @@ -0,0 +1,81 @@ + +#!/usr/bin/env python +# +# __TOOL_COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Make sure, that the examples given in user guide all work. +""" + +import TestSCons +import os + +site_scons = os.environ['SCONS_TOOL_LIB_DIR'] + +############################################################################### +test = TestSCons.TestSCons() + +test.subdir('0', ['0','1'], ['0', '1', 'po']) +test.write('0/1/po/SConstruct', +""" +# SConstruct file in '0/1/po/' subdirectory +env = Environment( tools = ['default', 'xgettext'] ) +env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH=['../', '../../']) +""") +test.write('0/1/po/POTFILES.in', +""" +# POTFILES.in in '0/1/po/' subdirectory +a.cpp +# end of file +""") +test.write('0/a.cpp', """ gettext("Hello from ../../a.cpp") """) +test.write('0/1/a.cpp', """ gettext("Hello from ../a.cpp") """) + +# scons 'pot-update' creates messages.pot +test.run(arguments = 'pot-update', chdir = '0/1/po') +test.must_exist('0/1/po/messages.pot') +test.must_contain('0/1/po/messages.pot', 'Hello from ../a.cpp') +test.must_not_contain('0/1/po/messages.pot', 'Hello from ../../a.cpp') + +test.write('0/1/po/SConstruct', +""" +# SConstruct file in '0/1/po/' subdirectory +env = Environment( + toolpath = ['""" + site_scons + """/SConsToolGettext'] +, tools = ['default', 'xgettext'] +) +env.POTUpdate(XGETTEXTFROM = 'POTFILES.in', XGETTEXTPATH=['../../', '../']) +""") +test.run(arguments = 'pot-update', chdir = '0/1/po') +test.must_contain('0/1/po/messages.pot', 'Hello from ../../a.cpp') +test.must_not_contain('0/1/po/messages.pot', 'Hello from ../a.cpp') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: |