Ticket #67: i18n-first-steps.diff

File i18n-first-steps.diff, 250.8 KB (added by Adrián Chaves, 11 years ago)

Initial implementation which allows translating the main menu of the home page and a couple of other strings in the same page.

  • binaries/data/mods/public/gui/common/init.xml

     
    2424
    2525        <script file="gui/common/functions_global_object.js" />
    2626
     27        <script file="gui/common/sprintf.js" />
     28
    2729</objects>
  • binaries/data/mods/public/gui/common/sprintf.js

     
     1/**
     2sprintf() for JavaScript 0.7-beta1
     3http://www.diveintojavascript.com/projects/javascript-sprintf
     4
     5Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
     6All rights reserved.
     7
     8Redistribution and use in source and binary forms, with or without
     9modification, are permitted provided that the following conditions are met:
     10    * Redistributions of source code must retain the above copyright
     11      notice, this list of conditions and the following disclaimer.
     12    * Redistributions in binary form must reproduce the above copyright
     13      notice, this list of conditions and the following disclaimer in the
     14      documentation and/or other materials provided with the distribution.
     15    * Neither the name of sprintf() for JavaScript nor the
     16      names of its contributors may be used to endorse or promote products
     17      derived from this software without specific prior written permission.
     18
     19THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     20ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
     23DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     26ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     28SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29
     30
     31Changelog:
     322010.09.06 - 0.7-beta1
     33  - features: vsprintf, support for named placeholders
     34  - enhancements: format cache, reduced global namespace pollution
     35
     362010.05.22 - 0.6:
     37 - reverted to 0.4 and fixed the bug regarding the sign of the number 0
     38 Note:
     39 Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/)
     40 who warned me about a bug in 0.5, I discovered that the last update was
     41 a regress. I appologize for that.
     42
     432010.05.09 - 0.5:
     44 - bug fix: 0 is now preceeded with a + sign
     45 - bug fix: the sign was not at the right position on padded results (Kamal Abdali)
     46 - switched from GPL to BSD license
     47
     482007.10.21 - 0.4:
     49 - unit test and patch (David Baird)
     50
     512007.09.17 - 0.3:
     52 - bug fix: no longer throws exception on empty paramenters (Hans Pufal)
     53
     542007.09.11 - 0.2:
     55 - feature: added argument swapping
     56
     572007.04.03 - 0.1:
     58 - initial release
     59**/
     60
     61var sprintf = (function() {
     62    function get_type(variable) {
     63        return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
     64    }
     65    function str_repeat(input, multiplier) {
     66        for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
     67        return output.join('');
     68    }
     69
     70    var str_format = function() {
     71        if (!str_format.cache.hasOwnProperty(arguments[0])) {
     72            str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
     73        }
     74        return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
     75    };
     76
     77    str_format.format = function(parse_tree, argv) {
     78        var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
     79        for (i = 0; i < tree_length; i++) {
     80            node_type = get_type(parse_tree[i]);
     81            if (node_type === 'string') {
     82                output.push(parse_tree[i]);
     83            }
     84            else if (node_type === 'array') {
     85                match = parse_tree[i]; // convenience purposes only
     86                if (match[2]) { // keyword argument
     87                    arg = argv[cursor];
     88                    for (k = 0; k < match[2].length; k++) {
     89                        if (!arg.hasOwnProperty(match[2][k])) {
     90                            throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
     91                        }
     92                        arg = arg[match[2][k]];
     93                    }
     94                }
     95                else if (match[1]) { // positional argument (explicit)
     96                    arg = argv[match[1]];
     97                }
     98                else { // positional argument (implicit)
     99                    arg = argv[cursor++];
     100                }
     101
     102                if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
     103                    throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
     104                }
     105                switch (match[8]) {
     106                    case 'b': arg = arg.toString(2); break;
     107                    case 'c': arg = String.fromCharCode(arg); break;
     108                    case 'd': arg = parseInt(arg, 10); break;
     109                    case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
     110                    case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
     111                    case 'o': arg = arg.toString(8); break;
     112                    case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
     113                    case 'u': arg = Math.abs(arg); break;
     114                    case 'x': arg = arg.toString(16); break;
     115                    case 'X': arg = arg.toString(16).toUpperCase(); break;
     116                }
     117                arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
     118                pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
     119                pad_length = match[6] - String(arg).length;
     120                pad = match[6] ? str_repeat(pad_character, pad_length) : '';
     121                output.push(match[5] ? arg + pad : pad + arg);
     122            }
     123        }
     124        return output.join('');
     125    };
     126
     127    str_format.cache = {};
     128
     129    str_format.parse = function(fmt) {
     130        var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
     131        while (_fmt) {
     132            if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
     133                parse_tree.push(match[0]);
     134            }
     135            else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
     136                parse_tree.push('%');
     137            }
     138            else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
     139                if (match[2]) {
     140                    arg_names |= 1;
     141                    var field_list = [], replacement_field = match[2], field_match = [];
     142                    if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
     143                        field_list.push(field_match[1]);
     144                        while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
     145                            if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
     146                                field_list.push(field_match[1]);
     147                            }
     148                            else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
     149                                field_list.push(field_match[1]);
     150                            }
     151                            else {
     152                                throw('[sprintf] huh?');
     153                            }
     154                        }
     155                    }
     156                    else {
     157                        throw('[sprintf] huh?');
     158                    }
     159                    match[2] = field_list;
     160                }
     161                else {
     162                    arg_names |= 2;
     163                }
     164                if (arg_names === 3) {
     165                    throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
     166                }
     167                parse_tree.push(match);
     168            }
     169            else {
     170                throw('[sprintf] huh?');
     171            }
     172            _fmt = _fmt.substring(match[0].length);
     173        }
     174        return parse_tree;
     175    };
     176
     177    return str_format;
     178})();
     179
     180var vsprintf = function(fmt, argv) {
     181    argv.unshift(fmt);
     182    return sprintf.apply(null, argv);
     183};
  • binaries/data/mods/public/gui/pregame/mainmenu.xml

     
    339339                    style="StoneButtonFancy"
    340340                    size="4 4 100%-4 32"
    341341                    tooltip_style="pgToolTip"
    342                     tooltip="The 0 A.D. Game Manual"
    343342                >
    344                     Learn To Play
     343                    <localizableAttribute id="caption">Learn To Play</localizableAttribute>
     344                    <localizableAttribute id="tooltip">The 0 A.D. Game Manual</localizableAttribute>
    345345                    <action on="Press">
    346346                        closeMenu();
    347347                        <![CDATA[
     
    356356                    type="button"
    357357                    size="4 36 100%-4 64"
    358358                    tooltip_style="pgToolTip"
    359                     tooltip="Challenge the computer player to a single player match."
    360359                >
    361                     Single Player
     360                    <localizableAttribute id="caption">Single Player</localizableAttribute>
     361                    <localizableAttribute id="tooltip">Challenge the computer player to a single player match.</localizableAttribute>
    362362                    <action on="Press">
    363363                        closeMenu();
    364364                        openMenu("submenuSinglePlayer", (this.parent.size.top+this.size.top), (this.size.bottom-this.size.top), 3);
     
    371371                    type="button"
    372372                    size="4 68 100%-4 96"
    373373                    tooltip_style="pgToolTip"
    374                     tooltip="Fight against one or more human players in a multiplayer game."
    375374                >
    376                     Multiplayer
     375                    <localizableAttribute id="caption">Multiplayer</localizableAttribute>
     376                    <localizableAttribute id="tooltip">Fight against one or more human players in a multiplayer game.</localizableAttribute>
    377377                    <action on="Press">
    378378                        closeMenu();
    379379                        openMenu("submenuMultiplayer", (this.parent.size.top+this.size.top), (this.size.bottom-this.size.top), 2);
     
    386386                    type="button"
    387387                    size="4 100 100%-4 128"
    388388                    tooltip_style="pgToolTip"
    389                     tooltip="Game options and scenario design tools."
    390389                >
    391                     Tools <![CDATA[&]]> Options
     390                    <localizableAttribute id="caption">Tools &amp; Options</localizableAttribute>
     391                    <localizableAttribute id="tooltip">Game options and scenario design tools.</localizableAttribute>
    392392                    <action on="Press">
    393393                        closeMenu();
    394394                        openMenu("submenuToolsAndOptions", (this.parent.size.top+this.size.top), (this.size.bottom-this.size.top), 2);
     
    401401                    type="button"
    402402                    size="4 132 100%-4 160"
    403403                    tooltip_style="pgToolTip"
    404                     tooltip="Learn about the many civilizations featured in 0 A.D."
    405404                >
    406                     History
     405                    <localizableAttribute id="caption">History</localizableAttribute>
     406                    <localizableAttribute id="tooltip">Learn about the many civilizations featured in 0 A.D.</localizableAttribute>
    407407                    <action on="Press">
    408408                        closeMenu();
    409409                        <![CDATA[
     
    418418                    style="StoneButtonFancy"
    419419                    size="4 164 100%-4 192"
    420420                    tooltip_style="pgToolTip"
    421                     tooltip="Exit Game"
    422421                >
    423                     Exit
     422                    <localizableAttribute id="caption">Exit</localizableAttribute>
     423                    <localizableAttribute id="tooltip">Exit Game</localizableAttribute>
    424424                    <action on="Press">
    425425                        closeMenu();
    426426                        <![CDATA[
     
    446446                    size="8 8 100%-8 100%-36"
    447447                                        ghost="true"
    448448                >
    449 [font="serif-bold-16"]Alpha XIII: Magadha<!-- IMPORTANT: remember to update session/session.xml in sync with this -->[/font]
    450 
    451 WARNING: This is an early development version of the game. Many features have not been added yet.
    452 
    453 Get involved at: play0ad.com
     449                    <!-- IMPORTANT: remember to update session/session.xml in sync with this ↓ -->
     450                    <localizableAttribute id="caption">[font="serif-bold-16"]Alpha XIII: Magadha[/font]\n\nWARNING: This is an early development version of the game. Many features have not been added yet.\n\nGet involved at: play0ad.com</localizableAttribute>
    454451                </object>
    455452
    456453                <!-- CONTACT METHODS -->
    457454                <object type="button"
    458455                    style="StoneButton"
    459456                    tooltip_style="pgToolTip"
    460                     tooltip="Click to open play0ad.com in your web browser."
    461457                    size="8 100%-72 50%-4 100%-44"
    462458                >
    463                     Website
     459                    <localizableAttribute id="caption">Website</localizableAttribute>
     460                    <localizableAttribute id="tooltip">Click to open play0ad.com in your web browser.</localizableAttribute>
    464461                    <action on="Press"><![CDATA[
    465462                        var url = "http://play0ad.com/";
    466463                        Engine.OpenURL(url);
     
    471468                <object type="button"
    472469                    style="StoneButton"
    473470                    tooltip_style="pgToolTip"
    474                     tooltip="Click to open the 0 A.D. IRC chat in your browser. (#0ad on webchat.quakenet.org)"
    475471                    size="50%+4 100%-72 100%-8 100%-44"
    476472                >
    477                     Chat
     473                    <localizableAttribute id="caption">Chat</localizableAttribute>
     474                    <localizableAttribute id="tooltip">Click to open the 0 A.D. IRC chat in your browser. (#0ad on webchat.quakenet.org)</localizableAttribute>
    478475                    <action on="Press"><![CDATA[
    479476                        var url = "http://webchat.quakenet.org/?channels=0ad";
    480477                        Engine.OpenURL(url);
     
    485482                <object type="button"
    486483                    style="StoneButton"
    487484                    tooltip_style="pgToolTip"
    488                     tooltip="Click to visit 0 A.D. Trac to report a bug, crash, or error"
    489485                    size="8 100%-36 100%-8 100%-8"
    490486                >
    491                     Report a Bug
     487                    <localizableAttribute id="caption">Report a Bug</localizableAttribute>
     488                    <localizableAttribute id="tooltip">Click to visit 0 A.D. Trac to report a bug, crash, or error</localizableAttribute>
    492489                    <action on="Press"><![CDATA[
    493490                        var url = "http://trac.wildfiregames.com/wiki/ReportingErrors/";
    494491                        Engine.OpenURL(url);
     
    517514                        style="MediumTitleText"
    518515                    ghost="true"
    519516                    size="50%-128 32 50%+128 48"
    520                 >WILDFIRE GAMES</object>
     517                >
     518                    <localizableAttribute id="caption">WILDFIRE GAMES</localizableAttribute>
     519                </object>
    521520            </object>
    522521
    523522            <!-- VERSION -->
     
    527526                ghost="true"
    528527                size="50%-128 100%-36 50%+128 100%"
    529528            >
    530                 <action on="Load"><![CDATA[
    531                     this.caption = "Build: " + buildTime(0) + " - " + buildTime(2);
    532                 ]]></action>
     529                <action on="Load">
     530                    <keep>this.caption = sprintf("</keep><localize>Build: %(buildDate)s - %(buildDetails)s</localize><keep>", { buildDate: buildTime(0), buildDetails: buildTime(2) });</keep>
     531                </action>
    533532            </object>
    534533        </object>
    535534    </object>
  • binaries/data/mods/public/po/gl.public.po

     
     1# Adrián Chaves Fernández <adriyetichaves@gmail.com>, 2013.
     2msgid ""
     3msgstr ""
     4"Project-Id-Version: \n"
     5"POT-Creation-Date: 2013-05-29 08:24+0200\n"
     6"PO-Revision-Date: 2013-05-29 08:35+0200\n"
     7"Last-Translator: Adrián Chaves Fernández <adriyetichaves@gmail.com>\n"
     8"Language-Team: Galician <kde-i18n-doc@kde.org>\n"
     9"Language: gl\n"
     10"MIME-Version: 1.0\n"
     11"Content-Type: text/plain; charset=UTF-8\n"
     12"Content-Transfer-Encoding: 8bit\n"
     13"Plural-Forms: nplurals=2; plural=n != 1;\n"
     14"X-Generator: Lokalize 1.5\n"
     15
     16#. (itstool) path: object/localizableAttribute
     17#: binaries/data/mods/public/gui/pregame/mainmenu.xml:343
     18msgid "Learn To Play"
     19msgstr "Aprender a xogar"
     20
     21#. (itstool) path: object/localizableAttribute
     22#: binaries/data/mods/public/gui/pregame/mainmenu.xml:344
     23msgid "The 0 A.D. Game Manual"
     24msgstr "Manual do xogo."
     25
     26#. (itstool) path: object/localizableAttribute
     27#: binaries/data/mods/public/gui/pregame/mainmenu.xml:360
     28msgid "Single Player"
     29msgstr "Un xogador"
     30
     31#. (itstool) path: object/localizableAttribute
     32#: binaries/data/mods/public/gui/pregame/mainmenu.xml:361
     33msgid "Challenge the computer player to a single player match."
     34msgstr "Xoga unha partida contra a intelixencia artificial."
     35
     36#. (itstool) path: object/localizableAttribute
     37#: binaries/data/mods/public/gui/pregame/mainmenu.xml:375
     38msgid "Multiplayer"
     39msgstr "Varios xogadores"
     40
     41#. (itstool) path: object/localizableAttribute
     42#: binaries/data/mods/public/gui/pregame/mainmenu.xml:376
     43msgid "Fight against one or more human players in a multiplayer game."
     44msgstr "Xoga contra outras persoas."
     45
     46#. (itstool) path: object/localizableAttribute
     47#: binaries/data/mods/public/gui/pregame/mainmenu.xml:390
     48msgid "Tools & Options"
     49msgstr "Ferramentas e opcións"
     50
     51#. (itstool) path: object/localizableAttribute
     52#: binaries/data/mods/public/gui/pregame/mainmenu.xml:391
     53msgid "Game options and scenario design tools."
     54msgstr "Opcións do xogo e ferramentas de deseño de escenarios."
     55
     56#. (itstool) path: object/localizableAttribute
     57#: binaries/data/mods/public/gui/pregame/mainmenu.xml:405
     58msgid "History"
     59msgstr "Historia"
     60
     61#. (itstool) path: object/localizableAttribute
     62#: binaries/data/mods/public/gui/pregame/mainmenu.xml:406
     63msgid "Learn about the many civilizations featured in 0 A.D."
     64msgstr "Infórmate sobre as civilizacións do xogo."
     65
     66#. (itstool) path: object/localizableAttribute
     67#: binaries/data/mods/public/gui/pregame/mainmenu.xml:422
     68msgid "Exit"
     69msgstr "Saír"
     70
     71#. (itstool) path: object/localizableAttribute
     72#: binaries/data/mods/public/gui/pregame/mainmenu.xml:423
     73msgid "Exit Game"
     74msgstr "Saír do xogo."
     75
     76#. (itstool) path: object/localizableAttribute
     77#: binaries/data/mods/public/gui/pregame/mainmenu.xml:450
     78msgid ""
     79"[font=\"serif-bold-16\"]Alpha XIII: Magadha[/font]\\n\\nWARNING: This is an "
     80"early development version of the game. Many features have not been added yet."
     81"\\n\\nGet involved at: play0ad.com"
     82msgstr ""
     83"[font=\"serif-bold-16\"]Alfa XIII: Magadha[/font]\\n"
     84"\\n"
     85"Advertencia: Esta versión do xogo aínda está en pleno desenvolvemento. Queda "
     86"moito por facer.\\n"
     87"\\n"
     88"Colabora: play0ad.com"
     89
     90#. (itstool) path: object/localizableAttribute
     91#: binaries/data/mods/public/gui/pregame/mainmenu.xml:459
     92msgid "Website"
     93msgstr "Sitio web"
     94
     95#. (itstool) path: object/localizableAttribute
     96#: binaries/data/mods/public/gui/pregame/mainmenu.xml:460
     97msgid "Click to open play0ad.com in your web browser."
     98msgstr "Preme aquí para abrir play0ad.com nun navegador web."
     99
     100#. (itstool) path: object/localizableAttribute
     101#: binaries/data/mods/public/gui/pregame/mainmenu.xml:473
     102msgid "Chat"
     103msgstr "Conversa"
     104
     105#. (itstool) path: object/localizableAttribute
     106#: binaries/data/mods/public/gui/pregame/mainmenu.xml:474
     107msgid ""
     108"Click to open the 0 A.D. IRC chat in your browser. (#0ad on webchat.quakenet."
     109"org)"
     110msgstr ""
     111"Preme aquí para abrir una xanela de conversa IRC de 0 A.D. nun navegador web "
     112"(#0ad en webchat.quakenet.org)."
     113
     114#. (itstool) path: object/localizableAttribute
     115#: binaries/data/mods/public/gui/pregame/mainmenu.xml:487
     116msgid "Report a Bug"
     117msgstr "Informar dun erro"
     118
     119#. (itstool) path: object/localizableAttribute
     120#: binaries/data/mods/public/gui/pregame/mainmenu.xml:488
     121msgid "Click to visit 0 A.D. Trac to report a bug, crash, or error"
     122msgstr ""
     123"Preme aquí para visitar o sitio Trac de 0 A.D., no que poderás informar dun "
     124"erro, fallo ou quebra."
     125
     126#. (itstool) path: object/localizableAttribute
     127#: binaries/data/mods/public/gui/pregame/mainmenu.xml:518
     128msgid "WILDFIRE GAMES"
     129msgstr "WILDFIRE GAMES"
     130
     131#. (itstool) path: action/localize
     132#: binaries/data/mods/public/gui/pregame/mainmenu.xml:530
     133msgid "Build: %(buildDate)s - %(buildDetails)s"
     134msgstr "Versión: %(buildDate)s (%(buildDetails)s)"
     135
     136#~ msgid "Alpha XIII: Magadha"
     137#~ msgstr "Alfa XIII: Magadha"
     138
     139#~ msgid "Get involved at: play0ad.com"
     140#~ msgstr "Axúdanos: play0ad.com"
  • binaries/data/mods/public/po/public.pot

     
     1msgid ""
     2msgstr ""
     3"Project-Id-Version: PACKAGE VERSION\n"
     4"POT-Creation-Date: 2013-06-15 21:58+0200\n"
     5"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
     6"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     7"Language-Team: LANGUAGE <LL@li.org>\n"
     8"MIME-Version: 1.0\n"
     9"Content-Type: text/plain; charset=UTF-8\n"
     10"Content-Transfer-Encoding: 8bit\n"
     11
     12#. (itstool) path: object/localizableAttribute
     13#: binaries/data/mods/public/gui/pregame/mainmenu.xml:343
     14msgid "Learn To Play"
     15msgstr ""
     16
     17#. (itstool) path: object/localizableAttribute
     18#: binaries/data/mods/public/gui/pregame/mainmenu.xml:344
     19msgid "The 0 A.D. Game Manual"
     20msgstr ""
     21
     22#. (itstool) path: object/localizableAttribute
     23#: binaries/data/mods/public/gui/pregame/mainmenu.xml:360
     24msgid "Single Player"
     25msgstr ""
     26
     27#. (itstool) path: object/localizableAttribute
     28#: binaries/data/mods/public/gui/pregame/mainmenu.xml:361
     29msgid "Challenge the computer player to a single player match."
     30msgstr ""
     31
     32#. (itstool) path: object/localizableAttribute
     33#: binaries/data/mods/public/gui/pregame/mainmenu.xml:375
     34msgid "Multiplayer"
     35msgstr ""
     36
     37#. (itstool) path: object/localizableAttribute
     38#: binaries/data/mods/public/gui/pregame/mainmenu.xml:376
     39msgid "Fight against one or more human players in a multiplayer game."
     40msgstr ""
     41
     42#. (itstool) path: object/localizableAttribute
     43#: binaries/data/mods/public/gui/pregame/mainmenu.xml:390
     44msgid "Tools & Options"
     45msgstr ""
     46
     47#. (itstool) path: object/localizableAttribute
     48#: binaries/data/mods/public/gui/pregame/mainmenu.xml:391
     49msgid "Game options and scenario design tools."
     50msgstr ""
     51
     52#. (itstool) path: object/localizableAttribute
     53#: binaries/data/mods/public/gui/pregame/mainmenu.xml:405
     54msgid "History"
     55msgstr ""
     56
     57#. (itstool) path: object/localizableAttribute
     58#: binaries/data/mods/public/gui/pregame/mainmenu.xml:406
     59msgid "Learn about the many civilizations featured in 0 A.D."
     60msgstr ""
     61
     62#. (itstool) path: object/localizableAttribute
     63#: binaries/data/mods/public/gui/pregame/mainmenu.xml:422
     64msgid "Exit"
     65msgstr ""
     66
     67#. (itstool) path: object/localizableAttribute
     68#: binaries/data/mods/public/gui/pregame/mainmenu.xml:423
     69msgid "Exit Game"
     70msgstr ""
     71
     72#. (itstool) path: object/localizableAttribute
     73#: binaries/data/mods/public/gui/pregame/mainmenu.xml:450
     74msgid "[font=\"serif-bold-16\"]Alpha XIII: Magadha[/font]\\n\\nWARNING: This is an early development version of the game. Many features have not been added yet.\\n\\nGet involved at: play0ad.com"
     75msgstr ""
     76
     77#. (itstool) path: object/localizableAttribute
     78#: binaries/data/mods/public/gui/pregame/mainmenu.xml:459
     79msgid "Website"
     80msgstr ""
     81
     82#. (itstool) path: object/localizableAttribute
     83#: binaries/data/mods/public/gui/pregame/mainmenu.xml:460
     84msgid "Click to open play0ad.com in your web browser."
     85msgstr ""
     86
     87#. (itstool) path: object/localizableAttribute
     88#: binaries/data/mods/public/gui/pregame/mainmenu.xml:473
     89msgid "Chat"
     90msgstr ""
     91
     92#. (itstool) path: object/localizableAttribute
     93#: binaries/data/mods/public/gui/pregame/mainmenu.xml:474
     94msgid "Click to open the 0 A.D. IRC chat in your browser. (#0ad on webchat.quakenet.org)"
     95msgstr ""
     96
     97#. (itstool) path: object/localizableAttribute
     98#: binaries/data/mods/public/gui/pregame/mainmenu.xml:487
     99msgid "Report a Bug"
     100msgstr ""
     101
     102#. (itstool) path: object/localizableAttribute
     103#: binaries/data/mods/public/gui/pregame/mainmenu.xml:488
     104msgid "Click to visit 0 A.D. Trac to report a bug, crash, or error"
     105msgstr ""
     106
     107#. (itstool) path: object/localizableAttribute
     108#: binaries/data/mods/public/gui/pregame/mainmenu.xml:518
     109msgid "WILDFIRE GAMES"
     110msgstr ""
     111
     112#. (itstool) path: action/localize
     113#: binaries/data/mods/public/gui/pregame/mainmenu.xml:530
     114msgid "Build: %(buildDate)s - %(buildDetails)s"
     115msgstr ""
     116
  • build/premake/extern_libs4.lua

     
    567567            end
    568568        end,
    569569    },
     570    tinygettext = {
     571        compile_settings = function()
     572            if not _OPTIONS["with-system-tinygettext"] then
     573                includedirs { libraries_source_dir .. "tinygettext" }
     574            end
     575        end,
     576        link_settings = function()
     577            if not _OPTIONS["with-system-tinygettext"] then
     578                add_source_lib_paths("tinygettext")
     579            end
     580            add_default_links({
     581                win_names  = { "tinygettext" },
     582                unix_names = { "tinygettext" },
     583            })
     584        end,
     585    },
    570586    valgrind = {
    571587        compile_settings = function()
    572588            add_source_include_paths("valgrind")
  • build/premake/premake4.lua

     
    1313newoption { trigger = "with-system-nvtt", description = "Search standard paths for nvidia-texture-tools library, instead of using bundled copy" }
    1414newoption { trigger = "with-system-enet", description = "Search standard paths for libenet, instead of using bundled copy" }
    1515newoption { trigger = "with-system-mozjs185", description = "Search standard paths for libmozjs185, instead of using bundled copy" }
     16newoption { trigger = "with-system-tinygettext", description = "Search standard paths for tinygettext, instead of using bundled copy" }
    1617newoption { trigger = "sysroot", description = "Set compiler system root path, used for building against a non-system SDK. For example /usr/local becomes SYSROOT/user/local" }
    1718newoption { trigger = "macosx-version-min", description = "Set minimum required version of the OS X API, the build will possibly fail if an older SDK is used, while newer API functions will be weakly linked (i.e. resolved at runtime)" }
    1819newoption { trigger = "macosx-bundle", description = "Enable OSX bundle, the argument is the bundle identifier string (e.g. com.wildfiregames.0ad)" }
     
    622623        "spidermonkey",
    623624        "sdl",  -- key definitions
    624625        "opengl",
    625         "boost"
     626        "boost",
     627        "tinygettext",
    626628    }
    627629    setup_static_lib_project("gui", source_dirs, extern_libs, {})
    628630
     
    653655        "libjpg",
    654656        "valgrind",
    655657        "cxxtest",
     658        "tinygettext",
    656659    }
    657660
    658661    -- CPU architecture-specific
     
    743746    "cxxtest",
    744747    "comsuppw",
    745748    "enet",
     749    "tinygettext",
    746750    "libcurl",
    747751
    748752    "valgrind",
  • build/workspaces/update-workspaces.sh

     
    3737with_system_nvtt=false
    3838with_system_enet=false
    3939with_system_mozjs185=false
     40with_system_tinygettext=false
    4041enable_atlas=true
    4142
    4243for i in "$@"
     
    4647    --with-system-nvtt ) with_system_nvtt=true; premake_args="${premake_args} --with-system-nvtt" ;;
    4748    --with-system-enet ) with_system_enet=true; premake_args="${premake_args} --with-system-enet" ;;
    4849    --with-system-mozjs185 ) with_system_mozjs185=true; premake_args="${premake_args} --with-system-mozjs185" ;;
     50    --with-system-tinygettext ) with_system_tinygettext=true; premake_args="${premake_args} --with-system-tinygettext" ;;
    4951    --enable-atlas ) enable_atlas=true ;;
    5052    --disable-atlas ) enable_atlas=false ;;
    5153    -j* ) JOBS=$i ;;
     
    9193    (cd ../../libraries/source/enet && MAKE=${MAKE} JOBS=${JOBS} ./build.sh) || die "ENet build failed"
    9294  fi
    9395  echo
     96  if [ "$with_system_tinygettext" = "false" ]; then
     97    (cd ../../libraries/source/tinygettext && JOBS=${JOBS} ./build.sh) || die "TinyGettext build failed"
     98  fi
     99  echo
    94100fi
    95101
    96102# Now build premake and run it to create the makefiles
  • libraries/LICENSE.txt

     
    2323  source/spidermonkey
    2424    MPL / GPL / LGPL
    2525
     26  source/tinygettext
     27    GNU GPL v2 (see COPYING)
     28
    2629  source/valgrind
    2730    BSD
    2831
  • libraries/source/tinygettext/CMakeLists.txt

     
     1#
     2# TinyGetText build script
     3# Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
     4#
     5# This program is free software; you can redistribute it and/or modify
     6# it under the terms of the GNU General Public License as published by
     7# the Free Software Foundation; either version 2 of the License, or
     8# (at your option) any later version.
     9#
     10# This program is distributed in the hope that it will be useful,
     11# but WITHOUT ANY WARRANTY; without even the implied warranty of
     12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13# GNU General Public License for more details.
     14#
     15# You should have received a copy of the GNU General Public License
     16# along with this program; if not, write to the Free Software
     17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     18#
     19
     20
     21#
     22# INSTRUCTIONS:
     23# -------------
     24#
     25# Create a directory build/ and change to it. Run
     26#
     27#   cmake ..
     28#
     29# This creates a set of Makefiles to build the project. Run
     30#
     31#   make
     32#
     33
     34
     35CMAKE_POLICY(SET CMP0005 NEW)
     36
     37## Project name to use as command prefix
     38
     39PROJECT(tinygettext)
     40SET(VERSION "0.1")
     41
     42### CMake configuration
     43
     44CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
     45IF(COMMAND cmake_policy)
     46    CMAKE_POLICY(SET CMP0003 NEW)
     47ENDIF(COMMAND cmake_policy)
     48SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${tinygettext_SOURCE_DIR})
     49
     50# move some config clutter to the advanced section
     51MARK_AS_ADVANCED(
     52    CMAKE_BACKWARDS_COMPATIBILITY
     53    CMAKE_BUILD_TYPE
     54    CMAKE_INSTALL_PREFIX
     55    EXECUTABLE_OUTPUT_PATH
     56    CMAKE_OSX_ARCHITECTURES
     57    CMAKE_OSX_SYSROOT
     58)
     59
     60## Reveal library type choice to users
     61OPTION(BUILD_SHARED_LIBS "Produce dynamic library instead of static archive" ON)
     62
     63## Add iconv to include directories
     64
     65FIND_PACKAGE(ICONV REQUIRED)
     66INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
     67
     68## Check iconv_const
     69
     70INCLUDE(CheckCXXSourceCompiles)
     71
     72SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${ICONV_INCLUDE_DIR})
     73CHECK_CXX_SOURCE_COMPILES(
     74    "
     75    #include <iconv.h>
     76    // this declaration will fail when there already exists a non const char** version which returns size_t
     77    double iconv(iconv_t cd,  char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
     78    int main() { return 0; }
     79    "
     80    HAVE_ICONV_CONST
     81)
     82
     83# TODO: better way of config
     84
     85IF(HAVE_ICONV_CONST)
     86  ADD_DEFINITIONS(-DHAVE_ICONV_CONST)
     87ELSE(HAVE_ICONV_CONST)
     88  REMOVE_DEFINITIONS(-DHAVE_ICONV_CONST)
     89ENDIF(HAVE_ICONV_CONST)
     90
     91## TinyGetText library compilation
     92
     93## build list of source files
     94
     95FILE(GLOB TINYGETTEXT_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} tinygettext/*.cpp)
     96FILE(GLOB TINYGETTEXT_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} tinygettext/*.hpp)
     97
     98## define a target for building the library
     99
     100ADD_LIBRARY(tinygettext ${TINYGETTEXT_SOURCES})
     101
     102## Add tinygettext dir to search path
     103
     104INCLUDE_DIRECTORIES(${tinygettext_SOURCE_DIR})
     105
     106## Debug options
     107
     108OPTION(WERROR "Stops on first compiler warning in debug mode" OFF)
     109IF(CMAKE_COMPILER_IS_GNUCC)
     110  ADD_DEFINITIONS(-O3 -Wall -Wextra -Weffc++ -pedantic)
     111  # -ansi fails in MinGW
     112  OPTION(WARNINGS "Enable long list of warnings for compiler to check" ON)
     113  IF(WARNINGS)
     114    ADD_DEFINITIONS(
     115          -Wabi  -Wctor-dtor-privacy
     116          -Wstrict-null-sentinel
     117          -Wold-style-cast
     118          -Woverloaded-virtual
     119          -Wsign-promo -Wswitch-enum
     120          -Wcast-align  -Wcast-qual
     121          -Wdisabled-optimization
     122          -Wfloat-equal 
     123          -Wformat=2
     124          -Winit-self
     125          -Winvalid-pch  -Wunsafe-loop-optimizations
     126          -Wlogical-op
     127          -Wmissing-format-attribute  -Wmissing-include-dirs -Wmissing-noreturn
     128          -Wpacked
     129          -Wredundant-decls
     130          -Wshadow
     131          -Wsign-conversion  -Wstack-protector
     132          -Wstrict-overflow=5
     133          -Wswitch-default  -Wswitch-enum
     134          -Wundef)
     135        # Still left:
     136        # -Wconversion  (find alternative to using toupper(int) on char)
     137        # -Wpadded      (DictionaryManager has a bool that sticks out)
     138  ENDIF(WARNINGS)
     139  IF(WERROR)
     140    ADD_DEFINITIONS(-Werror)
     141  ENDIF(WERROR)
     142ENDIF(CMAKE_COMPILER_IS_GNUCC)
     143
     144## Extra definitions
     145
     146ADD_DEFINITIONS(-DVERSION=\\\"${VERSION}\\\")
     147
     148## Generate test executables in the right place
     149
     150SET(EXECUTABLE_OUTPUT_PATH ${tinygettext_BINARY_DIR}/test)
     151
     152## Build tinygettext tests
     153
     154FOREACH(TEST tinygettext_test po_parser_test)
     155  ## Add target for tinygettext test
     156  ADD_EXECUTABLE(${TEST} test/${TEST}.cpp)
     157  ## Link with tinygettext library
     158  TARGET_LINK_LIBRARIES(${TEST} tinygettext)
     159  TARGET_LINK_LIBRARIES(${TEST} ${ICONV_LIBRARY})
     160ENDFOREACH(TEST)
     161
     162## Install tinygettext
     163
     164# use standardized variable name
     165SET(LIB_SUBDIR "lib${LIB_SUFFIX}"
     166    CACHE STRING "Subdirectory of prefix into which libraries are installed (e.g., lib32, lib64)")
     167
     168## prepare tinygettext.pc
     169CONFIGURE_FILE(tinygettext.pc.in tinygettext.pc @ONLY)
     170
     171INSTALL(TARGETS tinygettext
     172    ARCHIVE DESTINATION ${LIB_SUBDIR}
     173    LIBRARY DESTINATION ${LIB_SUBDIR})
     174INSTALL(FILES ${TINYGETTEXT_HEADERS}
     175    DESTINATION include/tinygettext)
     176INSTALL(FILES ${tinygettext_BINARY_DIR}/tinygettext.pc
     177    DESTINATION ${LIB_SUBDIR}/pkgconfig)
  • libraries/source/tinygettext/COPYING

     
     1                    GNU GENERAL PUBLIC LICENSE
     2                       Version 2, June 1991
     3
     4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
     5 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     6 Everyone is permitted to copy and distribute verbatim copies
     7 of this license document, but changing it is not allowed.
     8
     9                            Preamble
     10
     11  The licenses for most software are designed to take away your
     12freedom to share and change it.  By contrast, the GNU General Public
     13License is intended to guarantee your freedom to share and change free
     14software--to make sure the software is free for all its users.  This
     15General Public License applies to most of the Free Software
     16Foundation's software and to any other program whose authors commit to
     17using it.  (Some other Free Software Foundation software is covered by
     18the GNU Lesser General Public License instead.)  You can apply it to
     19your programs, too.
     20
     21  When we speak of free software, we are referring to freedom, not
     22price.  Our General Public Licenses are designed to make sure that you
     23have the freedom to distribute copies of free software (and charge for
     24this service if you wish), that you receive source code or can get it
     25if you want it, that you can change the software or use pieces of it
     26in new free programs; and that you know you can do these things.
     27
     28  To protect your rights, we need to make restrictions that forbid
     29anyone to deny you these rights or to ask you to surrender the rights.
     30These restrictions translate to certain responsibilities for you if you
     31distribute copies of the software, or if you modify it.
     32
     33  For example, if you distribute copies of such a program, whether
     34gratis or for a fee, you must give the recipients all the rights that
     35you have.  You must make sure that they, too, receive or can get the
     36source code.  And you must show them these terms so they know their
     37rights.
     38
     39  We protect your rights with two steps: (1) copyright the software, and
     40(2) offer you this license which gives you legal permission to copy,
     41distribute and/or modify the software.
     42
     43  Also, for each author's protection and ours, we want to make certain
     44that everyone understands that there is no warranty for this free
     45software.  If the software is modified by someone else and passed on, we
     46want its recipients to know that what they have is not the original, so
     47that any problems introduced by others will not reflect on the original
     48authors' reputations.
     49
     50  Finally, any free program is threatened constantly by software
     51patents.  We wish to avoid the danger that redistributors of a free
     52program will individually obtain patent licenses, in effect making the
     53program proprietary.  To prevent this, we have made it clear that any
     54patent must be licensed for everyone's free use or not licensed at all.
     55
     56  The precise terms and conditions for copying, distribution and
     57modification follow.
     58
     59                    GNU GENERAL PUBLIC LICENSE
     60   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
     61
     62  0. This License applies to any program or other work which contains
     63a notice placed by the copyright holder saying it may be distributed
     64under the terms of this General Public License.  The "Program", below,
     65refers to any such program or work, and a "work based on the Program"
     66means either the Program or any derivative work under copyright law:
     67that is to say, a work containing the Program or a portion of it,
     68either verbatim or with modifications and/or translated into another
     69language.  (Hereinafter, translation is included without limitation in
     70the term "modification".)  Each licensee is addressed as "you".
     71
     72Activities other than copying, distribution and modification are not
     73covered by this License; they are outside its scope.  The act of
     74running the Program is not restricted, and the output from the Program
     75is covered only if its contents constitute a work based on the
     76Program (independent of having been made by running the Program).
     77Whether that is true depends on what the Program does.
     78
     79  1. You may copy and distribute verbatim copies of the Program's
     80source code as you receive it, in any medium, provided that you
     81conspicuously and appropriately publish on each copy an appropriate
     82copyright notice and disclaimer of warranty; keep intact all the
     83notices that refer to this License and to the absence of any warranty;
     84and give any other recipients of the Program a copy of this License
     85along with the Program.
     86
     87You may charge a fee for the physical act of transferring a copy, and
     88you may at your option offer warranty protection in exchange for a fee.
     89
     90  2. You may modify your copy or copies of the Program or any portion
     91of it, thus forming a work based on the Program, and copy and
     92distribute such modifications or work under the terms of Section 1
     93above, provided that you also meet all of these conditions:
     94
     95    a) You must cause the modified files to carry prominent notices
     96    stating that you changed the files and the date of any change.
     97
     98    b) You must cause any work that you distribute or publish, that in
     99    whole or in part contains or is derived from the Program or any
     100    part thereof, to be licensed as a whole at no charge to all third
     101    parties under the terms of this License.
     102
     103    c) If the modified program normally reads commands interactively
     104    when run, you must cause it, when started running for such
     105    interactive use in the most ordinary way, to print or display an
     106    announcement including an appropriate copyright notice and a
     107    notice that there is no warranty (or else, saying that you provide
     108    a warranty) and that users may redistribute the program under
     109    these conditions, and telling the user how to view a copy of this
     110    License.  (Exception: if the Program itself is interactive but
     111    does not normally print such an announcement, your work based on
     112    the Program is not required to print an announcement.)
     113
     114These requirements apply to the modified work as a whole.  If
     115identifiable sections of that work are not derived from the Program,
     116and can be reasonably considered independent and separate works in
     117themselves, then this License, and its terms, do not apply to those
     118sections when you distribute them as separate works.  But when you
     119distribute the same sections as part of a whole which is a work based
     120on the Program, the distribution of the whole must be on the terms of
     121this License, whose permissions for other licensees extend to the
     122entire whole, and thus to each and every part regardless of who wrote it.
     123
     124Thus, it is not the intent of this section to claim rights or contest
     125your rights to work written entirely by you; rather, the intent is to
     126exercise the right to control the distribution of derivative or
     127collective works based on the Program.
     128
     129In addition, mere aggregation of another work not based on the Program
     130with the Program (or with a work based on the Program) on a volume of
     131a storage or distribution medium does not bring the other work under
     132the scope of this License.
     133
     134  3. You may copy and distribute the Program (or a work based on it,
     135under Section 2) in object code or executable form under the terms of
     136Sections 1 and 2 above provided that you also do one of the following:
     137
     138    a) Accompany it with the complete corresponding machine-readable
     139    source code, which must be distributed under the terms of Sections
     140    1 and 2 above on a medium customarily used for software interchange; or,
     141
     142    b) Accompany it with a written offer, valid for at least three
     143    years, to give any third party, for a charge no more than your
     144    cost of physically performing source distribution, a complete
     145    machine-readable copy of the corresponding source code, to be
     146    distributed under the terms of Sections 1 and 2 above on a medium
     147    customarily used for software interchange; or,
     148
     149    c) Accompany it with the information you received as to the offer
     150    to distribute corresponding source code.  (This alternative is
     151    allowed only for noncommercial distribution and only if you
     152    received the program in object code or executable form with such
     153    an offer, in accord with Subsection b above.)
     154
     155The source code for a work means the preferred form of the work for
     156making modifications to it.  For an executable work, complete source
     157code means all the source code for all modules it contains, plus any
     158associated interface definition files, plus the scripts used to
     159control compilation and installation of the executable.  However, as a
     160special exception, the source code distributed need not include
     161anything that is normally distributed (in either source or binary
     162form) with the major components (compiler, kernel, and so on) of the
     163operating system on which the executable runs, unless that component
     164itself accompanies the executable.
     165
     166If distribution of executable or object code is made by offering
     167access to copy from a designated place, then offering equivalent
     168access to copy the source code from the same place counts as
     169distribution of the source code, even though third parties are not
     170compelled to copy the source along with the object code.
     171
     172  4. You may not copy, modify, sublicense, or distribute the Program
     173except as expressly provided under this License.  Any attempt
     174otherwise to copy, modify, sublicense or distribute the Program is
     175void, and will automatically terminate your rights under this License.
     176However, parties who have received copies, or rights, from you under
     177this License will not have their licenses terminated so long as such
     178parties remain in full compliance.
     179
     180  5. You are not required to accept this License, since you have not
     181signed it.  However, nothing else grants you permission to modify or
     182distribute the Program or its derivative works.  These actions are
     183prohibited by law if you do not accept this License.  Therefore, by
     184modifying or distributing the Program (or any work based on the
     185Program), you indicate your acceptance of this License to do so, and
     186all its terms and conditions for copying, distributing or modifying
     187the Program or works based on it.
     188
     189  6. Each time you redistribute the Program (or any work based on the
     190Program), the recipient automatically receives a license from the
     191original licensor to copy, distribute or modify the Program subject to
     192these terms and conditions.  You may not impose any further
     193restrictions on the recipients' exercise of the rights granted herein.
     194You are not responsible for enforcing compliance by third parties to
     195this License.
     196
     197  7. If, as a consequence of a court judgment or allegation of patent
     198infringement or for any other reason (not limited to patent issues),
     199conditions are imposed on you (whether by court order, agreement or
     200otherwise) that contradict the conditions of this License, they do not
     201excuse you from the conditions of this License.  If you cannot
     202distribute so as to satisfy simultaneously your obligations under this
     203License and any other pertinent obligations, then as a consequence you
     204may not distribute the Program at all.  For example, if a patent
     205license would not permit royalty-free redistribution of the Program by
     206all those who receive copies directly or indirectly through you, then
     207the only way you could satisfy both it and this License would be to
     208refrain entirely from distribution of the Program.
     209
     210If any portion of this section is held invalid or unenforceable under
     211any particular circumstance, the balance of the section is intended to
     212apply and the section as a whole is intended to apply in other
     213circumstances.
     214
     215It is not the purpose of this section to induce you to infringe any
     216patents or other property right claims or to contest validity of any
     217such claims; this section has the sole purpose of protecting the
     218integrity of the free software distribution system, which is
     219implemented by public license practices.  Many people have made
     220generous contributions to the wide range of software distributed
     221through that system in reliance on consistent application of that
     222system; it is up to the author/donor to decide if he or she is willing
     223to distribute software through any other system and a licensee cannot
     224impose that choice.
     225
     226This section is intended to make thoroughly clear what is believed to
     227be a consequence of the rest of this License.
     228
     229  8. If the distribution and/or use of the Program is restricted in
     230certain countries either by patents or by copyrighted interfaces, the
     231original copyright holder who places the Program under this License
     232may add an explicit geographical distribution limitation excluding
     233those countries, so that distribution is permitted only in or among
     234countries not thus excluded.  In such case, this License incorporates
     235the limitation as if written in the body of this License.
     236
     237  9. The Free Software Foundation may publish revised and/or new versions
     238of the General Public License from time to time.  Such new versions will
     239be similar in spirit to the present version, but may differ in detail to
     240address new problems or concerns.
     241
     242Each version is given a distinguishing version number.  If the Program
     243specifies a version number of this License which applies to it and "any
     244later version", you have the option of following the terms and conditions
     245either of that version or of any later version published by the Free
     246Software Foundation.  If the Program does not specify a version number of
     247this License, you may choose any version ever published by the Free Software
     248Foundation.
     249
     250  10. If you wish to incorporate parts of the Program into other free
     251programs whose distribution conditions are different, write to the author
     252to ask for permission.  For software which is copyrighted by the Free
     253Software Foundation, write to the Free Software Foundation; we sometimes
     254make exceptions for this.  Our decision will be guided by the two goals
     255of preserving the free status of all derivatives of our free software and
     256of promoting the sharing and reuse of software generally.
     257
     258                            NO WARRANTY
     259
     260  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
     261FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
     262OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
     263PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
     264OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     265MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
     266TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
     267PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
     268REPAIR OR CORRECTION.
     269
     270  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
     271WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
     272REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
     273INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
     274OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
     275TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
     276YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
     277PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
     278POSSIBILITY OF SUCH DAMAGES.
     279
     280                     END OF TERMS AND CONDITIONS
     281
     282            How to Apply These Terms to Your New Programs
     283
     284  If you develop a new program, and you want it to be of the greatest
     285possible use to the public, the best way to achieve this is to make it
     286free software which everyone can redistribute and change under these terms.
     287
     288  To do so, attach the following notices to the program.  It is safest
     289to attach them to the start of each source file to most effectively
     290convey the exclusion of warranty; and each file should have at least
     291the "copyright" line and a pointer to where the full notice is found.
     292
     293    tinygettext - A gettext replacement that works directly on .po files
     294    Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     295
     296    This program is free software; you can redistribute it and/or modify
     297    it under the terms of the GNU General Public License as published by
     298    the Free Software Foundation; either version 2 of the License, or
     299    (at your option) any later version.
     300
     301    This program is distributed in the hope that it will be useful,
     302    but WITHOUT ANY WARRANTY; without even the implied warranty of
     303    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     304    GNU General Public License for more details.
     305
     306    You should have received a copy of the GNU General Public License along
     307    with this program; if not, write to the Free Software Foundation, Inc.,
     308    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     309
     310Also add information on how to contact you by electronic and paper mail.
     311
     312If the program is interactive, make it output a short notice like this
     313when it starts in an interactive mode:
     314
     315    Gnomovision version 69, Copyright (C) year name of author
     316    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     317    This is free software, and you are welcome to redistribute it
     318    under certain conditions; type `show c' for details.
     319
     320The hypothetical commands `show w' and `show c' should show the appropriate
     321parts of the General Public License.  Of course, the commands you use may
     322be called something other than `show w' and `show c'; they could even be
     323mouse-clicks or menu items--whatever suits your program.
     324
     325You should also get your employer (if you work as a programmer) or your
     326school, if any, to sign a "copyright disclaimer" for the program, if
     327necessary.  Here is a sample; alter the names:
     328
     329  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
     330  `Gnomovision' (which makes passes at compilers) written by James Hacker.
     331
     332  <signature of Ty Coon>, 1 April 1989
     333  Ty Coon, President of Vice
     334
     335This General Public License does not permit incorporating your program into
     336proprietary programs.  If your program is a subroutine library, you may
     337consider it more useful to permit linking proprietary applications with the
     338library.  If this is what you want to do, use the GNU Lesser General
     339Public License instead of this License.
  • libraries/source/tinygettext/FindICONV.cmake

     
     1#
     2#  Copyright (c) 2006, Peter Kümmel, <syntheticpp@gmx.net>
     3#
     4#  Redistribution and use in source and binary forms, with or without
     5#  modification, are permitted provided that the following conditions
     6#  are met:
     7
     8#  1. Redistributions of source code must retain the copyright
     9#     notice, this list of conditions and the following disclaimer.
     10#  2. Redistributions in binary form must reproduce the copyright
     11#     notice, this list of conditions and the following disclaimer in the
     12#     documentation and/or other materials provided with the distribution.
     13#  3. The name of the author may not be used to endorse or promote products
     14#     derived from this software without specific prior written permission.
     15
     16#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17#  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18#  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19#  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21#  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22#  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23#  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25#  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26
     27
     28set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
     29
     30if (ICONV_INCLUDE_DIR)
     31  # Already in cache, be silent
     32  set(ICONV_FIND_QUIETLY TRUE)
     33endif()
     34
     35find_path(ICONV_INCLUDE_DIR iconv.h
     36 /usr/include
     37 /usr/local/include)
     38
     39set(POTENTIAL_ICONV_LIBS iconv libiconv libiconv2)
     40
     41find_library(ICONV_LIBRARY NAMES ${POTENTIAL_ICONV_LIBS}
     42    PATHS /usr/lib /usr/local/lib)
     43
     44if(WIN32)
     45    set(ICONV_DLL_NAMES iconv.dll  libiconv.dll libiconv2.dll)
     46    find_file(ICONV_DLL   
     47                    NAMES ${ICONV_DLL_NAMES}
     48                    PATHS ENV PATH
     49                    NO_DEFAULT_PATH)
     50    find_file(ICONV_DLL_HELP   
     51                    NAMES ${ICONV_DLL_NAMES}
     52                    PATHS ENV PATH
     53                    ${ICONV_INCLUDE_DIR}/../bin)
     54    if(ICONV_FIND_REQUIRED)
     55        if(NOT ICONV_DLL AND NOT ICONV_DLL_HELP)
     56            message(FATAL_ERROR "Could not find iconv.dll, please add correct your PATH environment variable")
     57        endif()
     58        if(NOT ICONV_DLL AND ICONV_DLL_HELP)
     59            get_filename_component(ICONV_DLL_HELP ${ICONV_DLL_HELP} PATH)
     60            message(STATUS)
     61            message(STATUS "Could not find iconv.dll in standard search path, please add ")
     62            message(STATUS "${ICONV_DLL_HELP}")
     63            message(STATUS "to your PATH environment variable.")
     64            message(STATUS)
     65            message(FATAL_ERROR "exit cmake")
     66        endif()
     67    endif()
     68    if(ICONV_INCLUDE_DIR AND ICONV_LIBRARY AND ICONV_DLL)
     69        set(ICONV_FOUND TRUE)
     70    endif()
     71else()
     72    include(CheckFunctionExists)
     73    check_function_exists(iconv HAVE_ICONV_IN_LIBC)
     74    if(ICONV_INCLUDE_DIR AND HAVE_ICONV_IN_LIBC)
     75        set(ICONV_FOUND TRUE)
     76        set(ICONV_LIBRARY  CACHE TYPE STRING FORCE)
     77    endif()
     78    if(ICONV_INCLUDE_DIR AND ICONV_LIBRARY)
     79        set(ICONV_FOUND TRUE)
     80    endif()
     81endif()
     82
     83
     84
     85if(ICONV_FOUND)
     86   if(NOT ICONV_FIND_QUIETLY)
     87      message(STATUS "Found iconv library: ${ICONV_LIBRARY}")
     88      #message(STATUS "Found iconv   dll  : ${ICONV_DLL}")
     89   endif()
     90else()
     91   if(ICONV_FIND_REQUIRED)
     92      message(STATUS "Looked for iconv library named ${POTENTIAL_ICONV_LIBS}.")
     93      message(STATUS "Found no acceptable iconv library. This is fatal.")
     94      message(STATUS "iconv header: ${ICONV_INCLUDE_DIR}")
     95      message(STATUS "iconv lib   : ${ICONV_LIBRARY}")
     96      message(FATAL_ERROR "Could NOT find iconv library")
     97   endif()
     98endif()
     99
     100mark_as_advanced(ICONV_LIBRARY ICONV_INCLUDE_DIR)
  • libraries/source/tinygettext/NEWS

     
     1tinygettext 0.0.1 - (??. Feb 2009)
     2==================================
     3
     4* initial release
     5
     6# EOF #
  • libraries/source/tinygettext/README

     
     1tinygettext
     2===========
     3
     4tinygettext is a minimal gettext() replacement written in C++. It can
     5read .po files directly and doesn't need .mo files generated from .po.
     6It also can read the .po files from arbitary locations, so its much
     7better suited for non-Unix systems and situations in which one wants
     8to store or distrubite .po files seperatly from the software itself.
     9
     10
     11
     12Detecting the locale setting
     13============================
     14
     15Different operating systems store the default locale in different
     16places; a portable way to find it is provided by FindLocale:
     17
     18 * http://icculus.org/~aspirin/findlocale/
     19
     20
     21# EOF #
  • libraries/source/tinygettext/SConstruct

     
     1# -*- python -*-
     2
     3env = Environment(CXXFLAGS=['-O0',
     4                            '-g3',
     5                            '-Wall',
     6                            '-Wcast-qual',
     7                            '-Wconversion',
     8                            '-Weffc++',
     9                            '-Werror',
     10                            '-Wextra',
     11                            '-Winit-self',
     12                            '-Wno-unused-parameter',
     13                            '-Wnon-virtual-dtor',
     14                            '-Wshadow',
     15                            '-ansi',
     16                            '-pedantic',
     17                            ],
     18                  CPPPATH=['tinygettext', '.'])
     19
     20# env.ParseConfig("sdl-config --cflags --libs")
     21# env['CPPDEFINES'] += HAVE_SDL
     22
     23libtinygettext = env.SharedLibrary('tinygettext/tinygettext',
     24                                   ['tinygettext/tinygettext.cpp',
     25                                    'tinygettext/language.cpp',
     26                                    'tinygettext/plural_forms.cpp',
     27                                    'tinygettext/dictionary.cpp',
     28                                    'tinygettext/dictionary_manager.cpp',
     29                                    'tinygettext/unix_file_system.cpp',
     30                                    'tinygettext/po_parser.cpp',
     31                                    'tinygettext/iconv.cpp',
     32                                    'tinygettext/log.cpp'])
     33
     34env.Program('test/tinygettext_test', ['test/tinygettext_test.cpp', libtinygettext])
     35env.Program('test/po_parser_test', ['test/po_parser_test.cpp', libtinygettext])
     36
     37# EOF #
  • libraries/source/tinygettext/TODO

     
     1tinygettext API related stuff:
     2==============================
     3
     4* translate, translate_ctxt, translate_ctxt_plural, ... could be
     5  unified via overloading, not sure if that is a good idea. For the
     6  same reason add_translation() could be de-overloaded, to
     7  add_translation_ctxt, ...
     8
     9* iconv handling needs cleanup and more flexibility, since some
     10  systems don't provide iconv or only through SDL
     11
     12* Customizability could use grouping and documentation or other means
     13  to make it more obvious:
     14
     15  - POParser::pedantic
     16  - iconv (???)
     17  - logging (log_callback(std::string))
     18
     19* handle errors better, not with log_* stream, cases of errors:
     20
     21  - couldn't translate
     22  - collision while adding translation
     23  - failure to open file or directory
     24  - unknown language
     25  - iconv failure to convert charset
     26
     27* ABI management/freezing. If tinygettext is to benefit other projects,
     28  it should be able to provide a stable API (and, better, ABI).
     29
     30
     31tinygettext implementation details:
     32===================================
     33
     34* with PluralForms moved into Dictionary a lot of the Langugae stuff
     35  is pointless
     36
     37* get rid of goto
     38
     39* POParser can handle Big5, but needs testing.
     40  Big5 is one byte for ASCII letters and two bytes for chinese ones,
     41  this means some two byte characters collide with '\', some .po files
     42  seem to escape the \ properly so that the string can be read as
     43  usual, while others don't.
     44
     45* _()  -> getext() (gettext default)
     46  N_(id) -> gettext_noop(id) (gettext default)
     47  C_(ctxt, id) -> pgettext(ctxt, id) (Gnome does this: http://library.gnome.org/devel/glib/2.16/glib-I18N.html#Q-:CAPS)
     48  NC_(ctxt, id) -> pgettext(ctxt, id) (Gnome does this: http://library.gnome.org/devel/glib/2.16/glib-I18N.html#Q-:CAPS)
     49
     50* figure out how up-to-date other tinygettext implementations in the
     51  wild are (LinCity):
     52
     53  Pingus:
     54  -------
     55  dictionary.hpp (synced with Pingus)
     56  dictionary_manager.hpp (PhysFS vs opendir())
     57  language_def.hpp (synced with Pingus)
     58  po_file_reader.hpp (UTF-8 0xef-'header', lots of stuff from mathner)
     59  tinygettext.hpp (iconv vs convert)
     60
     61
    062
     63Random Unimportant Stuff
     64========================
     65
     66* a hashmap instead of std::map might be a good idea
     67
     68* support for .gmo files would be cool
     69
    170
     71tinygettext Documentation:
     72==========================
     73
     74* recommend a way to handle translation of speech and other data files
     75
     76* document how to use tinygettext and make it work like gettext
  • libraries/source/tinygettext/build.sh

    +
    
    +# EOF #
     
     1#!/bin/sh
     2
     3set -e
     4
     5JOBS=${JOBS:="-j2"}
     6
     7echo "Building TinyGettext…"
     8echo
     9
     10scons ${JOBS}
     11
     12mkdir -p lib/
     13
     14if [ "`uname -s`" = "Darwin" ]
     15then
     16  extension=dylib
     17else
     18  extension=so
     19fi
     20
     21filepath=tinygettext/libtinygettext.${extension}
     22cp $filepath lib/
     23cp $filepath ../../../binaries/system/
  • libraries/source/tinygettext/test/broken.po

    Property changes on: libraries/source/tinygettext/build.sh
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1# SOME DESCRIPTIVE TITLE.
     2# Copyright (C) YEAR Free Software Foundation, Inc.
     3# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
     4#
     5#, fuzzy
     6msgid ""
     7msgstr ""
     8"Project-Id-Version: PACKAGE VERSION\n"
     9"Report-Msgid-Bugs-To: \n"
     10"POT-Creation-Date: 2009-01-30 08:01+0100\n"
     11"PO-Revision-Date: 2009-01-30 08:39+0100\n"
     12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     13"Language-Team: LANGUAGE <LL@li.org>\n"
     14"MIME-Version: 1.0\n"
     15"Content-Type: text/plain; charset=UTF-8\n"
     16"Content-Transfer-Encoding: 8bit\n"
     17
     18#: helloworld.cpp:7
     19msgid "Short Hello World"
     20msgstr "kurzes Hallo Welt
     21
     22#: helloworld.cpp:8 helloworld.cpp:14
     23#, fuzzy
     24msgid "Hello World"
     25msgid_plural "Hello Worlds"
     26msgstr[0] "Hallo Welt (singular)"
     27msgstr[1] "Hallo Welt (plural)"
     28msgstr[10] "Hallo Welt (plural)"
     29
     30#: helloworld.cpp:10 helloworld.cpp:16
     31#, fuzzy
     32msgctxt ""
     33msgid "Hello World"
     34msgid_plural "Hello Worlds"
     35msgstr[0] Hallo Welt (singular) mit leerem Kontext"
     36msgstr[1] "Hallo Welt (plural) mit leerem Kontext"
     37
     38#: helloworld.cpp:11 helloworld.cpp:17
     39msgctxt "console"
     40msgid "Hello World"
     41msgid_plural "Hello Worlds"
     42msgstr[0]"Hallo Welt (singular) in der Console"
     43msgstr[1] "Hallo Welt (plural) in der Console"
     44
     45#: helloworld.cpp:13
     46msgid "gui"
     47msgid_plural "Hello World"
     48msgstr[0]   "Hallo Welt (singular)"
     49msgstr[1] "Hallo Welt (plural)"
     50
     51#: helloworld.cpp:18
     52#, fuzzy
     53msgctxt "gui"
     54msgid "Hello World"
     55msgid_plural "Hello Worlds"
     56msgstr[0] "Hallo Welt im GUI"
     57msgstr[1] "Hallo Welt (plural) im GUI"
  • libraries/source/tinygettext/test/game/de.po

     
     1# SOME DESCRIPTIVE TITLE.
     2# Copyright (C) YEAR Free Software Foundation, Inc.
     3# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
     4#
     5msgid ""
     6msgstr ""
     7"Project-Id-Version: Pingus 0.6.0\n"
     8"Report-Msgid-Bugs-To: \n"
     9"POT-Creation-Date: 2004-04-09 18:37+0000\n"
     10"PO-Revision-Date: 2003-04-15 17:31+0200\n"
     11"Last-Translator: David Philippi <david@torangan.de>\n"
     12"Language-Team: David Philippi <david@torangan.de>, Ingo Ruhnke <grumbel@gmx."
     13"de>, Giray Devlet <giray@devlet.cc>\n"
     14"MIME-Version: 1.0\n"
     15"Content-Type: text/plain; charset=ISO-8859-1\n"
     16"Content-Transfer-Encoding: 8bit\n"
     17
     18#: src/actions/bridger.cxx:48 src/actions/bridger.cxx:232
     19#: src/pingu_enums.cxx:40
     20msgid "Bridger"
     21msgstr "Bridger"
     22
     23#: src/config.cxx:73
     24msgid "Couldn't open: "
     25msgstr "Datei oder Verzeichnis konnte nicht geöffnet werden: "
     26
     27#: src/config.cxx:172
     28msgid "Unexpected char: '"
     29msgstr "Unerwartetes Zeichen: '"
     30
     31#: src/config.cxx:206
     32msgid "Unexpected char '"
     33msgstr "Unerwartetes Zeichen: '"
     34
     35#: src/credits.cxx:48
     36msgid "-Idea"
     37msgstr "-Idee"
     38
     39#: src/credits.cxx:52
     40msgid "-Maintaining"
     41msgstr "-Verwaltung"
     42
     43#: src/credits.cxx:56
     44msgid "-Programming"
     45msgstr "-Programmierung"
     46
     47#: src/credits.cxx:62
     48msgid "-Porting (Win32)"
     49msgstr "-Portierung (Win32)"
     50
     51#: src/credits.cxx:70
     52msgid "-Gfx"
     53msgstr "-Grafiken"
     54
     55#: src/credits.cxx:82
     56msgid "-Music"
     57msgstr "-Musik"
     58
     59#: src/credits.cxx:88
     60msgid "-Level Design"
     61msgstr "-Level Design"
     62
     63#: src/credits.cxx:93
     64msgid "-Story"
     65msgstr "-Geschichte"
     66
     67#: src/credits.cxx:97
     68msgid "-Translation"
     69msgstr "-Übersetzung"
     70
     71#: src/credits.cxx:112
     72msgid "-Special"
     73msgstr "-Besonderen"
     74
     75#: src/credits.cxx:113
     76msgid "-Thanks to"
     77msgstr "-Dank an"
     78
     79#: src/credits.cxx:154
     80msgid "_And a very Special Thanks"
     81msgstr "_Und einen besonderen Dank"
     82
     83#: src/credits.cxx:155
     84msgid "_to all the people who"
     85msgstr "_an alle Leute die"
     86
     87#: src/credits.cxx:156
     88msgid "_contribute to"
     89msgstr "_an Freier Software"
     90
     91#: src/credits.cxx:157
     92msgid "_Free Software!"
     93msgstr "_mitarbeiten!"
     94
     95#: src/credits.cxx:163
     96msgid "_Thank you for"
     97msgstr "_Dankeschön fürs"
     98
     99#: src/credits.cxx:164
     100msgid "_playing!"
     101msgstr "_spielen!"
     102
     103#: src/editor/editor_event.cxx:588
     104msgid "Enter filename to save as:"
     105msgstr "Datei speichern als:  "
     106
     107#: src/editor/editor_help_screen.cxx:43
     108msgid "Editor Helpscreen (hide with F1)"
     109msgstr "Editor Hilfe (ausblenden mit F1)"
     110
     111#: src/editor/editor_help_screen.cxx:51
     112msgid "F1 - show/hide this help screen"
     113msgstr "F1 - Hilfe anzeigen/verstecken"
     114
     115#: src/editor/editor_help_screen.cxx:52
     116msgid "F2 - launch level building tutorial"
     117msgstr "F2 - Starte Levelbau Tutorial"
     118
     119#: src/editor/editor_help_screen.cxx:53
     120msgid "F3 - toggle background color"
     121msgstr "F3 - Hintergrundfarbe aendern"
     122
     123#: src/editor/editor_help_screen.cxx:54
     124msgid "F4 - play/test the level"
     125msgstr "F4 - Level starten/testen"
     126
     127#: src/editor/editor_help_screen.cxx:55
     128msgid "F5 - load a level"
     129msgstr "Level Laden (F5)"
     130
     131#: src/editor/editor_help_screen.cxx:56
     132msgid "F6 - save this level"
     133msgstr "Level Speichern (F6)"
     134
     135#: src/editor/editor_help_screen.cxx:57
     136msgid "F7 - [unset]"
     137msgstr "F7 - [nicht belegt]"
     138
     139#: src/editor/editor_help_screen.cxx:58
     140msgid "F8 - quick save/backup save?!"
     141msgstr "F8 - Schnellspeichern/Backup"
     142
     143#: src/editor/editor_help_screen.cxx:59
     144msgid "F9 - change level width and height"
     145msgstr "F9 - Level Höhe und Breite ändern"
     146
     147#: src/editor/editor_help_screen.cxx:60
     148msgid "F10 - [unset]"
     149msgstr "F10 - [nicht belegt]"
     150
     151#: src/editor/editor_help_screen.cxx:61
     152msgid "F11 - toggle fps counter"
     153msgstr "F11 - fps Zähler an/aus"
     154
     155#: src/editor/editor_help_screen.cxx:62
     156msgid "F12 - make screenshot"
     157msgstr "F12 - Screenshot erstellen"
     158
     159#: src/editor/editor_help_screen.cxx:66
     160msgid "Home - increase object size"
     161msgstr "Einfg - Objekt vergrößern"
     162
     163#: src/editor/editor_help_screen.cxx:67
     164msgid "End  - decrease object size"
     165msgstr "Ende - Objekt verkleinern"
     166
     167#: src/editor/editor_help_screen.cxx:68
     168msgid "Cursor Keys - Move object"
     169msgstr "Cursor Tasten - Objekt bewegen"
     170
     171#: src/editor/editor_help_screen.cxx:69
     172msgid "Shift 'Cursor Keys' - Move objects fast "
     173msgstr "Shift Cursor Tasten - Objekt schneller bewegen"
     174
     175#: src/editor/editor_help_screen.cxx:70
     176msgid "PageUp   - level object up"
     177msgstr "Bild rauf - Objekt nach oben"
     178
     179#: src/editor/editor_help_screen.cxx:71
     180msgid "PageDown - level object down"
     181msgstr "Bild runter - Objekt nach unten"
     182
     183#: src/editor/editor_help_screen.cxx:72
     184msgid "Shift PageUp   - increase objects z-pos by 50"
     185msgstr "Shift Bild rauf - Objekt nach oben"
     186
     187#: src/editor/editor_help_screen.cxx:73
     188msgid "Shift PageDown - decrease objects z-pos by 50"
     189msgstr "Shift Bild runter - Objekt nach unten"
     190
     191#: src/editor/editor_help_screen.cxx:74
     192msgid "Enter - Set default zoom (1:1)"
     193msgstr "Eingabe - Setze Standard Zoom (1:1)"
     194
     195#: src/editor/editor_help_screen.cxx:75
     196msgid "d - duplicate object"
     197msgstr "d - Objekt kopieren"
     198
     199#: src/editor/editor_help_screen.cxx:76
     200msgid "a - mark all objects"
     201msgstr "a - Alle Objekte markieren"
     202
     203#: src/editor/editor_help_screen.cxx:77
     204msgid "shift leftmouseclick - add object to selection"
     205msgstr "Shift + linke Maustaste - Objekt zur Auswahl tun"
     206
     207#: src/editor/editor_help_screen.cxx:78
     208msgid "leftmouseclick - select object"
     209msgstr "linke Maustaste - Objekt auswählen"
     210
     211#: src/editor/editor_help_screen.cxx:79
     212msgid "Insert - insert new object"
     213msgstr "Einfügen - neues Objekt einfügen"
     214
     215#: src/editor/editor_help_screen.cxx:80
     216msgid "Remove - remove selected object"
     217msgstr "Entfernen - entferne ausgewähltes Objekt"
     218
     219#: src/editor/editor_help_screen.cxx:81
     220msgid "g - ungroup/group current selection"
     221msgstr "g - Auswahl gruppieren / Gruppierung aufheben"
     222
     223#: src/editor/editor_help_screen.cxx:82
     224msgid "Ctrl PageUp   - increase objects z-pos by 1"
     225msgstr "Strg Bild rauf - z-pos des Objekts um 1 erhöhen"
     226
     227#: src/editor/editor_help_screen.cxx:83
     228msgid "Ctrl PageDown - decrease objects z-pos by 1"
     229msgstr "Strg Bild runter - z-pos des Objekts um 1 senken"
     230
     231#: src/editor/editor_help_screen.cxx:89
     232msgid "Naming Convention: <LEVELNAME><NUMBER>-<CREATOR>.plf"
     233msgstr "Dateinamensvorgabe: <LEVELNAME><NUMMER>-<AUTOR>.pfl"
     234
     235#: src/editor/editor_help_screen.cxx:91
     236msgid ""
     237"When you have created a level and want to have it in the next Pingus "
     238"release,\n"
     239"please mail it to pingus-devel@nongnu.org."
     240msgstr ""
     241"Falls Du einen Level erstellt hast und ihn gerne im nächsten Pingus\n"
     242"Release hättest, schicke ihn an pingus-devel@nongnu.org."
     243
     244#: src/editor/object_selector.cxx:106
     245msgid "1 - guillotine"
     246msgstr "1 - Guillotine"
     247
     248#: src/editor/object_selector.cxx:107
     249msgid "2 - hammer"
     250msgstr "2 - Hammer"
     251
     252#: src/editor/object_selector.cxx:108
     253msgid "3 - spike"
     254msgstr "3 - Stacheln"
     255
     256#: src/editor/object_selector.cxx:109
     257msgid "4 - laser_exit"
     258msgstr "4 - Laser Ausgang"
     259
     260#: src/editor/object_selector.cxx:110
     261msgid "5 - fake_exit"
     262msgstr "5 - Täusch Ausgang"
     263
     264#: src/editor/object_selector.cxx:111
     265msgid "6 - smasher"
     266msgstr "6 - Stampfer"
     267
     268#: src/editor/object_selector.cxx:112
     269msgid "7 - bumper"
     270msgstr "7 - Stosser"
     271
     272#: src/editor/object_selector.cxx:186
     273msgid "Select a WorldObj"
     274msgstr "Wähle ein WeltObjekt"
     275
     276#: src/editor/object_selector.cxx:187
     277msgid "1 - teleporter"
     278msgstr "1 - Teleporter"
     279
     280#: src/editor/object_selector.cxx:188
     281msgid "2 - switch and door"
     282msgstr "2 - Schalter und Tür"
     283
     284#: src/editor/object_selector.cxx:189
     285msgid "3 - ConveyorBelt"
     286msgstr "3 - Förderband"
     287
     288#: src/editor/object_selector.cxx:190
     289msgid "4 - IceBlock"
     290msgstr "4 - Eisblock"
     291
     292#: src/editor/object_selector.cxx:191
     293msgid "5 - InfoBox"
     294msgstr "5 - InfoBox"
     295
     296#: src/editor/object_selector.cxx:232
     297msgid "Select a weather"
     298msgstr "Wähle ein Wetter"
     299
     300#: src/editor/object_selector.cxx:233
     301msgid "1 - snow"
     302msgstr "1 - Schnee"
     303
     304#: src/editor/object_selector.cxx:234
     305msgid "2 - rain"
     306msgstr "2 - Regen"
     307
     308#: src/editor/object_selector.cxx:265
     309msgid "Select an entrance"
     310msgstr "Wähle einen Eingang"
     311
     312#: src/editor/object_selector.cxx:266
     313msgid "1 - generic"
     314msgstr "1 - allgemein"
     315
     316#: src/editor/object_selector.cxx:267
     317msgid "2 - woodthing"
     318msgstr "2 - hölzern"
     319
     320#: src/editor/object_selector.cxx:268
     321msgid "3 - cloud"
     322msgstr "3 - Wolke"
     323
     324#: src/editor/object_selector.cxx:269
     325msgid "h - entrance surface (hotspot)"
     326msgstr "h - Eingangs Grafik (hotspot)"
     327
     328#: src/editor/object_selector.cxx:343
     329msgid "What object type do you want?"
     330msgstr "Was für ein Objekt willst du?"
     331
     332#: src/editor/object_selector.cxx:344 src/editor/object_selector.cxx:400
     333msgid "h - Hotspot"
     334msgstr "h - Grafikelement (hotspot)"
     335
     336#: src/editor/object_selector.cxx:345
     337msgid "g - Groundpiece (ground) [not implemented]"
     338msgstr "g - Bodenstück (ground) [nicht implementiert]"
     339
     340#: src/editor/object_selector.cxx:394 src/editor/object_selector.cxx:562
     341msgid "Which object do you want?"
     342msgstr "Welches Objekt willst du?"
     343
     344#: src/editor/object_selector.cxx:395
     345msgid "g - Groundpiece (ground)"
     346msgstr "g - Bodenstück (ground)"
     347
     348#: src/editor/object_selector.cxx:396
     349msgid "s - Groundpiece (solid)"
     350msgstr "s - Bodenelement (Stahl)"
     351
     352#: src/editor/object_selector.cxx:397
     353msgid "b - Groundpiece (bridge)"
     354msgstr "b - Bodenelement (Bruecke)"
     355
     356#: src/editor/object_selector.cxx:398
     357msgid "n - Groundpiece (transparent)"
     358msgstr "n - Bodenelement (transparent)"
     359
     360#: src/editor/object_selector.cxx:399
     361msgid "r - Groundpiece (remove)"
     362msgstr "r - Bodenelement (entfernen)"
     363
     364#: src/editor/object_selector.cxx:401
     365msgid "e - Entrance"
     366msgstr "e - Eingang"
     367
     368#: src/editor/object_selector.cxx:402
     369msgid "x - Exit"
     370msgstr "x - Ausgang"
     371
     372#: src/editor/object_selector.cxx:403
     373msgid "l - Liquid"
     374msgstr "l - Flüssigkeit"
     375
     376#: src/editor/object_selector.cxx:404
     377msgid "w - Weather"
     378msgstr "w - Wetter"
     379
     380#: src/editor/object_selector.cxx:405
     381msgid "t - Traps"
     382msgstr "t - Falle"
     383
     384#: src/editor/object_selector.cxx:406
     385msgid "o - WorldObject"
     386msgstr "o - WeltObjekt"
     387
     388#: src/editor/object_selector.cxx:407
     389msgid "z - Background"
     390msgstr "z - Hintergrund"
     391
     392#: src/editor/object_selector.cxx:408
     393msgid "p - Prefab (ObjectGroup)"
     394msgstr "p - Prefab (Objekt Gruppe)"
     395
     396#: src/editor/object_selector.cxx:409
     397msgid "f - something from file (~/.pingus/images/)"
     398msgstr "f - etwas aus einer Datei (~/.pingus/images/)"
     399
     400#: src/editor/object_selector.cxx:498
     401msgid "Which prefab do you want?"
     402msgstr "Welche Prefab willst du?"
     403
     404#: src/editor/object_selector.cxx:563
     405msgid "1 - Surface Background"
     406msgstr "1 - Bild Hintergrund"
     407
     408#: src/editor/object_selector.cxx:564
     409msgid "2 - Solid Color Background"
     410msgstr "2 - Farb Hintergrund"
     411
     412#: src/editor/object_selector.cxx:565
     413msgid "3 - Starfield Background"
     414msgstr "3 - Sternen Hintergrund"
     415
     416#: src/editor/object_selector.cxx:566
     417msgid "4 - Thunderstorm Background"
     418msgstr "4 - Gewitter Hintergrund"
     419
     420#: src/editor/panel_icons.cxx:33
     421msgid "Load a level (F5)"
     422msgstr "Level laden (F5)"
     423
     424#: src/editor/panel_icons.cxx:46
     425msgid "Exit the editor (Escape)"
     426msgstr "Editor Beenden (Esc)"
     427
     428#: src/editor/panel_icons.cxx:58
     429msgid "Save this level (F6)"
     430msgstr "Level Speichern (F6)"
     431
     432#: src/editor/panel_icons.cxx:70
     433msgid "Delete marked objects (delete)"
     434msgstr "Markierte Objekte Löschen (Entfernen)"
     435
     436#: src/editor/panel_icons.cxx:82
     437msgid "Duplicate current object (d)"
     438msgstr "Aktuelles Object kopieren (d)"
     439
     440#: src/editor/panel_icons.cxx:94
     441msgid "Edit Level Properties"
     442msgstr "Leveleigenschaften ändern"
     443
     444#: src/editor/panel_icons.cxx:106
     445msgid "Edit Object Properties"
     446msgstr "Objekteigenschaften ändern"
     447
     448#: src/editor/panel_icons.cxx:118
     449msgid "Start the level and test it (F4)"
     450msgstr "Level starten und testen (F4)"
     451
     452#: src/editor/panel_icons.cxx:130
     453msgid "Create a new level from scratch"
     454msgstr "Neuen Level erstellen"
     455
     456#: src/editor/panel_icons.cxx:142
     457msgid "Insert an object (Insert)"
     458msgstr "Objekt einfuegen (Einfg)"
     459
     460#: src/editor/panel_icons.cxx:154
     461msgid "Zoom into a region"
     462msgstr "Einen Bereich vergrössern"
     463
     464#: src/editor/panel_icons.cxx:166
     465msgid "Zoom in"
     466msgstr "Vergroessern"
     467
     468#: src/editor/panel_icons.cxx:179
     469msgid "Zoom out"
     470msgstr "Verkleinern"
     471
     472#: src/editor/panel_icons.cxx:192
     473msgid "Setup Number of Actions"
     474msgstr "Stelle die Anzahl der Fähigkeiten ein"
     475
     476#: src/editor/panel_icons.cxx:204
     477msgid "Display Help Screen (F1)"
     478msgstr "Hilfe Anzeigen (F1)"
     479
     480#: src/exit_menu.cxx:48
     481msgid "Yes"
     482msgstr "Ja"
     483
     484#: src/exit_menu.cxx:81
     485msgid "No"
     486msgstr "Nein"
     487
     488#: src/exit_menu.cxx:114
     489msgid "Exit Pingus?"
     490msgstr "Pingus beenden?"
     491
     492#: src/fps_counter.cxx:48
     493msgid "unknown"
     494msgstr "unbekannt"
     495
     496#: src/game_time.cxx:70
     497msgid "unlimited"
     498msgstr "unbegrenzt"
     499
     500#: src/level_desc.cxx:74
     501msgid "Designed by "
     502msgstr "Erstellt von "
     503
     504#: src/level_desc.cxx:79
     505#, c-format
     506msgid "Pingus to Save: %d"
     507msgstr "Zu rettende Pingus: %d"
     508
     509#: src/level_desc.cxx:81
     510#, c-format
     511msgid "Number of Pingus: %d"
     512msgstr "Anzahl an Pingus: %d"
     513
     514#: src/level_desc.cxx:86
     515msgid "Loading..."
     516msgstr "Ladevorgang läuft..."
     517
     518#: src/level_desc.cxx:89
     519msgid "Loading finished. Press a mouse button to start the level"
     520msgstr ""
     521"Ladevorgang abgeschlossen. Drücke eine Maus Taste um den Level zu starten"
     522
     523#: src/level_result.cxx:61
     524msgid "Results:"
     525msgstr "Ergebnisse:"
     526
     527#: src/level_result.cxx:67
     528#, c-format
     529msgid "Pingus saved:   %3d/%3d"
     530msgstr "Gerettete Pingus: %3d/%3d"
     531
     532#: src/level_result.cxx:72
     533#, c-format
     534msgid "Pingus died:  %3d/%3d"
     535msgstr "Tote Pingus: %3d/%3d"
     536
     537#: src/level_result.cxx:88
     538msgid "Press button to continue..."
     539msgstr "Knopf drücken um fortzufahren"
     540
     541#: src/level_result.cxx:102
     542msgid ""
     543"As many Pingus escaped as entered the level. That's going to be hard to "
     544"beat.... unless this game becomes pornographic."
     545msgstr ""
     546"Es wurden alle Pingu dieses Levels gerettet. Das wird hart zu schlagen "
     547"sein... es sei denn dieses Spiel wird pornographisch."
     548
     549#: src/level_result.cxx:104
     550msgid "Very impressive indeed."
     551msgstr "In der Tat sehr eindrucksvoll."
     552
     553#: src/level_result.cxx:106
     554msgid "Good work. Still room for improvement though."
     555msgstr "Gute Arbeit. Aber Übung macht den Meiser!"
     556
     557#: src/level_result.cxx:108
     558msgid "Not too shabby, not too shabby at all."
     559msgstr "Nicht schlecht, nicht schlecht!"
     560
     561#: src/level_result.cxx:110
     562msgid ""
     563"That was OK, but Pingu life insurance premiums have just gotten more "
     564"expensive."
     565msgstr ""
     566"Das war ok, aber die Lebensversicherungsprämien für Pingus sind gerade "
     567"gestiegen."
     568
     569#: src/level_result.cxx:112
     570msgid "Maybe this level calls for a different strategy."
     571msgstr "Möglicherweise verlangt dieser Level eine andere Strategie."
     572
     573#: src/level_result.cxx:114
     574msgid "Exactly half. Are you saving only the female ones?"
     575msgstr "Genau die Hälfte! Rettest du nur die Weibchen?"
     576
     577#: src/level_result.cxx:116
     578msgid "If I were a Pingu, I never would have left that entrance."
     579msgstr "Wenn ich ein Pingu wäre, hätte ich den Eingang nie verlassen."
     580
     581#: src/level_result.cxx:118
     582msgid "Maybe you would feel more at home playing Quake."
     583msgstr "Möglicherweise wäre es besser Quake zu spielen?"
     584
     585#: src/level_result.cxx:120
     586msgid ""
     587"Maybe this level calls for a different strategy. Like attempting to save "
     588"them, for example."
     589msgstr ""
     590"Es kann sein, dass wir etwas anderes versuchen sollten.  Vielleicht könnten "
     591"wir ja die Pingus retten?"
     592
     593#: src/level_result.cxx:122
     594msgid "Ever considered a career as a Pingu exterminator?"
     595msgstr "Hast du mal über eine Karriere als Pingu Zerstörer nachgedacht?"
     596
     597#: src/level_result.cxx:124
     598msgid "You missed one! What's your excuse!?"
     599msgstr "Du hast einen vergessen! Was ist deine Entschuldigung?"
     600
     601#: src/level_result.cxx:126
     602msgid "Please reassure me that you hit the Armageddon button."
     603msgstr "Bestätige mir bitte, dass das die Armageddon Taste war."
     604
     605#: src/level_result.cxx:128
     606msgid "You've got a negative save/total value, something is buggy."
     607msgstr "Ein negativer Wert? Hier liegt ein Fehler vor."
     608
     609#: src/menu_button.cxx:181
     610msgid "..:: The people who brought this game to you ::.."
     611msgstr "..:: Die Leute, die fuer dieses Spiel verantwortlich sind... ::.."
     612
     613#: src/menu_button.cxx:184
     614msgid "Credits"
     615msgstr "Mitwirkende"
     616
     617#: src/menu_button.cxx:216
     618msgid "..:: Takes you to the options menu ::.."
     619msgstr "..:: Einstellungen, Cheats und Debugging stuff ::.."
     620
     621#: src/menu_button.cxx:219
     622msgid "Options"
     623msgstr "Einstellungen"
     624
     625#: src/menu_button.cxx:252
     626msgid "..:: Bye, bye ::.."
     627msgstr "..:: Auf Wiedersehen ::.."
     628
     629#: src/menu_button.cxx:255
     630msgid "Exit"
     631msgstr "Beenden"
     632
     633#: src/menu_button.cxx:306
     634msgid "..:: Launch the level editor ::.."
     635msgstr "..:: Erstelle deinen eigenen Level ::.."
     636
     637#: src/menu_button.cxx:309
     638msgid "Create a"
     639msgstr "Bau einen"
     640
     641#: src/menu_button.cxx:310
     642msgid "Level"
     643msgstr "Level"
     644
     645#: src/menu_button.cxx:344
     646msgid "..:: Start the game ::.."
     647msgstr "..:: das Spiel starten ::.."
     648
     649#: src/menu_button.cxx:345
     650msgid "Start"
     651msgstr "Start"
     652
     653#: src/menu_button.cxx:375
     654msgid "..:: Start a contrib level ::.."
     655msgstr "..:: Contrib level Spielen ::.."
     656
     657#: src/menu_button.cxx:377
     658msgid "Contrib"
     659msgstr "Levels"
     660
     661#: src/menu_button.cxx:399
     662msgid "..:: Multiplayer Modes... experimental stuff ::.."
     663msgstr "..:: Mehrspieler Modus ::.. Experimentelles Zeug ::.."
     664
     665#: src/menu_button.cxx:401
     666msgid "Multi"
     667msgstr "Multi"
     668
     669#: src/pingu_enums.cxx:35
     670msgid "Angel"
     671msgstr "Angel"
     672
     673#: src/pingu_enums.cxx:36
     674msgid "Basher"
     675msgstr "Basher"
     676
     677#: src/pingu_enums.cxx:37
     678msgid "Blocker"
     679msgstr "Blocker"
     680
     681#: src/pingu_enums.cxx:38
     682msgid "Boarder"
     683msgstr "Boarder"
     684
     685#: src/pingu_enums.cxx:39
     686msgid "Bomber"
     687msgstr "Bomber"
     688
     689#: src/pingu_enums.cxx:41
     690msgid "Climber"
     691msgstr "Climber"
     692
     693#: src/pingu_enums.cxx:42
     694msgid "Digger"
     695msgstr "Digger"
     696
     697#: src/pingu_enums.cxx:43
     698msgid "Drown"
     699msgstr "Drown"
     700
     701#: src/pingu_enums.cxx:44
     702msgid "Exiter"
     703msgstr "Exiter"
     704
     705#: src/pingu_enums.cxx:45
     706msgid "Faller"
     707msgstr "Faller"
     708
     709#: src/pingu_enums.cxx:46
     710msgid "Floater"
     711msgstr "Floater"
     712
     713#: src/pingu_enums.cxx:47
     714msgid "Jumper"
     715msgstr "Jumper"
     716
     717#: src/pingu_enums.cxx:48
     718msgid "Laserkill"
     719msgstr "Laserkill"
     720
     721#: src/pingu_enums.cxx:49
     722msgid "Miner"
     723msgstr "Miner"
     724
     725#: src/pingu_enums.cxx:50
     726msgid "Rocketlauncher"
     727msgstr "Rocketlauncher"
     728
     729#: src/pingu_enums.cxx:51
     730msgid "Slider"
     731msgstr "Slider"
     732
     733#: src/pingu_enums.cxx:52
     734msgid "Smashed"
     735msgstr "Smashed"
     736
     737#: src/pingu_enums.cxx:53
     738msgid "Splashed"
     739msgstr "Splashed"
     740
     741#: src/pingu_enums.cxx:54
     742msgid "Superman"
     743msgstr "Superman"
     744
     745#: src/pingu_enums.cxx:55
     746msgid "Teleported"
     747msgstr "Teleported"
     748
     749#: src/pingu_enums.cxx:56
     750msgid "Waiter"
     751msgstr "Waiter"
     752
     753#: src/pingu_enums.cxx:57
     754msgid "Walker"
     755msgstr "Walker"
     756
     757#: src/pingus_counter.cxx:52
     758#, c-format
     759msgid "Released:%3d/%-3d   Out:%3d   Saved:%3d/%-3d"
     760msgstr "Rein: %3d/%-3d  Raus: %3d Gerettet: %3d/%-3d"
     761
     762#: src/pingus_main.cxx:90
     763msgid "| segfault_handler: catched a SIGSEGV."
     764msgstr "| segfault_handler: SIGSEGV abgefangen."
     765
     766#: src/pingus_main.cxx:92
     767msgid "| Woops, Pingus just crashed, congratulations you've found a bug."
     768msgstr ""
     769"| Woops, Pingus ist abgestürzt. Gratuliere, du hast einen Bug gefunden."
     770
     771#: src/pingus_main.cxx:93
     772msgid ""
     773"| Please write a little bug report to <grumbel@gmx.de>, include informations"
     774msgstr ""
     775"| Bitte schreibe einen kleinen Report an <pingus-devel@nongnu.org, mit "
     776"Informationen,"
     777
     778#: src/pingus_main.cxx:94
     779msgid "| where exacly the SIGSEGV occured and how to reproduce it."
     780msgstr "| wo genau der SIGSEGV auftrat und wie man ihn reproduziert."
     781
     782#: src/pingus_main.cxx:95
     783msgid "| Also try include a backtrace, you can get it like this:"
     784msgstr "| Versuche auch einen backtrace zu erstellen, du bekommst ihn so:"
     785
     786#: src/pingus_main.cxx:101
     787msgid "| If that doesn't work, try this:"
     788msgstr "| Wenn das nicht geht, versuche dies:"
     789
     790#: src/pingus_main.cxx:105
     791msgid "| [play until it crashes again]"
     792msgstr "| [spiele bis es wieder crasht]"
     793
     794#: src/pingus_main.cxx:113
     795msgid "| Warning: Pingus recieved a SIGINT, exiting now."
     796msgstr "| Warnung: Pingus erhielt einen SIGINT, beende jetzt."
     797
     798#: src/pingus_main.cxx:301
     799msgid "Warning: Larger resolution than 800x600 will result in visual problems"
     800msgstr ""
     801"Warnung: Auflösungen grösser als 800x600 können zu visuellen Problemen führen"
     802
     803#: src/pingus_main.cxx:488
     804msgid "Unknow char: "
     805msgstr "Unbekannter Buchstabe: "
     806
     807#: src/pingus_main.cxx:489
     808msgid "Usage: "
     809msgstr "Benutzung: "
     810
     811#: src/pingus_main.cxx:489
     812msgid " [OPTIONS]... [LEVELFILE]"
     813msgstr "[OPTIONEN]... [LEVELDATEI]"
     814
     815#: src/pingus_main.cxx:492
     816msgid "Options:"
     817msgstr "Einstellungen"
     818
     819#: src/pingus_main.cxx:494
     820msgid "Set the resolution for pingus (default: 800x600)"
     821msgstr "Setze die Auflösung für Pingus (Standard: 800x600)"
     822
     823#: src/pingus_main.cxx:495
     824msgid "Displays this help"
     825msgstr "Hilfe Anzeigen"
     826
     827#: src/pingus_main.cxx:496
     828msgid "Disable intro"
     829msgstr "Intro abschalten"
     830
     831#: src/pingus_main.cxx:497
     832msgid "Use OpenGL"
     833msgstr "OpenGL benutzen"
     834
     835#: src/pingus_main.cxx:499
     836msgid "Start in Window Mode"
     837msgstr "Pingus im Fenster starten"
     838
     839#: src/pingus_main.cxx:500
     840msgid "Start in Fullscreen"
     841msgstr "Pingus im Vollbild starten"
     842
     843#: src/pingus_main.cxx:504
     844msgid "FILE      "
     845msgstr "Datei     "
     846
     847#: src/pingus_main.cxx:504
     848msgid "Load a custom level from FILE"
     849msgstr "Einen Level aus DATEI laden"
     850
     851#: src/pingus_main.cxx:505
     852msgid "FILE        "
     853msgstr "Datei      "
     854
     855#: src/pingus_main.cxx:505
     856msgid "Load a custom worldmap from FILE"
     857msgstr "Eine Weltkarte aus DATEI laden"
     858
     859#: src/pingus_main.cxx:506
     860msgid "Print some more messages to stdout, can be set"
     861msgstr "Gibt mehr Nachrichten auf stdout aus, kann"
     862
     863#: src/pingus_main.cxx:507
     864msgid "multiple times to increase verbosity"
     865msgstr "mehrmals gesetzt werden, um die Genauigkeit zu erhöhen"
     866
     867#: src/pingus_main.cxx:508
     868msgid "Prints version number and exit"
     869msgstr "Version ausgeben und beenden"
     870
     871#: src/pingus_main.cxx:509
     872msgid "Launch the Level editor (experimental)"
     873msgstr "Level Editor starten (Experimentell)"
     874
     875#: src/pingus_main.cxx:510
     876msgid "Disable automatic scrolling"
     877msgstr "Automatisches Scrollen abschalten"
     878
     879#: src/pingus_main.cxx:512
     880msgid "Enable software cursor"
     881msgstr "Aktiviere Software Cursor"
     882
     883#: src/pingus_main.cxx:515
     884msgid "Don't read ~/.pingus/config"
     885msgstr "~/.pingus/config nicht einlesen"
     886
     887#: src/pingus_main.cxx:516
     888msgid "FILE       "
     889msgstr "Datei      "
     890
     891#: src/pingus_main.cxx:516
     892msgid "Read config from FILE (default: ~/.pingus/config)"
     893msgstr "Konfiguration aus DATEI lesen"
     894
     895#: src/pingus_main.cxx:517
     896msgid "reduce CPU usage, might speed up the game on slower machines"
     897msgstr ""
     898"reduziere CPU Belastung, könnte das Spiel auf langsamen Rechnern "
     899"beschleunigen"
     900
     901#: src/pingus_main.cxx:518
     902msgid "Uses the controller given in FILE"
     903msgstr "Controller aus FILE benutzen"
     904
     905#: src/pingus_main.cxx:520
     906msgid "Debugging and experimental stuff:"
     907msgstr "Debug und Experimentelles Zeug"
     908
     909#: src/pingus_main.cxx:521
     910msgid "Enables some features, only interesting programmers"
     911msgstr "Aktiviere einige Funktionen, nur für Programmierer"
     912
     913#: src/pingus_main.cxx:522
     914msgid "Enable the output of debugging infos, possible"
     915msgstr "Aktiviere die Ausgabe von Debug Informationen, mögliche"
     916
     917#: src/pingus_main.cxx:523
     918msgid "OPTION's are tiles, gametime, actions, sound, resources, gui,"
     919msgstr "Optionen sind tiles, gametime, actions, sound, resources, gui,"
     920
     921#: src/pingus_main.cxx:525
     922msgid "Skip at least N frames, larger values speed the game up"
     923msgstr ""
     924"Überspringe mindestens N Bilder, größere Werte erhöhen die Geschwindigkeit"
     925
     926#: src/pingus_main.cxx:526
     927msgid "Skip at most N frames"
     928msgstr "Überspringe maximal N Bilder"
     929
     930#: src/pingus_main.cxx:527
     931msgid "Set both min and max frameskip to N"
     932msgstr "Setze sowohl minimalen als auch maximalen Bildsprung auf N"
     933
     934#: src/pingus_main.cxx:528
     935msgid "Set the game speed (0=fastest, >0=slower)"
     936msgstr "Setze die Geschwindigkeit (0=schnellste, >0=langsamer)"
     937
     938#: src/pingus_main.cxx:529
     939msgid "Prints the fps to stdout"
     940msgstr "Schreibe die fps auf stdout"
     941
     942#: src/pingus_main.cxx:530
     943msgid "Set the size of the map tiles (default: 32)"
     944msgstr "Setze die Größe der Kartenteile (Standard: 32)"
     945
     946#: src/pingus_main.cxx:531
     947msgid "Disable some cpu intensive features"
     948msgstr "Deaktivere einige CPU intensive Funktionen"
     949
     950#: src/pingus_main.cxx:532
     951msgid "Reduces the CPU usage by issuing sleep()"
     952msgstr "Reduziert die CPU Belastung durch Verwendung von sleep()"
     953
     954#: src/pingus_main.cxx:534
     955msgid "Demo playing and recording:"
     956msgstr "Demo aufzeichnung und wiedergabe:"
     957
     958#: src/pingus_main.cxx:535
     959msgid "FILE     "
     960msgstr "Datei    "
     961
     962#: src/pingus_main.cxx:535
     963msgid "Plays a demo session from FILE"
     964msgstr "Spielt eine Demo Sitzung aus FILE"
     965
     966#: src/pingus_main.cxx:537
     967msgid "Record demos for each played level"
     968msgstr "Nehme Demos für jeden gespielten Level auf"
     969
     970#: src/pingus_main.cxx:539
     971msgid "Sound:"
     972msgstr "Sound"
     973
     974#: src/pingus_main.cxx:540
     975msgid "Disable sound"
     976msgstr "Sound deaktivieren"
     977
     978#: src/pingus_main.cxx:541
     979msgid "Disable music"
     980msgstr "Musik deaktivieren"
     981
     982#: src/pingus_main.cxx:720
     983msgid "clanVorbis support:           ok"
     984msgstr "clanVorbis Unterstützung:    ok"
     985
     986#: src/pingus_main.cxx:722
     987msgid "clanVoribs support:  missing (.ogg music files will not be playable)"
     988msgstr ""
     989"clanVorbis Unterstützung: fehlt (.ogg Musik Datein können nicht abgespielt "
     990"werden)"
     991
     992#: src/pingus_main.cxx:726
     993msgid "clanMikMod support:           ok"
     994msgstr "clanMikMod Unterstützung:    ok"
     995
     996#: src/pingus_main.cxx:728
     997msgid "clanMikMod support:  missing (music files will not be playable)"
     998msgstr ""
     999"clanMikMod Untersützung: fehlt (Musikdateien können nicht abgespielt werden)"
     1000
     1001#: src/pingus_main.cxx:732
     1002msgid "getext support:               ok"
     1003msgstr "gettext Unterstützung:       ok"
     1004
     1005#: src/pingus_main.cxx:733
     1006msgid "gettext language:        english"
     1007msgstr "gettext Sprache:        deutsch"
     1008
     1009#: src/pingus_main.cxx:739
     1010msgid "sound support:           enabled"
     1011msgstr "Sound Unterstützung:         an"
     1012
     1013#: src/pingus_main.cxx:741
     1014msgid "sound support:          disabled"
     1015msgstr "Sound Unterstützung:        aus"
     1016
     1017#: src/pingus_main.cxx:744
     1018msgid "music support:           enabled"
     1019msgstr "Musik Unterstützung:         an"
     1020
     1021#: src/pingus_main.cxx:746
     1022msgid "music support:          disabled"
     1023msgstr "Musik Unterstützung:        aus"
     1024
     1025#: src/pingus_main.cxx:748
     1026msgid "resolution set to:       "
     1027msgstr "Auflösung:              "
     1028
     1029#: src/pingus_main.cxx:749
     1030msgid "fullscreen:              "
     1031msgstr "Vollbild:           "
     1032
     1033#: src/pingus_main.cxx:750
     1034msgid " enabled"
     1035msgstr "aktiviert"
     1036
     1037#: src/pingus_main.cxx:750
     1038msgid "disabled"
     1039msgstr "deaktiviert"
     1040
  • libraries/source/tinygettext/test/helloworld/de.po

     
     1# SOME DESCRIPTIVE TITLE.
     2# Copyright (C) YEAR Free Software Foundation, Inc.
     3# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
     4#
     5#, fuzzy
     6msgid ""
     7msgstr ""
     8"Project-Id-Version: PACKAGE VERSION\n"
     9"Report-Msgid-Bugs-To: \n"
     10"POT-Creation-Date: 2009-01-30 08:01+0100\n"
     11"PO-Revision-Date: 2009-01-30 08:39+0100\n"
     12"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     13"Language-Team: LANGUAGE <LL@li.org>\n"
     14"MIME-Version: 1.0\n"
     15"Content-Type: text/plain; charset=UTF-8\n"
     16"Content-Transfer-Encoding: 8bit\n"
     17
     18#: helloworld.cpp:7
     19msgid "Short Hello World"
     20msgstr "kurzes Hallo Welt"
     21
     22#: helloworld.cpp:8 helloworld.cpp:14
     23#, fuzzy
     24msgid "Hello World"
     25msgid_plural "Hello Worlds"
     26msgstr[0] "Hallo Welt (singular)"
     27msgstr[1] "Hallo Welt (plural)"
     28
     29#: helloworld.cpp:10 helloworld.cpp:16
     30#, fuzzy
     31msgctxt ""
     32msgid "Hello World"
     33msgid_plural "Hello Worlds"
     34msgstr[0] "Hallo Welt (singular) mit leerem Kontext"
     35msgstr[1] "Hallo Welt (plural) mit leerem Kontext"
     36
     37#: helloworld.cpp:11 helloworld.cpp:17
     38msgctxt "console"
     39msgid "Hello World"
     40msgid_plural "Hello Worlds"
     41msgstr[0] "Hallo Welt (singular) in der Console"
     42msgstr[1] "Hallo Welt (plural) in der Console"
     43
     44#: helloworld.cpp:13
     45msgid "gui"
     46msgid_plural "Hello World"
     47msgstr[0] "Hallo Welt (singular)"
     48msgstr[1] "Hallo Welt (plural)"
     49
     50#: helloworld.cpp:18
     51#, fuzzy
     52msgctxt "gui"
     53msgid "Hello World"
     54msgid_plural "Hello Worlds"
     55msgstr[0] "Hallo Welt im GUI"
     56msgstr[1] "Hallo Welt (plural) im GUI"
  • libraries/source/tinygettext/test/helloworld/helloworld.pot

     
     1# SOME DESCRIPTIVE TITLE.
     2# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
     3# This file is distributed under the same license as the PACKAGE package.
     4# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
     5#
     6#, fuzzy
     7msgid ""
     8msgstr ""
     9"Project-Id-Version: PACKAGE VERSION\n"
     10"Report-Msgid-Bugs-To: \n"
     11"POT-Creation-Date: 2009-01-30 08:10+0100\n"
     12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
     13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     14"Language-Team: LANGUAGE <LL@li.org>\n"
     15"MIME-Version: 1.0\n"
     16"Content-Type: text/plain; charset=CHARSET\n"
     17"Content-Transfer-Encoding: 8bit\n"
     18"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
     19
     20#: helloworld.cpp:7
     21msgid "Short Hello World"
     22msgstr ""
     23
     24#: helloworld.cpp:8 helloworld.cpp:14
     25msgid "Hello World"
     26msgid_plural "Hello Worlds"
     27msgstr[0] ""
     28msgstr[1] ""
     29
     30#: helloworld.cpp:10 helloworld.cpp:16
     31msgctxt ""
     32msgid "Hello World"
     33msgid_plural "Hello Worlds"
     34msgstr[0] ""
     35msgstr[1] ""
     36
     37#: helloworld.cpp:11 helloworld.cpp:17
     38msgctxt "console"
     39msgid "Hello World"
     40msgid_plural "Hello Worlds"
     41msgstr[0] ""
     42msgstr[1] ""
     43
     44#: helloworld.cpp:13
     45msgid "gui"
     46msgid_plural "Hello World"
     47msgstr[0] ""
     48msgstr[1] ""
     49
     50#: helloworld.cpp:18
     51msgctxt "gui"
     52msgid "Hello World"
     53msgid_plural "Hello Worlds"
     54msgstr[0] ""
     55msgstr[1] ""
  • libraries/source/tinygettext/test/helloworld.cpp

     
     1#include <iostream>
     2
     3#define _(x) gettext(x)
     4
     5int main()
     6{
     7  std::cout << _("Short Hello World") << std::endl;
     8  std::cout << gettext("Hello World") << std::endl;
     9  std::cout << gettext("Hello Worlds") << std::endl;
     10
     11  std::cout << pgettext("", "Hello World") << std::endl;
     12  std::cout << pgettext("console", "Hello World") << std::endl;
     13
     14  std::cout << ngettext("gui", "Hello World") << std::endl;
     15  std::cout << ngettext("Hello World", "Hello Worlds", 5) << std::endl;
     16
     17  std::cout << npgettext("", "Hello World", "Hello Worlds", 5) << std::endl;
     18  std::cout << npgettext("console", "Hello World", "Hello Worlds", 5) << std::endl;
     19  std::cout << npgettext("gui", "Hello World", "Hello Worlds", 5) << std::endl;
     20
     21  return 0;
     22}
     23
     24/* EOF */
  • libraries/source/tinygettext/test/level/de.po

     
     1# SOME DESCRIPTIVE TITLE.
     2# Copyright (C) YEAR Free Software Foundation, Inc.
     3# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
     4#
     5#, fuzzy
     6msgid ""
     7msgstr ""
     8"Project-Id-Version: PACKAGE VERSION\n"
     9"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
     10"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     11"Language-Team: LANGUAGE <LL@li.org>\n"
     12"MIME-Version: 1.0\n"
     13"Content-Type: text/plain; charset=CHARSET\n"
     14"Content-Transfer-Encoding: 8bit\n"
     15
     16#: src/pingus_main.cxx:760
     17msgid "PingusMain: Starting Main: "
     18msgstr "PingusMain: Hauptteil wird gestartet: "
     19
     20#: src/pingus_main.cxx:805
     21msgid "PingusMain: Levelfile not found, ignoring: "
     22msgstr "PingusMain: Leveldatei nicht gefunden, Fehler wird ignoriert: "
     23
     24#: src/pingus_main.cxx:909
     25msgid "Error caught from ClanLib: "
     26msgstr "ClanLib Fehler abgefangen: "
     27
     28#: src/pingus_main.cxx:913
     29msgid "Error caught from Pingus: "
     30msgstr "Pingus Fehler wurde abgefangen: "
     31
     32#: src/pingus_main.cxx:917
     33msgid "Pingus: Out of memory!"
     34msgstr "Pingus: Speicher ist ausgegangen"
     35
     36#: src/pingus_main.cxx:921
     37msgid "Pingus: Standard exception caught!:\n"
     38msgstr "Pingus: Standard Ausnahme abgefangen!:\n"
     39
     40#: src/pingus_main.cxx:925
     41msgid "Pingus: Unknown throw caught!"
     42msgstr "Pingus: Unbekannte Ausnahme abgefangen!"
     43
     44#: src/result_screen.cxx:99 src/start_screen.cxx:111
     45msgid "Abort"
     46msgstr "Abbruch"
     47
     48#: src/result_screen.cxx:167
     49msgid "Retry"
     50msgstr "Versuche erneut"
     51
     52#: src/result_screen.cxx:175
     53msgid "Success!"
     54msgstr "Erfolg!"
     55
     56#: src/result_screen.cxx:182
     57msgid "Failure!"
     58msgstr "Fehler!"
     59
     60#: src/result_screen.cxx:191
     61msgid "Perfect! You saved everyone possible - great!"
     62msgstr "Perfekt! Du hast alle gerettet!"
     63
     64#: src/result_screen.cxx:193
     65msgid "No-one got killed, pretty good work."
     66msgstr "Keiner wurde getötet, sehr gute Arbeit."
     67
     68#: src/result_screen.cxx:195
     69msgid ""
     70"You saved exactly what you needed - you made it, but\n"
     71"maybe you can do better?"
     72msgstr ""
     73"Du hast so viele gerettet wie nötig. Du hast es\n"
     74"geschafft, aber vielleicht kannst Du es noch besser?"
     75
     76#: src/result_screen.cxx:198
     77msgid "Not everybody was saved, but still good work!"
     78msgstr "Nicht alle wurden gerettet, aber trotzdem noch gute Arbeit!"
     79
     80#: src/result_screen.cxx:200
     81msgid "What can I say, you made it - congratulations!"
     82msgstr "Was soll ich sagen, Du hast es geschafft. Gratuliere!"
     83
     84#: src/result_screen.cxx:205
     85msgid "You killed everybody, not good."
     86msgstr "Du hast alle getötet, nicht gut."
     87
     88#: src/result_screen.cxx:207
     89msgid "No-one got saved - I know you can do better."
     90msgstr "Keiner wurde gerettet, ich weiß, dass du es besser kannst."
     91
     92#: src/result_screen.cxx:209
     93msgid ""
     94"You didn't save enough, but you saved a few.  Next\n"
     95"time you might do better."
     96msgstr ""
     97"Du hast nicht genug gerettet, aber immerhin ein paar.\n"
     98"Nächstes Mal machst du es bestimmt besser."
     99
     100#: src/result_screen.cxx:212
     101msgid "Only one more and you would have made it - try again!"
     102msgstr "Einer mehr und du hast es, versuch es nochmal!"
     103
     104#: src/result_screen.cxx:214
     105msgid "Only a handful more and you would have made it - try again!"
     106msgstr "Nur ein paar mehr und du hättest es, versuch es nochmal!"
     107
     108#: src/result_screen.cxx:216
     109msgid "Better luck next time!"
     110msgstr "Mehr Glück fürs nächste Mal!"
     111
     112#: src/result_screen.cxx:232
     113msgid "Saved: "
     114msgstr "Gerettet: "
     115
     116#: src/result_screen.cxx:236
     117msgid "Died: "
     118msgstr "Getötet: "
     119
     120#: src/result_screen.cxx:240
     121msgid "Time left: "
     122msgstr "Verbliebene Zeit: "
     123
     124#: src/screenshot.cxx:45
     125msgid "Screenshot: Saving screenshot to: "
     126msgstr "Screenshot: Speichere Screenshot als: "
     127
     128#: src/screenshot.cxx:47
     129msgid "Screenshot: Screenshot is done."
     130msgstr "Screenshot: Screenshot wurde erstellt."
     131
     132#: src/screenshot.cxx:53
     133msgid "Screenshot: Couldn't save screenshot"
     134msgstr "Screenshot: Screenshot konnte nicht gespeichert werden"
     135
     136#: src/screenshot.cxx:138
     137msgid "Screenshot: Couldn't write file: "
     138msgstr "Screenshot: Datei konnte nicht geschrieben werden: "
     139
     140#: src/spot_map.cxx:286
     141#, c-format
     142msgid "Image has wrong color depth: %d"
     143msgstr "Bild hat falsche Farbtiefe: %d"
     144
     145#: src/start_screen.cxx:75
     146msgid "Ok"
     147msgstr "Ok"
     148
     149#: src/start_screen.cxx:158
     150msgid "Number of Pingus: "
     151msgstr "Anzahl an Pingus: "
     152
     153#: src/start_screen.cxx:161
     154msgid "Number to Save: "
     155msgstr "Zu rettende Pingus: "
     156
     157#: src/start_screen.cxx:164
     158msgid "Time: "
     159msgstr "Zeit: "
     160
     161#: src/start_screen.cxx:167
     162msgid "Difficulty:"
     163msgstr "Schwierigkeitsgrad:"
     164
     165#: src/start_screen.cxx:175
     166msgid "Author: "
     167msgstr "Autor: "
     168
     169#: src/start_screen.cxx:178
     170msgid "Filename: "
     171msgstr "Dateiname: "
     172
     173#: src/story.cxx:41
     174msgid "The Journey Continues"
     175msgstr "Die Reise geht weiter"
     176
     177#: src/story.cxx:46
     178msgid ""
     179"Now after you and the Pingus have learned the basics and\n"
     180"practiced a bit it is time to move on and begin the journey into\n"
     181"the world. Since the ice floe with which the Pingus traveled to the\n"
     182"Tutorial Island isn't going to hold on the whole way into the warmer\n"
     183"climates the Pingus have to find something else to guide\n"
     184"them on their journey.\n"
     185msgstr ""
     186"Nachdem Du und die Pingus nun die Grundlagen gelernt und\n"
     187"ein wenig Übung haben, ist es an der Zeit, weiter zu gehen und die\n"
     188"Reise in die Welt zu beginnen. Da die Scholle, mit der die Pingus zum\n"
     189"Tutorial Island reisten, nicht den ganzen Weg in die wärmeren Regionen\n"
     190"halten wird, müssen die Pingus etwas anderes finden, um sie auf der\n"
     191"Reise zu begleiten.\n"
     192
     193#: src/story.cxx:58
     194msgid ""
     195"But as the eldest have said, the Tutorial Island provides not\n"
     196"only a good way to practice, but it is also the starting point into\n"
     197"the world. After some searching the Pingus discovered the meaning\n"
     198"of this, and they found the large tree at the end of the island\n"
     199"which gave them wood to construct a float.\n"
     200msgstr ""
     201"Aber wie die Weisen sagten, ist Tutorial Island nicht nur\n"
     202"eine Möglichkeit zum üben, es ist auch der erste Schritt in\n"
     203"die Welt, denn das Holz der Bäume am Ende der Insel liefert\n"
     204"gutes Material, um ein Floß zu bauen.\n"
     205
     206#: src/story.cxx:69
     207msgid ""
     208"So the Pingus set out and constructed some large rafts, enough\n"
     209"to carry them all. After also packing a bunch of provisions\n"
     210"they were prepared to start their journey and leave\n"
     211"their familiar ground and enter the unknown parts of the world.\n"
     212msgstr ""
     213"So gingen die Pingus hin und bauten ein paar große\n"
     214"Flöße, genug, um alle zu tragen. Nachdem sie auch noch einigen\n"
     215"Proviant eingepackt hatten, waren sie endlich bereit, ihre Reise zu\n"
     216"beginnen, den bekannten Bereich zu verlassen und die unbekannten\n"
     217"Bereiche der Welt zu betreten.\n"
     218
     219#: src/story.cxx:79
     220msgid ""
     221"So the Pingus sit on their raft, worrying about what's to come and\n"
     222"where to go, while floating into the sunset.\n"
     223"\n"
     224"To be continued..."
     225msgstr ""
     226"So saßen die Pingus nur auf ihrem Floß und sorgten sich, was denn nun\n"
     227"kommen möge, während sie in den Sonnenuntergang trieben.\n"
     228"\n"
     229"Fortsetzung folgt..."
     230
     231#: src/story.cxx:91
     232msgid "The Journey Begins"
     233msgstr "Die Reise beginnt"
     234
     235#: src/story.cxx:96
     236msgid ""
     237"For a long time, the Pingus have lived happily in peace on the\n"
     238"South Pole along with all the other animals. Everything was in\n"
     239"balance and it seemed like nothing could disrupt their peace.  The\n"
     240"Pingus were happy and it seemed like this could never end.\n"
     241msgstr ""
     242"Die Pingus lebten schon lange glücklich und in Frieden am Südpol,\n"
     243"zusammen mit all den anderen Tieren. Alles war im Gleichgewicht und\n"
     244"es schien, als könnte nichts ihren Frieden stören. Die Pingus waren\n"
     245"glücklich und es schien, als würde dies niemals enden.\n"
     246
     247#: src/story.cxx:106
     248msgid ""
     249"But then one day, things began to change slowly: the sky got darker\n"
     250"and the earth got warmer. Firstly, they thought this was just a\n"
     251"normal fluctuation in the world's climate, but things seemed to get\n"
     252"worse and worse with every year."
     253msgstr ""
     254"Aber dann, eines Tages, veränderten sich die Dinge langsam. Der\n"
     255"Himmel wurde dunkler und die Erde wärmer. Zuerst dachten sie, dies\n"
     256"wäre nur eine normale Schwankung im Klima, aber es wurde von Jahr \n"
     257"zu Jahr immer schlimmer."
     258
     259#: src/story.cxx:117
     260msgid ""
     261"The snow began to melt away in a few areas and food became an\n"
     262"issue. Other animals tried to leave the region to search\n"
     263"for colder areas, but the Pingus knew that this wouldn't help:\n"
     264"they knew that they had to do something about it."
     265msgstr ""
     266"Der Schnee begann in einigen Bereichen zu schmelzen und Nahrung\n"
     267"wurde ein Problem. Andere Tiere begannen bereits, die Region zu\n"
     268"verlassen, um kältere Gebiete zu suchen. Aber die Pingus wussten,\n"
     269"dass dies nicht helfen würde, sie wussten, es musste etwas gegen\n"
     270"dieses Problem getan werden."
     271
     272#: src/story.cxx:127
     273msgid ""
     274"So the circle of the eldest came together to decide what to do\n"
     275"about it. They decided to send out an expedition around the world\n"
     276"to find the cause of this warming. The expedition consisted of\n"
     277"hundreds of the bravest Pingus on the South Pole."
     278msgstr ""
     279"Darum traf sich der Rat der Ältesten, um zu entscheiden, was dagegen\n"
     280"getan werden sollte. Sie entschieden, eine Expedition um die Welt\n"
     281"zu senden, um den Grund für die Erwärmung zu finden. Die Expedition\n"
     282"bestand aus hunderten der mutigsten Pingus des ganzen Südpols."
     283
     284#: src/story.cxx:137
     285msgid ""
     286"And they picked you to lead them on their journey around the\n"
     287"world. Since the journey will be dangerous and difficult, your\n"
     288"first goal is the Island of Mogorok, also known as the Tutorial\n"
     289"Island. According to the eldest, this island has always been the\n"
     290"first stop of Pingus that were sent out into the world."
     291msgstr ""
     292"Und sie wählten dich, um sie auf der Reise um die Welt zu führen.\n"
     293"Denn die Reise wird gefährlich und schwierig werden. Dein erstes Ziel ist\n"
     294"die Insel Mogorok, auch bekannt als Tutorial Island. Den Weisen\n"
     295"zufolge war diese Insel immer der erste Anlaufpunkt für Pingus,\n"
     296"die in die Welt gesandt wurden."
     297
     298#: src/story.cxx:148
     299msgid ""
     300"The island consists of many areas that are ideal to teach the\n"
     301"Pingus their abilities. The Pingus can learn to build\n"
     302"bridges, climb, bash and use many other talents which they\n"
     303"will need on their long and dangerous journey."
     304msgstr ""
     305"Die Insel besteht aus verschiedenen Regionen, die ideal sind, um die\n"
     306"Fähigkeiten der Pingus zu trainieren. Sie können dort ihre Fähig-\n"
     307"keiten im Brückenbau, klettern, graben und all die anderen Talente\n"
     308"trainieren, die sie sicher auf der langen und gefährlichen Reise\n"
     309"benötigen werden."
     310
     311#: src/story.cxx:158
     312msgid ""
     313"While there, you can practice your abilities in commanding\n"
     314"and guiding the Pingus. You can also get familiar with\n"
     315"all the abilities the Pingus provide and learn to master them,\n"
     316"since you will need all of them on your journey around the\n"
     317"world."
     318msgstr ""
     319"Währenddessen kannst Du auf der anderen Seite deine Fähigkeit, die\n"
     320"Pingus zu leiten und zu führen, trainieren. Du kannst dich dort auch mit\n"
     321"allen Fähigkeiten vertraut machen, die die Pingus besitzen und\n"
     322"erlernen, sie zu meistern, denn du wirst sie sicher alle auf der\n"
     323"Reise um die Welt benötigen."
     324
     325#: src/story.cxx:169
     326msgid ""
     327"Now that you and the Pingus have arrived at Tutorial Island it\n"
     328"is time to take command and begin your mission.\n"
     329"\n"
     330"Good Luck!"
     331msgstr ""
     332"Nun da du und die Pingus im Tutorial Island angekommen sind,\n"
     333"musst du das Kommando übernehmen und deine Mission beginnen.\n"
     334"\n"
     335"Viel Glück!"
     336
     337#: src/system.cxx:273
     338msgid "Environment variable $HOME not set, fix that and start again."
     339msgstr ""
     340"Umgebungs Variable $HOME ist nicht gesetzt. Setze sie und starte erneut."
     341
     342#: src/worldmap/level_dot.cxx:174 src/worldmap/level_dot.cxx:184
     343msgid "locked"
     344msgstr "gesperrt"
     345
     346#: src/worldmap/manager.cxx:103
     347msgid "Show Ending?"
     348msgstr "Ende anzeigen?"
     349
     350#: src/worldmap/manager.cxx:133
     351msgid "Show Story?"
     352msgstr "Story zeigen?"
     353
     354#: src/worldmap/manager.cxx:161
     355msgid "Leave?"
     356msgstr "Verlassen?"
     357
     358#: src/worldmap/manager.cxx:201
     359msgid "Enter?"
     360msgstr "Betreten?"
     361
     362#: src/worldmap/worldmap.cxx:77
     363msgid "WorldMap: File not found: "
     364msgstr "Worldmap: Datei nicht gefunden: "
     365
     366#: src/worldmap/worldmap.cxx:261
     367msgid "...walking..."
     368msgstr "...laufe..."
     369
     370msgid "You got %d error.\n"
     371msgid_plural "You got %d error.\n"
     372msgstr[0] "Du hast %d fehler\n"
     373msgstr[1] "Du hast %d fehlers\n"
     374
     375msgid "found %d fatal error"
     376msgid_plural "found %d fatal errors"
     377msgstr[0] "s'ha trobat %d error fatal"
     378msgstr[1] "s'han trobat %d errors fatals"
     379
  • libraries/source/tinygettext/test/po/de.po

     
     1# SOME DESCRIPTIVE TITLE.
     2# Copyright (C) YEAR Free Software Foundation, Inc.
     3# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
     4#
     5msgid ""
     6msgstr ""
     7"Project-Id-Version: Pingus 0.6.0\n"
     8"Report-Msgid-Bugs-To: \n"
     9"POT-Creation-Date: 2004-04-09 18:37+0000\n"
     10"PO-Revision-Date: 2009-02-01 17:44+0100\n"
     11"Last-Translator: David Philippi <david@torangan.de>\n"
     12"Language-Team: David Philippi <david@torangan.de>, Ingo Ruhnke <grumbel@gmx.de>, Giray Devlet <giray@devlet.cc>\n"
     13"MIME-Version: 1.0\n"
     14"Plural-Forms: nplurals=2; plural=(n != 1);\n"
     15"Content-Type: text/plain; charset=UTF-8\n"
     16"Content-Transfer-Encoding: 8bit\n"
     17
     18msgid "umlaut"
     19msgstr "ÄÖÜäöüß"
     20
     21#: src/actions/bridger.cxx:48 src/actions/bridger.cxx:232
     22#: src/pingu_enums.cxx:40
     23msgid "Bridger"
     24msgstr "Bridger"
     25
     26#: src/config.cxx:73
     27msgid "Couldn't open: "
     28msgstr "Datei oder Verzeichnis konnte nicht geöffnet werden: "
     29
     30#: src/config.cxx:172
     31msgid "Unexpected char: '"
     32msgstr "Unerwartetes Zeichen: '"
     33
     34#: src/config.cxx:206
     35msgid "Unexpected char '"
     36msgstr "Unerwartetes Zeichen: '"
     37
     38#: src/credits.cxx:48
     39msgid "-Idea"
     40msgstr "-Idee"
     41
     42#: src/credits.cxx:52
     43msgid "-Maintaining"
     44msgstr "-Verwaltung"
     45
     46#: src/credits.cxx:56
     47msgid "-Programming"
     48msgstr "-Programmierung"
     49
     50#: src/credits.cxx:62
     51msgid "-Porting (Win32)"
     52msgstr "-Portierung (Win32)"
     53
     54#: src/credits.cxx:70
     55msgid "-Gfx"
     56msgstr "-Grafiken"
     57
     58#: src/credits.cxx:82
     59msgid "-Music"
     60msgstr "-Musik"
     61
     62#: src/credits.cxx:88
     63msgid "-Level Design"
     64msgstr "-Level Design"
     65
     66#: src/credits.cxx:93
     67msgid "-Story"
     68msgstr "-Geschichte"
     69
     70#: src/credits.cxx:97
     71msgid "-Translation"
     72msgstr "-Übersetzung"
     73
     74#: src/credits.cxx:112
     75msgid "-Special"
     76msgstr "-Besonderen"
     77
     78#: src/credits.cxx:113
     79msgid "-Thanks to"
     80msgstr "-Dank an"
     81
     82#: src/credits.cxx:154
     83msgid "_And a very Special Thanks"
     84msgstr "_Und einen besonderen Dank"
     85
     86#: src/credits.cxx:155
     87msgid "_to all the people who"
     88msgstr "_an alle Leute die"
     89
     90#: src/credits.cxx:156
     91msgid "_contribute to"
     92msgstr "_an Freier Software"
     93
     94#: src/credits.cxx:157
     95msgid "_Free Software!"
     96msgstr "_mitarbeiten!"
     97
     98#: src/credits.cxx:163
     99msgid "_Thank you for"
     100msgstr "_Dankeschön fürs"
     101
     102#: src/credits.cxx:164
     103msgid "_playing!"
     104msgstr "_spielen!"
     105
     106#: src/editor/editor_event.cxx:588
     107msgid "Enter filename to save as:"
     108msgstr "Datei speichern als:  "
     109
     110#: src/editor/editor_help_screen.cxx:43
     111msgid "Editor Helpscreen (hide with F1)"
     112msgstr "Editor Hilfe (ausblenden mit F1)"
     113
     114#: src/editor/editor_help_screen.cxx:51
     115msgid "F1 - show/hide this help screen"
     116msgstr "F1 - Hilfe anzeigen/verstecken"
     117
     118#: src/editor/editor_help_screen.cxx:52
     119msgid "F2 - launch level building tutorial"
     120msgstr "F2 - Starte Levelbau Tutorial"
     121
     122#: src/editor/editor_help_screen.cxx:53
     123msgid "F3 - toggle background color"
     124msgstr "F3 - Hintergrundfarbe aendern"
     125
     126#: src/editor/editor_help_screen.cxx:54
     127msgid "F4 - play/test the level"
     128msgstr "F4 - Level starten/testen"
     129
     130#: src/editor/editor_help_screen.cxx:55
     131msgid "F5 - load a level"
     132msgstr "Level Laden (F5)"
     133
     134#: src/editor/editor_help_screen.cxx:56
     135msgid "F6 - save this level"
     136msgstr "Level Speichern (F6)"
     137
     138#: src/editor/editor_help_screen.cxx:57
     139msgid "F7 - [unset]"
     140msgstr "F7 - [nicht belegt]"
     141
     142#: src/editor/editor_help_screen.cxx:58
     143msgid "F8 - quick save/backup save?!"
     144msgstr "F8 - Schnellspeichern/Backup"
     145
     146#: src/editor/editor_help_screen.cxx:59
     147msgid "F9 - change level width and height"
     148msgstr "F9 - Level Höhe und Breite ändern"
     149
     150#: src/editor/editor_help_screen.cxx:60
     151msgid "F10 - [unset]"
     152msgstr "F10 - [nicht belegt]"
     153
     154#: src/editor/editor_help_screen.cxx:61
     155msgid "F11 - toggle fps counter"
     156msgstr "F11 - fps Zähler an/aus"
     157
     158#: src/editor/editor_help_screen.cxx:62
     159msgid "F12 - make screenshot"
     160msgstr "F12 - Screenshot erstellen"
     161
     162#: src/editor/editor_help_screen.cxx:66
     163msgid "Home - increase object size"
     164msgstr "Einfg - Objekt vergrößern"
     165
     166#: src/editor/editor_help_screen.cxx:67
     167msgid "End  - decrease object size"
     168msgstr "Ende - Objekt verkleinern"
     169
     170#: src/editor/editor_help_screen.cxx:68
     171msgid "Cursor Keys - Move object"
     172msgstr "Cursor Tasten - Objekt bewegen"
     173
     174#: src/editor/editor_help_screen.cxx:69
     175msgid "Shift 'Cursor Keys' - Move objects fast "
     176msgstr "Shift Cursor Tasten - Objekt schneller bewegen"
     177
     178#: src/editor/editor_help_screen.cxx:70
     179msgid "PageUp   - level object up"
     180msgstr "Bild rauf - Objekt nach oben"
     181
     182#: src/editor/editor_help_screen.cxx:71
     183msgid "PageDown - level object down"
     184msgstr "Bild runter - Objekt nach unten"
     185
     186#: src/editor/editor_help_screen.cxx:72
     187msgid "Shift PageUp   - increase objects z-pos by 50"
     188msgstr "Shift Bild rauf - Objekt nach oben"
     189
     190#: src/editor/editor_help_screen.cxx:73
     191msgid "Shift PageDown - decrease objects z-pos by 50"
     192msgstr "Shift Bild runter - Objekt nach unten"
     193
     194#: src/editor/editor_help_screen.cxx:74
     195msgid "Enter - Set default zoom (1:1)"
     196msgstr "Eingabe - Setze Standard Zoom (1:1)"
     197
     198#: src/editor/editor_help_screen.cxx:75
     199msgid "d - duplicate object"
     200msgstr "d - Objekt kopieren"
     201
     202#: src/editor/editor_help_screen.cxx:76
     203msgid "a - mark all objects"
     204msgstr "a - Alle Objekte markieren"
     205
     206#: src/editor/editor_help_screen.cxx:77
     207msgid "shift leftmouseclick - add object to selection"
     208msgstr "Shift + linke Maustaste - Objekt zur Auswahl tun"
     209
     210#: src/editor/editor_help_screen.cxx:78
     211msgid "leftmouseclick - select object"
     212msgstr "linke Maustaste - Objekt auswählen"
     213
     214#: src/editor/editor_help_screen.cxx:79
     215msgid "Insert - insert new object"
     216msgstr "Einfügen - neues Objekt einfügen"
     217
     218#: src/editor/editor_help_screen.cxx:80
     219msgid "Remove - remove selected object"
     220msgstr "Entfernen - entferne ausgewähltes Objekt"
     221
     222#: src/editor/editor_help_screen.cxx:81
     223msgid "g - ungroup/group current selection"
     224msgstr "g - Auswahl gruppieren / Gruppierung aufheben"
     225
     226#: src/editor/editor_help_screen.cxx:82
     227msgid "Ctrl PageUp   - increase objects z-pos by 1"
     228msgstr "Strg Bild rauf - z-pos des Objekts um 1 erhöhen"
     229
     230#: src/editor/editor_help_screen.cxx:83
     231msgid "Ctrl PageDown - decrease objects z-pos by 1"
     232msgstr "Strg Bild runter - z-pos des Objekts um 1 senken"
     233
     234#: src/editor/editor_help_screen.cxx:89
     235msgid "Naming Convention: <LEVELNAME><NUMBER>-<CREATOR>.plf"
     236msgstr "Dateinamensvorgabe: <LEVELNAME><NUMMER>-<AUTOR>.pfl"
     237
     238#: src/editor/editor_help_screen.cxx:91
     239msgid ""
     240"When you have created a level and want to have it in the next Pingus "
     241"release,\n"
     242"please mail it to pingus-devel@nongnu.org."
     243msgstr ""
     244"Falls Du einen Level erstellt hast und ihn gerne im nächsten Pingus\n"
     245"Release hättest, schicke ihn an pingus-devel@nongnu.org."
     246
     247#: src/editor/object_selector.cxx:106
     248msgid "1 - guillotine"
     249msgstr "1 - Guillotine"
     250
     251#: src/editor/object_selector.cxx:107
     252msgid "2 - hammer"
     253msgstr "2 - Hammer"
     254
     255#: src/editor/object_selector.cxx:108
     256msgid "3 - spike"
     257msgstr "3 - Stacheln"
     258
     259#: src/editor/object_selector.cxx:109
     260msgid "4 - laser_exit"
     261msgstr "4 - Laser Ausgang"
     262
     263#: src/editor/object_selector.cxx:110
     264msgid "5 - fake_exit"
     265msgstr "5 - Täusch Ausgang"
     266
     267#: src/editor/object_selector.cxx:111
     268msgid "6 - smasher"
     269msgstr "6 - Stampfer"
     270
     271#: src/editor/object_selector.cxx:112
     272msgid "7 - bumper"
     273msgstr "7 - Stosser"
     274
     275#: src/editor/object_selector.cxx:186
     276msgid "Select a WorldObj"
     277msgstr "Wähle ein WeltObjekt"
     278
     279#: src/editor/object_selector.cxx:187
     280msgid "1 - teleporter"
     281msgstr "1 - Teleporter"
     282
     283#: src/editor/object_selector.cxx:188
     284msgid "2 - switch and door"
     285msgstr "2 - Schalter und Tür"
     286
     287#: src/editor/object_selector.cxx:189
     288msgid "3 - ConveyorBelt"
     289msgstr "3 - Förderband"
     290
     291#: src/editor/object_selector.cxx:190
     292msgid "4 - IceBlock"
     293msgstr "4 - Eisblock"
     294
     295#: src/editor/object_selector.cxx:191
     296msgid "5 - InfoBox"
     297msgstr "5 - InfoBox"
     298
     299#: src/editor/object_selector.cxx:232
     300msgid "Select a weather"
     301msgstr "Wähle ein Wetter"
     302
     303#: src/editor/object_selector.cxx:233
     304msgid "1 - snow"
     305msgstr "1 - Schnee"
     306
     307#: src/editor/object_selector.cxx:234
     308msgid "2 - rain"
     309msgstr "2 - Regen"
     310
     311#: src/editor/object_selector.cxx:265
     312msgid "Select an entrance"
     313msgstr "Wähle einen Eingang"
     314
     315#: src/editor/object_selector.cxx:266
     316msgid "1 - generic"
     317msgstr "1 - allgemein"
     318
     319#: src/editor/object_selector.cxx:267
     320msgid "2 - woodthing"
     321msgstr "2 - hölzern"
     322
     323#: src/editor/object_selector.cxx:268
     324msgid "3 - cloud"
     325msgstr "3 - Wolke"
     326
     327#: src/editor/object_selector.cxx:269
     328msgid "h - entrance surface (hotspot)"
     329msgstr "h - Eingangs Grafik (hotspot)"
     330
     331#: src/editor/object_selector.cxx:343
     332msgid "What object type do you want?"
     333msgstr "Was für ein Objekt willst du?"
     334
     335#: src/editor/object_selector.cxx:344 src/editor/object_selector.cxx:400
     336msgid "h - Hotspot"
     337msgstr "h - Grafikelement (hotspot)"
     338
     339#: src/editor/object_selector.cxx:345
     340msgid "g - Groundpiece (ground) [not implemented]"
     341msgstr "g - Bodenstück (ground) [nicht implementiert]"
     342
     343#: src/editor/object_selector.cxx:394 src/editor/object_selector.cxx:562
     344msgid "Which object do you want?"
     345msgstr "Welches Objekt willst du?"
     346
     347#: src/editor/object_selector.cxx:395
     348msgid "g - Groundpiece (ground)"
     349msgstr "g - Bodenstück (ground)"
     350
     351#: src/editor/object_selector.cxx:396
     352msgid "s - Groundpiece (solid)"
     353msgstr "s - Bodenelement (Stahl)"
     354
     355#: src/editor/object_selector.cxx:397
     356msgid "b - Groundpiece (bridge)"
     357msgstr "b - Bodenelement (Bruecke)"
     358
     359#: src/editor/object_selector.cxx:398
     360msgid "n - Groundpiece (transparent)"
     361msgstr "n - Bodenelement (transparent)"
     362
     363#: src/editor/object_selector.cxx:399
     364msgid "r - Groundpiece (remove)"
     365msgstr "r - Bodenelement (entfernen)"
     366
     367#: src/editor/object_selector.cxx:401
     368msgid "e - Entrance"
     369msgstr "e - Eingang"
     370
     371#: src/editor/object_selector.cxx:402
     372msgid "x - Exit"
     373msgstr "x - Ausgang"
     374
     375#: src/editor/object_selector.cxx:403
     376msgid "l - Liquid"
     377msgstr "l - Flüssigkeit"
     378
     379#: src/editor/object_selector.cxx:404
     380msgid "w - Weather"
     381msgstr "w - Wetter"
     382
     383#: src/editor/object_selector.cxx:405
     384msgid "t - Traps"
     385msgstr "t - Falle"
     386
     387#: src/editor/object_selector.cxx:406
     388msgid "o - WorldObject"
     389msgstr "o - WeltObjekt"
     390
     391#: src/editor/object_selector.cxx:407
     392msgid "z - Background"
     393msgstr "z - Hintergrund"
     394
     395#: src/editor/object_selector.cxx:408
     396msgid "p - Prefab (ObjectGroup)"
     397msgstr "p - Prefab (Objekt Gruppe)"
     398
     399#: src/editor/object_selector.cxx:409
     400msgid "f - something from file (~/.pingus/images/)"
     401msgstr "f - etwas aus einer Datei (~/.pingus/images/)"
     402
     403#: src/editor/object_selector.cxx:498
     404msgid "Which prefab do you want?"
     405msgstr "Welche Prefab willst du?"
     406
     407#: src/editor/object_selector.cxx:563
     408msgid "1 - Surface Background"
     409msgstr "1 - Bild Hintergrund"
     410
     411#: src/editor/object_selector.cxx:564
     412msgid "2 - Solid Color Background"
     413msgstr "2 - Farb Hintergrund"
     414
     415#: src/editor/object_selector.cxx:565
     416msgid "3 - Starfield Background"
     417msgstr "3 - Sternen Hintergrund"
     418
     419#: src/editor/object_selector.cxx:566
     420msgid "4 - Thunderstorm Background"
     421msgstr "4 - Gewitter Hintergrund"
     422
     423#: src/editor/panel_icons.cxx:33
     424msgid "Load a level (F5)"
     425msgstr "Level laden (F5)"
     426
     427#: src/editor/panel_icons.cxx:46
     428msgid "Exit the editor (Escape)"
     429msgstr "Editor Beenden (Esc)"
     430
     431#: src/editor/panel_icons.cxx:58
     432msgid "Save this level (F6)"
     433msgstr "Level Speichern (F6)"
     434
     435#: src/editor/panel_icons.cxx:70
     436msgid "Delete marked objects (delete)"
     437msgstr "Markierte Objekte Löschen (Entfernen)"
     438
     439#: src/editor/panel_icons.cxx:82
     440msgid "Duplicate current object (d)"
     441msgstr "Aktuelles Object kopieren (d)"
     442
     443#: src/editor/panel_icons.cxx:94
     444msgid "Edit Level Properties"
     445msgstr "Leveleigenschaften ändern"
     446
     447#: src/editor/panel_icons.cxx:106
     448msgid "Edit Object Properties"
     449msgstr "Objekteigenschaften ändern"
     450
     451#: src/editor/panel_icons.cxx:118
     452msgid "Start the level and test it (F4)"
     453msgstr "Level starten und testen (F4)"
     454
     455#: src/editor/panel_icons.cxx:130
     456msgid "Create a new level from scratch"
     457msgstr "Neuen Level erstellen"
     458
     459#: src/editor/panel_icons.cxx:142
     460msgid "Insert an object (Insert)"
     461msgstr "Objekt einfuegen (Einfg)"
     462
     463#: src/editor/panel_icons.cxx:154
     464msgid "Zoom into a region"
     465msgstr "Einen Bereich vergrössern"
     466
     467#: src/editor/panel_icons.cxx:166
     468msgid "Zoom in"
     469msgstr "Vergroessern"
     470
     471#: src/editor/panel_icons.cxx:179
     472msgid "Zoom out"
     473msgstr "Verkleinern"
     474
     475#: src/editor/panel_icons.cxx:192
     476msgid "Setup Number of Actions"
     477msgstr "Stelle die Anzahl der Fähigkeiten ein"
     478
     479#: src/editor/panel_icons.cxx:204
     480msgid "Display Help Screen (F1)"
     481msgstr "Hilfe Anzeigen (F1)"
     482
     483#: src/exit_menu.cxx:48
     484msgid "Yes"
     485msgstr "Ja"
     486
     487#: src/exit_menu.cxx:81
     488msgid "No"
     489msgstr "Nein"
     490
     491#: src/exit_menu.cxx:114
     492msgid "Exit Pingus?"
     493msgstr "Pingus beenden?"
     494
     495#: src/fps_counter.cxx:48
     496msgid "unknown"
     497msgstr "unbekannt"
     498
     499#: src/game_time.cxx:70
     500msgid "unlimited"
     501msgstr "unbegrenzt"
     502
     503#: src/level_desc.cxx:74
     504msgid "Designed by "
     505msgstr "Erstellt von "
     506
     507#: src/level_desc.cxx:79
     508#, c-format
     509msgid "Pingus to Save: %d"
     510msgstr "Zu rettende Pingus: %d"
     511
     512#: src/level_desc.cxx:81
     513#, c-format
     514msgid "Number of Pingus: %d"
     515msgstr "Anzahl an Pingus: %d"
     516
     517#: src/level_desc.cxx:86
     518msgid "Loading..."
     519msgstr "Ladevorgang läuft..."
     520
     521#: src/level_desc.cxx:89
     522msgid "Loading finished. Press a mouse button to start the level"
     523msgstr ""
     524"Ladevorgang abgeschlossen. Drücke eine Maus Taste um den Level zu starten"
     525
     526#: src/level_result.cxx:61
     527msgid "Results:"
     528msgstr "Ergebnisse:"
     529
     530#: src/level_result.cxx:67
     531#, c-format
     532msgid "Pingus saved:   %3d/%3d"
     533msgstr "Gerettete Pingus: %3d/%3d"
     534
     535#: src/level_result.cxx:72
     536#, c-format
     537msgid "Pingus died:  %3d/%3d"
     538msgstr "Tote Pingus: %3d/%3d"
     539
     540#: src/level_result.cxx:88
     541msgid "Press button to continue..."
     542msgstr "Knopf drücken um fortzufahren"
     543
     544#: src/level_result.cxx:102
     545msgid ""
     546"As many Pingus escaped as entered the level. That's going to be hard to "
     547"beat.... unless this game becomes pornographic."
     548msgstr ""
     549"Es wurden alle Pingu dieses Levels gerettet. Das wird hart zu schlagen "
     550"sein... es sei denn dieses Spiel wird pornographisch."
     551
     552#: src/level_result.cxx:104
     553msgid "Very impressive indeed."
     554msgstr "In der Tat sehr eindrucksvoll."
     555
     556#: src/level_result.cxx:106
     557msgid "Good work. Still room for improvement though."
     558msgstr "Gute Arbeit. Aber Übung macht den Meiser!"
     559
     560#: src/level_result.cxx:108
     561msgid "Not too shabby, not too shabby at all."
     562msgstr "Nicht schlecht, nicht schlecht!"
     563
     564#: src/level_result.cxx:110
     565msgid ""
     566"That was OK, but Pingu life insurance premiums have just gotten more "
     567"expensive."
     568msgstr ""
     569"Das war ok, aber die Lebensversicherungsprämien für Pingus sind gerade "
     570"gestiegen."
     571
     572#: src/level_result.cxx:112
     573msgid "Maybe this level calls for a different strategy."
     574msgstr "Möglicherweise verlangt dieser Level eine andere Strategie."
     575
     576#: src/level_result.cxx:114
     577msgid "Exactly half. Are you saving only the female ones?"
     578msgstr "Genau die Hälfte! Rettest du nur die Weibchen?"
     579
     580#: src/level_result.cxx:116
     581msgid "If I were a Pingu, I never would have left that entrance."
     582msgstr "Wenn ich ein Pingu wäre, hätte ich den Eingang nie verlassen."
     583
     584#: src/level_result.cxx:118
     585msgid "Maybe you would feel more at home playing Quake."
     586msgstr "Möglicherweise wäre es besser Quake zu spielen?"
     587
     588#: src/level_result.cxx:120
     589msgid ""
     590"Maybe this level calls for a different strategy. Like attempting to save "
     591"them, for example."
     592msgstr ""
     593"Es kann sein, dass wir etwas anderes versuchen sollten.  Vielleicht könnten "
     594"wir ja die Pingus retten?"
     595
     596#: src/level_result.cxx:122
     597msgid "Ever considered a career as a Pingu exterminator?"
     598msgstr "Hast du mal über eine Karriere als Pingu Zerstörer nachgedacht?"
     599
     600#: src/level_result.cxx:124
     601msgid "You missed one! What's your excuse!?"
     602msgstr "Du hast einen vergessen! Was ist deine Entschuldigung?"
     603
     604#: src/level_result.cxx:126
     605msgid "Please reassure me that you hit the Armageddon button."
     606msgstr "Bestätige mir bitte, dass das die Armageddon Taste war."
     607
     608#: src/level_result.cxx:128
     609msgid "You've got a negative save/total value, something is buggy."
     610msgstr "Ein negativer Wert? Hier liegt ein Fehler vor."
     611
     612#: src/menu_button.cxx:181
     613msgid "..:: The people who brought this game to you ::.."
     614msgstr "..:: Die Leute, die fuer dieses Spiel verantwortlich sind... ::.."
     615
     616#: src/menu_button.cxx:184
     617msgid "Credits"
     618msgstr "Mitwirkende"
     619
     620#: src/menu_button.cxx:216
     621msgid "..:: Takes you to the options menu ::.."
     622msgstr "..:: Einstellungen, Cheats und Debugging stuff ::.."
     623
     624#: src/menu_button.cxx:219
     625msgid "Options"
     626msgstr "Einstellungen"
     627
     628#: src/menu_button.cxx:252
     629msgid "..:: Bye, bye ::.."
     630msgstr "..:: Auf Wiedersehen ::.."
     631
     632#: src/menu_button.cxx:255
     633msgid "Exit"
     634msgstr "Beenden"
     635
     636#: src/menu_button.cxx:306
     637msgid "..:: Launch the level editor ::.."
     638msgstr "..:: Erstelle deinen eigenen Level ::.."
     639
     640#: src/menu_button.cxx:309
     641msgid "Create a"
     642msgstr "Bau einen"
     643
     644#: src/menu_button.cxx:310
     645msgid "Level"
     646msgstr "Level"
     647
     648#: src/menu_button.cxx:344
     649msgid "..:: Start the game ::.."
     650msgstr "..:: das Spiel starten ::.."
     651
     652#: src/menu_button.cxx:345
     653msgid "Start"
     654msgstr "Start"
     655
     656#: src/menu_button.cxx:375
     657msgid "..:: Start a contrib level ::.."
     658msgstr "..:: Contrib level Spielen ::.."
     659
     660#: src/menu_button.cxx:377
     661msgid "Contrib"
     662msgstr "Levels"
     663
     664#: src/menu_button.cxx:399
     665msgid "..:: Multiplayer Modes... experimental stuff ::.."
     666msgstr "..:: Mehrspieler Modus ::.. Experimentelles Zeug ::.."
     667
     668#: src/menu_button.cxx:401
     669msgid "Multi"
     670msgstr "Multi"
     671
     672#: src/pingu_enums.cxx:35
     673msgid "Angel"
     674msgstr "Angel"
     675
     676#: src/pingu_enums.cxx:36
     677msgid "Basher"
     678msgstr "Basher"
     679
     680#: src/pingu_enums.cxx:37
     681msgid "Blocker"
     682msgstr "Blocker"
     683
     684#: src/pingu_enums.cxx:38
     685msgid "Boarder"
     686msgstr "Boarder"
     687
     688#: src/pingu_enums.cxx:39
     689msgid "Bomber"
     690msgstr "Bomber"
     691
     692#: src/pingu_enums.cxx:41
     693msgid "Climber"
     694msgstr "Climber"
     695
     696#: src/pingu_enums.cxx:42
     697msgid "Digger"
     698msgstr "Digger"
     699
     700#: src/pingu_enums.cxx:43
     701msgid "Drown"
     702msgstr "Drown"
     703
     704#: src/pingu_enums.cxx:44
     705msgid "Exiter"
     706msgstr "Exiter"
     707
     708#: src/pingu_enums.cxx:45
     709msgid "Faller"
     710msgstr "Faller"
     711
     712#: src/pingu_enums.cxx:46
     713msgid "Floater"
     714msgstr "Floater"
     715
     716#: src/pingu_enums.cxx:47
     717msgid "Jumper"
     718msgstr "Jumper"
     719
     720#: src/pingu_enums.cxx:48
     721msgid "Laserkill"
     722msgstr "Laserkill"
     723
     724#: src/pingu_enums.cxx:49
     725msgid "Miner"
     726msgstr "Miner"
     727
     728#: src/pingu_enums.cxx:50
     729msgid "Rocketlauncher"
     730msgstr "Rocketlauncher"
     731
     732#: src/pingu_enums.cxx:51
     733msgid "Slider"
     734msgstr "Slider"
     735
     736#: src/pingu_enums.cxx:52
     737msgid "Smashed"
     738msgstr "Smashed"
     739
     740#: src/pingu_enums.cxx:53
     741msgid "Splashed"
     742msgstr "Splashed"
     743
     744#: src/pingu_enums.cxx:54
     745msgid "Superman"
     746msgstr "Superman"
     747
     748#: src/pingu_enums.cxx:55
     749msgid "Teleported"
     750msgstr "Teleported"
     751
     752#: src/pingu_enums.cxx:56
     753msgid "Waiter"
     754msgstr "Waiter"
     755
     756#: src/pingu_enums.cxx:57
     757msgid "Walker"
     758msgstr "Walker"
     759
     760#: src/pingus_counter.cxx:52
     761#, c-format
     762msgid "Released:%3d/%-3d   Out:%3d   Saved:%3d/%-3d"
     763msgstr "Rein: %3d/%-3d  Raus: %3d Gerettet: %3d/%-3d"
     764
     765#: src/pingus_main.cxx:90
     766msgid "| segfault_handler: catched a SIGSEGV."
     767msgstr "| segfault_handler: SIGSEGV abgefangen."
     768
     769#: src/pingus_main.cxx:92
     770msgid "| Woops, Pingus just crashed, congratulations you've found a bug."
     771msgstr ""
     772"| Woops, Pingus ist abgestürzt. Gratuliere, du hast einen Bug gefunden."
     773
     774#: src/pingus_main.cxx:93
     775msgid ""
     776"| Please write a little bug report to <grumbel@gmx.de>, include informations"
     777msgstr ""
     778"| Bitte schreibe einen kleinen Report an <pingus-devel@nongnu.org, mit "
     779"Informationen,"
     780
     781#: src/pingus_main.cxx:94
     782msgid "| where exacly the SIGSEGV occured and how to reproduce it."
     783msgstr "| wo genau der SIGSEGV auftrat und wie man ihn reproduziert."
     784
     785#: src/pingus_main.cxx:95
     786msgid "| Also try include a backtrace, you can get it like this:"
     787msgstr "| Versuche auch einen backtrace zu erstellen, du bekommst ihn so:"
     788
     789#: src/pingus_main.cxx:101
     790msgid "| If that doesn't work, try this:"
     791msgstr "| Wenn das nicht geht, versuche dies:"
     792
     793#: src/pingus_main.cxx:105
     794msgid "| [play until it crashes again]"
     795msgstr "| [spiele bis es wieder crasht]"
     796
     797#: src/pingus_main.cxx:113
     798msgid "| Warning: Pingus recieved a SIGINT, exiting now."
     799msgstr "| Warnung: Pingus erhielt einen SIGINT, beende jetzt."
     800
     801#: src/pingus_main.cxx:301
     802msgid "Warning: Larger resolution than 800x600 will result in visual problems"
     803msgstr ""
     804"Warnung: Auflösungen grösser als 800x600 können zu visuellen Problemen führen"
     805
     806#: src/pingus_main.cxx:488
     807msgid "Unknow char: "
     808msgstr "Unbekannter Buchstabe: "
     809
     810#: src/pingus_main.cxx:489
     811msgid "Usage: "
     812msgstr "Benutzung: "
     813
     814#: src/pingus_main.cxx:489
     815msgid " [OPTIONS]... [LEVELFILE]"
     816msgstr "[OPTIONEN]... [LEVELDATEI]"
     817
     818#: src/pingus_main.cxx:492
     819msgid "Options:"
     820msgstr "Einstellungen"
     821
     822#: src/pingus_main.cxx:494
     823msgid "Set the resolution for pingus (default: 800x600)"
     824msgstr "Setze die Auflösung für Pingus (Standard: 800x600)"
     825
     826#: src/pingus_main.cxx:495
     827msgid "Displays this help"
     828msgstr "Hilfe Anzeigen"
     829
     830#: src/pingus_main.cxx:496
     831msgid "Disable intro"
     832msgstr "Intro abschalten"
     833
     834#: src/pingus_main.cxx:497
     835msgid "Use OpenGL"
     836msgstr "OpenGL benutzen"
     837
     838#: src/pingus_main.cxx:499
     839msgid "Start in Window Mode"
     840msgstr "Pingus im Fenster starten"
     841
     842#: src/pingus_main.cxx:500
     843msgid "Start in Fullscreen"
     844msgstr "Pingus im Vollbild starten"
     845
     846#: src/pingus_main.cxx:504
     847msgid "FILE      "
     848msgstr "Datei     "
     849
     850#: src/pingus_main.cxx:504
     851msgid "Load a custom level from FILE"
     852msgstr "Einen Level aus DATEI laden"
     853
     854#: src/pingus_main.cxx:505
     855msgid "FILE        "
     856msgstr "Datei      "
     857
     858#: src/pingus_main.cxx:505
     859msgid "Load a custom worldmap from FILE"
     860msgstr "Eine Weltkarte aus DATEI laden"
     861
     862#: src/pingus_main.cxx:506
     863msgid "Print some more messages to stdout, can be set"
     864msgstr "Gibt mehr Nachrichten auf stdout aus, kann"
     865
     866#: src/pingus_main.cxx:507
     867msgid "multiple times to increase verbosity"
     868msgstr "mehrmals gesetzt werden, um die Genauigkeit zu erhöhen"
     869
     870#: src/pingus_main.cxx:508
     871msgid "Prints version number and exit"
     872msgstr "Version ausgeben und beenden"
     873
     874#: src/pingus_main.cxx:509
     875msgid "Launch the Level editor (experimental)"
     876msgstr "Level Editor starten (Experimentell)"
     877
     878#: src/pingus_main.cxx:510
     879msgid "Disable automatic scrolling"
     880msgstr "Automatisches Scrollen abschalten"
     881
     882#: src/pingus_main.cxx:512
     883msgid "Enable software cursor"
     884msgstr "Aktiviere Software Cursor"
     885
     886#: src/pingus_main.cxx:515
     887msgid "Don't read ~/.pingus/config"
     888msgstr "~/.pingus/config nicht einlesen"
     889
     890#: src/pingus_main.cxx:516
     891msgid "FILE       "
     892msgstr "Datei      "
     893
     894#: src/pingus_main.cxx:516
     895msgid "Read config from FILE (default: ~/.pingus/config)"
     896msgstr "Konfiguration aus DATEI lesen"
     897
     898#: src/pingus_main.cxx:517
     899msgid "reduce CPU usage, might speed up the game on slower machines"
     900msgstr ""
     901"reduziere CPU Belastung, könnte das Spiel auf langsamen Rechnern "
     902"beschleunigen"
     903
     904#: src/pingus_main.cxx:518
     905msgid "Uses the controller given in FILE"
     906msgstr "Controller aus FILE benutzen"
     907
     908#: src/pingus_main.cxx:520
     909msgid "Debugging and experimental stuff:"
     910msgstr "Debug und Experimentelles Zeug"
     911
     912#: src/pingus_main.cxx:521
     913msgid "Enables some features, only interesting programmers"
     914msgstr "Aktiviere einige Funktionen, nur für Programmierer"
     915
     916#: src/pingus_main.cxx:522
     917msgid "Enable the output of debugging infos, possible"
     918msgstr "Aktiviere die Ausgabe von Debug Informationen, mögliche"
     919
     920#: src/pingus_main.cxx:523
     921msgid "OPTION's are tiles, gametime, actions, sound, resources, gui,"
     922msgstr "Optionen sind tiles, gametime, actions, sound, resources, gui,"
     923
     924#: src/pingus_main.cxx:525
     925msgid "Skip at least N frames, larger values speed the game up"
     926msgstr ""
     927"Überspringe mindestens N Bilder, größere Werte erhöhen die Geschwindigkeit"
     928
     929#: src/pingus_main.cxx:526
     930msgid "Skip at most N frames"
     931msgstr "Überspringe maximal N Bilder"
     932
     933#: src/pingus_main.cxx:527
     934msgid "Set both min and max frameskip to N"
     935msgstr "Setze sowohl minimalen als auch maximalen Bildsprung auf N"
     936
     937#: src/pingus_main.cxx:528
     938msgid "Set the game speed (0=fastest, >0=slower)"
     939msgstr "Setze die Geschwindigkeit (0=schnellste, >0=langsamer)"
     940
     941#: src/pingus_main.cxx:529
     942msgid "Prints the fps to stdout"
     943msgstr "Schreibe die fps auf stdout"
     944
     945#: src/pingus_main.cxx:530
     946msgid "Set the size of the map tiles (default: 32)"
     947msgstr "Setze die Größe der Kartenteile (Standard: 32)"
     948
     949#: src/pingus_main.cxx:531
     950msgid "Disable some cpu intensive features"
     951msgstr "Deaktivere einige CPU intensive Funktionen"
     952
     953#: src/pingus_main.cxx:532
     954msgid "Reduces the CPU usage by issuing sleep()"
     955msgstr "Reduziert die CPU Belastung durch Verwendung von sleep()"
     956
     957#: src/pingus_main.cxx:534
     958msgid "Demo playing and recording:"
     959msgstr "Demo aufzeichnung und wiedergabe:"
     960
     961#: src/pingus_main.cxx:535
     962msgid "FILE     "
     963msgstr "Datei    "
     964
     965#: src/pingus_main.cxx:535
     966msgid "Plays a demo session from FILE"
     967msgstr "Spielt eine Demo Sitzung aus FILE"
     968
     969#: src/pingus_main.cxx:537
     970msgid "Record demos for each played level"
     971msgstr "Nehme Demos für jeden gespielten Level auf"
     972
     973#: src/pingus_main.cxx:539
     974msgid "Sound:"
     975msgstr "Sound"
     976
     977#: src/pingus_main.cxx:540
     978msgid "Disable sound"
     979msgstr "Sound deaktivieren"
     980
     981#: src/pingus_main.cxx:541
     982msgid "Disable music"
     983msgstr "Musik deaktivieren"
     984
     985#: src/pingus_main.cxx:720
     986msgid "clanVorbis support:           ok"
     987msgstr "clanVorbis Unterstützung:    ok"
     988
     989#: src/pingus_main.cxx:722
     990msgid "clanVoribs support:  missing (.ogg music files will not be playable)"
     991msgstr ""
     992"clanVorbis Unterstützung: fehlt (.ogg Musik Datein können nicht abgespielt "
     993"werden)"
     994
     995#: src/pingus_main.cxx:726
     996msgid "clanMikMod support:           ok"
     997msgstr "clanMikMod Unterstützung:    ok"
     998
     999#: src/pingus_main.cxx:728
     1000msgid "clanMikMod support:  missing (music files will not be playable)"
     1001msgstr ""
     1002"clanMikMod Untersützung: fehlt (Musikdateien können nicht abgespielt werden)"
     1003
     1004#: src/pingus_main.cxx:732
     1005msgid "getext support:               ok"
     1006msgstr "gettext Unterstützung:       ok"
     1007
     1008#: src/pingus_main.cxx:733
     1009msgid "gettext language:        english"
     1010msgstr "gettext Sprache:        deutsch"
     1011
     1012#: src/pingus_main.cxx:739
     1013msgid "sound support:           enabled"
     1014msgstr "Sound Unterstützung:         an"
     1015
     1016#: src/pingus_main.cxx:741
     1017msgid "sound support:          disabled"
     1018msgstr "Sound Unterstützung:        aus"
     1019
     1020#: src/pingus_main.cxx:744
     1021msgid "music support:           enabled"
     1022msgstr "Musik Unterstützung:         an"
     1023
     1024#: src/pingus_main.cxx:746
     1025msgid "music support:          disabled"
     1026msgstr "Musik Unterstützung:        aus"
     1027
     1028#: src/pingus_main.cxx:748
     1029msgid "resolution set to:       "
     1030msgstr "Auflösung:              "
     1031
     1032#: src/pingus_main.cxx:749
     1033msgid "fullscreen:              "
     1034msgstr "Vollbild:           "
     1035
     1036#: src/pingus_main.cxx:750
     1037msgid " enabled"
     1038msgstr "aktiviert"
     1039
     1040#: src/pingus_main.cxx:750
     1041msgid "disabled"
     1042msgstr "däktiviert"
     1043
     1044
     1045#: src/pingus_main.cxx:751
     1046msgid "reenabled"
     1047msgstr ""
  • libraries/source/tinygettext/test/po/de_AT.po

     
     1# SOME DESCRIPTIVE TITLE.
     2# Copyright (C) YEAR Free Software Foundation, Inc.
     3# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
     4#
     5#, fuzzy
     6msgid ""
     7msgstr ""
     8"Project-Id-Version: PACKAGE VERSION\n"
     9"PO-Revision-Date: 2009-02-02 12:07+0100\n"
     10"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     11"Language-Team: LANGUAGE <LL@li.org>\n"
     12"MIME-Version: 1.0\n"
     13"Content-Type: text/plain; charset=UTF-8\n"
     14"Content-Transfer-Encoding: 8bit\n"
     15"Plural-Forms: nplurals=2; plural=( n != 1);\n"
     16
     17msgid "umlaut"
     18msgstr "ÄÖÜäöü߀¢"
     19
     20msgid "You got %d error."
     21msgid_plural "You got %d error."
     22msgstr[0] "Du hast %d fehler"
     23msgstr[1] "Du hast %d fehlers"
     24
     25msgid "found %d fatal error"
     26msgid_plural "found %d fatal errors"
     27msgstr[0] "s'ha trobat %d error fätal"
     28msgstr[1] "s'han trobat %d errors fätals"
     29
     30
     31msgid "I ate %d pizza."
     32msgid_plural "I ate %d pizzas."
     33msgstr[0] ""
  • libraries/source/tinygettext/test/po/fr.po

     
     1# SOME DESCRIPTIVE TITLE.
     2# Copyright (C) YEAR Free Software Foundation, Inc.
     3# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
     4#
     5#, fuzzy
     6msgid ""
     7msgstr ""
     8"Project-Id-Version: PACKAGE VERSION\n"
     9"PO-Revision-Date: 2009-01-28 08:45+0100\n"
     10"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     11"Language-Team: LANGUAGE <LL@li.org>\n"
     12"MIME-Version: 1.0\n"
     13"Content-Type: text/plain; charset=utf-8\n"
     14"Content-Transfer-Encoding: 8bit\n"
     15
     16#: src/actions/bridger.cxx:48 src/actions/bridger.cxx:232
     17#: src/pingu_enums.cxx:40
     18msgid "invalid"
     19msgstr "ungütig"
     20
  • libraries/source/tinygettext/test/po_parser_test.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include <errno.h>
     19#include <string.h>
     20#include <iostream>
     21#include <fstream>
     22#include <stdexcept>
     23
     24#include "tinygettext/po_parser.hpp"
     25#include "tinygettext/tinygettext.hpp"
     26#include "tinygettext/log.hpp"
     27
     28void my_log_callback(const std::string& err)
     29{
     30  std::cerr << err;
     31}
     32
     33int main(int argc, char** argv)
     34{
     35  if (argc < 2)
     36  {
     37    std::cout << argv[0] << " FILENAME..." << std::endl;
     38  }
     39  else
     40  {
     41    tinygettext::Log::set_log_info_callback(my_log_callback);
     42    tinygettext::Log::set_log_warning_callback(my_log_callback);
     43    tinygettext::Log::set_log_error_callback(my_log_callback);
     44
     45    for(int i = 1; i < argc; ++i)
     46    {
     47      std::ifstream in(argv[i]);
     48      if (!in)
     49      {
     50        std::cerr << argv[0] << ": cannot access " << argv[i] << ": " << strerror(errno) << std::endl;
     51      }
     52      else
     53      {
     54        try
     55        {
     56          tinygettext::Dictionary dict1;
     57          tinygettext::POParser::parse(argv[i], in, dict1);
     58
     59          //tinygettext::Dictionary dict2;
     60          //tinygettext::POFileReader::read(in, dict2);
     61        }
     62        catch(std::runtime_error& err)
     63        {
     64          std::cout << argv[i] << ": exception: " << err.what() << std::endl;
     65        }
     66      }
     67    }
     68  } 
     69}
     70
     71/* EOF */
  • libraries/source/tinygettext/test/test.sh

     
     1#!/bin/sh
     2
     3./tinygettext_test translate po/fr.po  "invalid"
     4./tinygettext_test directory po/ umlaut Deutsch
     5./tinygettext_test directory po/ umlaut deutsch
     6./tinygettext_test directory po/ umlaut de
     7
     8# EOF #
  • libraries/source/tinygettext/test/tinygettext_test.cpp

    Property changes on: libraries/source/tinygettext/test/test.sh
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
     1//  TinyGetText
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include <iostream>
     19#include <string.h>
     20#include <fstream>
     21#include <stdlib.h>
     22#include <iostream>
     23#include <stdexcept>
     24#include "tinygettext/po_parser.hpp"
     25#include "tinygettext/tinygettext.hpp"
     26
     27using namespace tinygettext;
     28
     29void print_msg(const std::string& msgid, const std::vector<std::string>& msgstrs)
     30{
     31  std::cout << "Msgid: " << msgid << std::endl;
     32  for(std::vector<std::string>::const_iterator i = msgstrs.begin(); i != msgstrs.end(); ++i)
     33    {
     34      std::cout << *i << std::endl;
     35    }
     36}
     37
     38void print_msg_ctxt(const std::string& ctxt, const std::string& msgid, const std::vector<std::string>& msgstrs)
     39{
     40  std::cout << "Msgctxt: " << ctxt << std::endl;
     41  std::cout << "Msgid: " << msgid << std::endl;
     42  for(std::vector<std::string>::const_iterator i = msgstrs.begin(); i != msgstrs.end(); ++i)
     43    {
     44      std::cout << *i << std::endl;
     45    }
     46}
     47
     48void print_usage(int /*argc*/, char** argv)
     49{
     50  std::cout << "Usage: " << argv[0] << " translate FILE MESSAGE" << std::endl;
     51  std::cout << "       " << argv[0] << " translate FILE MESSAGE_S MESSAGE_P NUM" << std::endl;
     52  std::cout << "       " << argv[0] << " directory DIRECTORY MESSAGE [LANG]" << std::endl;
     53  std::cout << "       " << argv[0] << " language LANGUAGE" << std::endl;
     54  std::cout << "       " << argv[0] << " language-dir DIR" << std::endl;
     55  std::cout << "       " << argv[0] << " list-msgstrs FILE" << std::endl;
     56}
     57
     58void read_dictionary(const std::string& filename, Dictionary& dict)
     59{
     60  std::ifstream in(filename.c_str());
     61 
     62  if (!in)
     63    {
     64      throw std::runtime_error("Couldn't open " + filename);
     65    }
     66  else
     67    {
     68      POParser::parse(filename, in, dict);
     69      in.close();
     70    }
     71}
     72
     73int main(int argc, char** argv)
     74{
     75  try
     76  {
     77    if (argc == 3 && strcmp(argv[1], "language-dir") == 0)
     78    {
     79      DictionaryManager dictionary_manager;
     80      dictionary_manager.add_directory(argv[2]);
     81      const std::set<Language>& languages = dictionary_manager.get_languages();
     82      std::cout << "Number of languages: " << languages.size() << std::endl;
     83      for (std::set<Language>::const_iterator i = languages.begin(); i != languages.end(); ++i)
     84      {
     85        const Language& language = *i;
     86        std::cout << "Env:       " << language.str()           << std::endl
     87                  << "Name:      " << language.get_name()      << std::endl
     88                  << "Language:  " << language.get_language()  << std::endl
     89                  << "Country:   " << language.get_country()   << std::endl
     90                  << "Modifier:  " << language.get_modifier()  << std::endl
     91                  << std::endl;
     92      }
     93    }
     94    else if (argc == 3 && strcmp(argv[1], "language") == 0)
     95    {
     96      Language language = Language::from_name(argv[2]);
     97
     98      if (language)
     99        std::cout << "Env:       " << language.str()           << std::endl
     100                  << "Name:      " << language.get_name()      << std::endl
     101                  << "Language:  " << language.get_language()  << std::endl
     102                  << "Country:   " << language.get_country()   << std::endl
     103                  << "Modifier:  " << language.get_modifier()  << std::endl;
     104      else
     105        std::cout << "not found" << std::endl;
     106    }
     107    else if (argc == 4 && strcmp(argv[1], "translate") == 0)
     108    {
     109      const char* filename = argv[2];
     110      const char* message  = argv[3];
     111
     112      Dictionary dict;
     113      read_dictionary(filename, dict);
     114      std::cout << "TRANSLATION: \"\"\"" << dict.translate(message) << "\"\"\""<< std::endl;
     115    }
     116    else if (argc == 5 && strcmp(argv[1], "translate") == 0)
     117    {
     118      const char* filename = argv[2];
     119      const char* context  = argv[3];
     120      const char* message  = argv[4];
     121
     122      Dictionary dict;
     123      read_dictionary(filename, dict);
     124      std::cout << dict.translate_ctxt(context, message) << std::endl;
     125    }
     126    else if (argc == 6 && strcmp(argv[1], "translate") == 0)
     127    {
     128      const char* filename = argv[2];
     129      const char* message_singular = argv[3];
     130      const char* message_plural   = argv[4];
     131      int num = atoi(argv[5]);
     132
     133      Dictionary dict;
     134      read_dictionary(filename, dict);
     135      std::cout << dict.translate_plural(message_singular, message_plural, num) << std::endl;
     136    }
     137    else if (argc == 7 && strcmp(argv[1], "translate") == 0)
     138    {
     139      const char* filename = argv[2];
     140      const char* context  = argv[3];
     141      const char* message_singular = argv[4];
     142      const char* message_plural   = argv[5];
     143      int num = atoi(argv[6]);
     144
     145      Dictionary dict;
     146      read_dictionary(filename, dict);
     147      std::cout << dict.translate_ctxt_plural(context, message_singular, message_plural, num) << std::endl;
     148    }
     149    else if ((argc == 4 || argc == 5) && strcmp(argv[1], "directory") == 0)
     150    {
     151      const char* directory = argv[2];
     152      const char* message   = argv[3];
     153      const char* language  = (argc == 5) ? argv[4] : NULL;
     154         
     155      DictionaryManager manager;
     156      manager.add_directory(directory);
     157         
     158      if (language)
     159      {
     160        Language lang = Language::from_name(language);
     161        if (lang)
     162        {
     163          manager.set_language(lang);
     164        }
     165        else
     166        {
     167          std::cout << "Unknown language: " << language << std::endl;
     168          exit(EXIT_FAILURE);
     169        }
     170      }
     171
     172      std::cout << "Directory:   '" << directory << "'"  << std::endl;
     173      std::cout << "Message:     '" << message << "'" << std::endl;
     174      std::cout << "Language:    '" << manager.get_language().str() << "' (name: '"
     175                << manager.get_language().get_name() << "', language: '"
     176                << manager.get_language().get_language() << "', country: '"
     177                << manager.get_language().get_country() << "', modifier: '"
     178                << manager.get_language().get_modifier() << "')"
     179                << std::endl;
     180      std::cout << "Translation: '" << manager.get_dictionary().translate(message) << "'" << std::endl;
     181    }
     182    else if ((argc == 3) && strcmp(argv[1], "list-msgstrs") == 0)
     183    {
     184      const char* filename = argv[2];
     185
     186      Dictionary dict;
     187      read_dictionary(filename, dict);
     188      dict.foreach(print_msg);
     189      dict.foreach_ctxt(print_msg_ctxt);
     190    }
     191    else
     192    {
     193      print_usage(argc, argv);
     194    }
     195  }
     196  catch(std::exception& err)
     197  {
     198    std::cout << "Exception: " << err.what() << std::endl;
     199  }
     200 
     201  return 0;
     202}
     203
     204/* EOF */
  • libraries/source/tinygettext/tinygettext/dictionary.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include <assert.h>
     19#include "log_stream.hpp"
     20#include "dictionary.hpp"
     21
     22namespace tinygettext {
     23
    024
     25Dictionary::Dictionary(const std::string& charset_) :
     26  entries(),
     27  ctxt_entries(),
     28  charset(charset_),
     29  plural_forms()
     30{
     31}
     32
     33Dictionary::~Dictionary()
     34{
     35}
     36
     37std::string
     38Dictionary::get_charset() const
     39{
     40  return charset;
     41}
     42
     43void
     44Dictionary::set_plural_forms(const PluralForms& plural_forms_)
     45{
     46  plural_forms = plural_forms_;
     47}
     48
     49PluralForms
     50Dictionary::get_plural_forms() const
     51{
     52  return plural_forms;
     53}
     54
     55std::string
     56Dictionary::translate_plural(const std::string& msgid, const std::string& msgid_plural, int num)
     57{
     58  return translate_plural(entries, msgid, msgid_plural, num);
     59}
     60
     61std::string
     62Dictionary::translate_plural(const Entries& dict, const std::string& msgid, const std::string& msgid_plural, int count)
     63{
     64  Entries::const_iterator i = dict.find(msgid);
     65  const std::vector<std::string>& msgstrs = i->second;
     66
     67  if (i != dict.end())
     68  {
     69    unsigned int n = 0;
     70    n = plural_forms.get_plural(count);
     71    assert(/*n >= 0 &&*/ n < msgstrs.size());
     72
     73    if (!msgstrs[n].empty())
     74      return msgstrs[n];
     75    else
     76      if (count == 1) // default to english rules
     77        return msgid;
     78      else
     79        return msgid_plural;
     80  }
     81  else
     82  {
     83    log_info << "Couldn't translate: " << msgid << std::endl;
     84    log_info << "Candidates: " << std::endl;
     85    for (i = dict.begin(); i != dict.end(); ++i)
     86      log_info << "'" << i->first << "'" << std::endl;
     87
     88    if (count == 1) // default to english rules
     89      return msgid;
     90    else
     91      return msgid_plural;
     92  }
     93}
     94
     95std::string
     96Dictionary::translate(const std::string& msgid)
     97{
     98  return translate(entries, msgid);
     99}
     100
     101std::string
     102Dictionary::translate(const Entries& dict, const std::string& msgid)
     103{
     104  Entries::const_iterator i = dict.find(msgid);
     105  if (i != dict.end() && !i->second.empty())
     106  {
     107    return i->second[0];
     108  }
     109  else
     110  {
     111    log_info << "Couldn't translate: " << msgid << std::endl;
     112    return msgid;
     113  }
     114}
     115
     116std::string
     117Dictionary::translate_ctxt(const std::string& msgctxt, const std::string& msgid)
     118{
     119  CtxtEntries::iterator i = ctxt_entries.find(msgctxt);
     120  if (i != ctxt_entries.end())
     121  {
     122    return translate(i->second, msgid);
     123  }
     124  else
     125  {
     126    log_info << "Couldn't translate: " << msgid << std::endl;
     127    return msgid;
     128  }
     129}
     130
     131std::string
     132Dictionary::translate_ctxt_plural(const std::string& msgctxt,
     133                                  const std::string& msgid, const std::string& msgidplural, int num)
     134{
     135  CtxtEntries::iterator i = ctxt_entries.find(msgctxt);
     136  if (i != ctxt_entries.end())
     137  {
     138    return translate_plural(i->second, msgid, msgidplural, num);
     139  }
     140  else
     141  {
     142    log_info << "Couldn't translate: " << msgid << std::endl;
     143    if (num != 1) // default to english
     144      return msgidplural;
     145    else
     146      return msgid;
     147  }
     148}
     149
    1150
     151void
     152Dictionary::add_translation(const std::string& msgid, const std::string& ,
     153                            const std::vector<std::string>& msgstrs)
     154{
     155  // Do we need msgid2 for anything? its after all supplied to the
     156  // translate call, so we just throw it away here
     157  entries[msgid] = msgstrs;
     158}
     159
     160void
     161Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
     162{
     163  std::vector<std::string>& vec = entries[msgid];
     164  if (vec.empty())
     165  {
     166    vec.push_back(msgstr);
     167  }
     168  else
     169  {
     170    log_warning << "collision in add_translation: '"
     171                << msgid << "' -> '" << msgstr << "' vs '" << vec[0] << "'" << std::endl;
     172    vec[0] = msgstr;
     173  }
     174}
     175
     176void
     177Dictionary::add_translation(const std::string& msgctxt,
     178                            const std::string& msgid, const std::string& msgid_plural,
     179                            const std::vector<std::string>& msgstrs)
     180{
     181  std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
     182  if (vec.empty())
     183  {
     184    vec = msgstrs;
     185  }
     186  else
     187  {
     188    log_warning << "collision in add_translation(\"" << msgctxt << "\", \"" << msgid << "\", \"" << msgid_plural << "\")" << std::endl;
     189    vec = msgstrs;
     190  }
     191}
     192
     193void
     194Dictionary::add_translation(const std::string& msgctxt, const std::string& msgid, const std::string& msgstr)
     195{
     196  std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
     197  if (vec.empty())
     198  {
     199    vec.push_back(msgstr);
     200  }
     201  else
     202  {
     203    log_warning << "collision in add_translation(\"" << msgctxt << "\", \"" << msgid << "\")" << std::endl;
     204    vec[0] = msgstr;
     205  }
     206}
     207
    2208
  • libraries/source/tinygettext/tinygettext/dictionary.hpp

    +} // namespace tinygettext
    +
    +/* EOF */
     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_DICTIONARY_HPP
     19#define HEADER_TINYGETTEXT_DICTIONARY_HPP
     20
     21#include <map>
     22#include <vector>
     23#include <string>
     24#include "plural_forms.hpp"
     25
     26namespace tinygettext {
     27
     28/** A simple dictionary class that mimics gettext() behaviour. Each
     29    Dictionary only works for a single language, for managing multiple
     30    languages and .po files at once use the DictionaryManager. */
     31class Dictionary
     32{
     33private:
     34  typedef std::map<std::string, std::vector<std::string> > Entries;
     35  Entries entries;
     36
     37  typedef std::map<std::string, Entries> CtxtEntries;
     38  CtxtEntries ctxt_entries;
     39
     40  std::string charset;
     41  PluralForms plural_forms;
     42
     43  std::string translate(const Entries& dict, const std::string& msgid);
     44  std::string translate_plural(const Entries& dict, const std::string& msgid, const std::string& msgidplural, int num);
     45
     46public:
     47  /** Constructs a dictionary converting to the specified \a charset (default UTF-8) */
     48  Dictionary(const std::string& charset = "UTF-8");
     49  ~Dictionary();
     50
     51  /** Return the charset used for this dictionary */
     52  std::string get_charset() const;
     53
     54  void set_plural_forms(const PluralForms&);
     55  PluralForms get_plural_forms() const;
     56
     57
     58  /** Translate the string \a msgid. */
     59  std::string translate(const std::string& msgid);
     60
     61  /** Translate the string \a msgid to its correct plural form, based
     62      on the number of items given by \a num. \a msgid_plural is \a msgid in
     63      plural form. */
     64  std::string translate_plural(const std::string& msgid, const std::string& msgidplural, int num);
     65
     66  /** Translate the string \a msgid that is in context \a msgctx. A
     67      context is a way to disambiguate msgids that contain the same
     68      letters, but different meaning. For example "exit" might mean to
     69      quit doing something or it might refer to a door that leads
     70      outside (i.e. 'Ausgang' vs 'Beenden' in german) */
     71  std::string translate_ctxt(const std::string& msgctxt, const std::string& msgid);
     72
     73  std::string translate_ctxt_plural(const std::string& msgctxt, const std::string& msgid, const std::string& msgidplural, int num);
     74
     75  /** Add a translation from \a msgid to \a msgstr to the dictionary,
     76      where \a msgid is the singular form of the message, msgid_plural the
     77      plural form and msgstrs a table of translations. The right
     78      translation will be calculated based on the \a num argument to
     79      translate(). */
     80  void add_translation(const std::string& msgid, const std::string& msgid_plural,
     81                       const std::vector<std::string>& msgstrs);
     82  void add_translation(const std::string& msgctxt,
     83                       const std::string& msgid, const std::string& msgid_plural,
     84                       const std::vector<std::string>& msgstrs);
     85
     86  /** Add a translation from \a msgid to \a msgstr to the
     87      dictionary */
     88  void add_translation(const std::string& msgid, const std::string& msgstr);
     89  void add_translation(const std::string& msgctxt, const std::string& msgid, const std::string& msgstr);
     90
     91  /** Iterate over all messages, Func is of type:
     92      void func(const std::string& msgid, const std::vector<std::string>& msgstrs) */
     93  template<class Func>
     94  Func foreach(Func func)
     95  {
     96    for(Entries::iterator i = entries.begin(); i != entries.end(); ++i)
     97    {
     98      func(i->first, i->second);
     99    }
     100    return func;
     101  }
     102
     103  /** Iterate over all messages with a context, Func is of type:
     104      void func(const std::string& ctxt, const std::string& msgid, const std::vector<std::string>& msgstrs) */
     105  template<class Func>
     106  Func foreach_ctxt(Func func)
     107  {
     108    for(CtxtEntries::iterator i = ctxt_entries.begin(); i != ctxt_entries.end(); ++i)
     109    {
     110      for(Entries::iterator j = i->second.begin(); j != i->second.end(); ++j)
     111      {
     112        func(i->first, j->first, j->second);
     113      }
     114    }
     115    return func;
     116  }
     117};
     118
     119} // namespace tinygettext
     120
     121#endif
     122
     123/* EOF */
  • libraries/source/tinygettext/tinygettext/dictionary_manager.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include "dictionary_manager.hpp"
     19
     20#include <memory>
     21#include <assert.h>
     22#include <stdlib.h>
     23#include <string.h>
     24#include <fstream>
     25#include <algorithm>
     26
     27#include "log_stream.hpp"
     28#include "po_parser.hpp"
     29#include "unix_file_system.hpp"
     30
     31namespace tinygettext {
     32
     33static bool has_suffix(const std::string& lhs, const std::string rhs)
     34{
     35  if (lhs.length() < rhs.length())
     36    return false;
     37  else
     38    return lhs.compare(lhs.length() - rhs.length(), rhs.length(), rhs) == 0;
     39}
     40
     41DictionaryManager::DictionaryManager(const std::string& charset_) :
     42  dictionaries(),
     43  search_path(),
     44  charset(charset_),
     45  use_fuzzy(true),
     46  current_language(),
     47  current_dict(0),
     48  empty_dict(),
     49  filesystem(new UnixFileSystem)
     50{
     51}
     52
     53DictionaryManager::~DictionaryManager()
     54{
     55  for(Dictionaries::iterator i = dictionaries.begin(); i != dictionaries.end(); ++i)
     56  {
     57    delete i->second;
     58  }
     59}
     60
     61void
     62DictionaryManager::clear_cache()
     63{
     64  for(Dictionaries::iterator i = dictionaries.begin(); i != dictionaries.end(); ++i)
     65  {
     66    delete i->second;
     67  }
     68  dictionaries.clear();
     69
     70  current_dict = 0;
     71}
     72
     73Dictionary&
     74DictionaryManager::get_dictionary()
     75{
     76  if (current_dict)
     77  {
     78    return *current_dict;
     79  }
     80  else
     81  {
     82    if (current_language)
     83    {
     84      current_dict = &get_dictionary(current_language);
     85      return *current_dict;
     86    }
     87    else
     88    {
     89      return empty_dict;
     90    }
     91  }
     92}
     93
     94Dictionary&
     95DictionaryManager::get_dictionary(const Language& language)
     96{
     97  //log_debug << "Dictionary for language \"" << spec << "\" requested" << std::endl;
     98  //log_debug << "...normalized as \"" << lang << "\"" << std::endl;
     99  assert(language);
     100
     101  Dictionaries::iterator i = dictionaries.find(language);
     102  if (i != dictionaries.end())
     103  {
     104    return *i->second;
     105  }
     106  else // Dictionary for languages lang isn't loaded, so we load it
     107  {
     108    //log_debug << "get_dictionary: " << lang << std::endl;
     109    Dictionary* dict = new Dictionary(charset);
     110
     111    dictionaries[language] = dict;
     112
     113    for (SearchPath::reverse_iterator p = search_path.rbegin(); p != search_path.rend(); ++p)
     114    {
     115      std::vector<std::string> files = filesystem->open_directory(*p);
     116
     117      std::string best_filename;
     118      int best_score = 0;
     119
     120      for(std::vector<std::string>::iterator filename = files.begin(); filename != files.end(); filename++)
     121      {
     122        // check if filename matches requested language
     123        if (has_suffix(*filename, ".po"))
     124        { // ignore anything that isn't a .po file
     125          Language po_language = Language::from_env(filename->substr(0, filename->size()-3));
     126
     127          if (!po_language)
     128          {
     129            log_warning << *filename << ": warning: ignoring, unknown language" << std::endl;
     130          }
     131          else
     132          {
     133            int score = Language::match(language, po_language);
     134                         
     135            if (score > best_score)
     136            {
     137              best_score = score;
     138              best_filename = *filename;
     139            }
     140          }
     141        }
     142      }
     143             
     144      if (!best_filename.empty())
     145      {
     146        std::string pofile = *p + "/" + best_filename;
     147        try
     148        {
     149          std::auto_ptr<std::istream> in = filesystem->open_file(pofile);
     150          if (!in.get())
     151          {
     152            log_error << "error: failure opening: " << pofile << std::endl;
     153          }
     154          else
     155          {
     156            POParser::parse(pofile, *in, *dict);
     157          }
     158        }
     159        catch(std::exception& e)
     160        {
     161          log_error << "error: failure parsing: " << pofile << std::endl;
     162          log_error << e.what() << "" << std::endl;
     163        }
     164      }
     165    }
     166
     167    return *dict;
     168  }
     169}
     170
     171std::set<Language>
     172DictionaryManager::get_languages()
     173{
     174  std::set<Language> languages;
     175
     176  for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
     177  {
     178    std::vector<std::string> files = filesystem->open_directory(*p);
     179
     180    for(std::vector<std::string>::iterator file = files.begin(); file != files.end(); ++file)
     181    {
     182      if (has_suffix(*file, ".po"))
     183      {
     184        languages.insert(Language::from_env(file->substr(0, file->size()-3)));
     185      }
     186    }
     187  }
     188  return languages;
     189}
     190
     191void
     192DictionaryManager::set_language(const Language& language)
     193{
     194  if (current_language != language)
     195  {
     196    current_language = language;
     197    current_dict     = 0;
     198  }
     199}
     200
     201Language
     202DictionaryManager::get_language() const
     203{
     204  return current_language;
     205}
     206
     207void
     208DictionaryManager::set_charset(const std::string& charset_)
     209{
     210  clear_cache(); // changing charset invalidates cache
     211  charset = charset_;
     212}
     213
     214void
     215DictionaryManager::set_use_fuzzy(bool t)
     216{
     217  clear_cache();
     218  use_fuzzy = t;
     219}
     220
     221bool
     222DictionaryManager::get_use_fuzzy() const
     223{
     224  return use_fuzzy;
     225}
     226
     227void
     228DictionaryManager::add_directory(const std::string& pathname)
     229{
     230  clear_cache(); // adding directories invalidates cache
     231  search_path.push_back(pathname);
     232}
     233
     234void
     235DictionaryManager::set_filesystem(std::auto_ptr<FileSystem> filesystem_)
     236{
     237  filesystem = filesystem_;
     238}
     239
     240} // namespace tinygettext
     241
     242/* EOF */
  • libraries/source/tinygettext/tinygettext/dictionary_manager.hpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_DICTIONARY_MANAGER_HPP
     19#define HEADER_TINYGETTEXT_DICTIONARY_MANAGER_HPP
     20
     21#include <map>
     22#include <set>
     23#include <string>
     24#include <vector>
     25#include <memory>
     26
     27#include "dictionary.hpp"
     28#include "language.hpp"
     29
     30namespace tinygettext {
     31
     32class FileSystem;
     33
     34/** Manager class for dictionaries, you give it a bunch of directories
     35    with .po files and it will then automatically load the right file
     36    on demand depending on which language was set. */
     37class DictionaryManager
     38{
     39private:
     40  typedef std::map<Language, Dictionary*> Dictionaries;
     41  Dictionaries dictionaries;
     42
     43  typedef std::vector<std::string> SearchPath;
     44  SearchPath search_path;
     45
     46  std::string charset;
     47  bool        use_fuzzy;
     48 
     49  Language    current_language;
     50  Dictionary* current_dict;
     51
     52  Dictionary  empty_dict;
     53
     54  std::auto_ptr<FileSystem> filesystem;
     55
     56  void clear_cache();
     57
     58public:
     59  DictionaryManager(const std::string& charset_ = "UTF-8");
     60  ~DictionaryManager();
     61
     62  /** Return the currently active dictionary, if none is set, an empty
     63      dictionary is returned. */
     64  Dictionary& get_dictionary();
     65
     66  /** Get dictionary for language */
     67  Dictionary& get_dictionary(const Language& language);
     68
     69  /** Set a language based on a four? letter country code */
     70  void set_language(const Language& language);
     71
     72  /** returns the (normalized) country code of the currently used language */
     73  Language get_language() const;
     74
     75  void set_use_fuzzy(bool t);
     76  bool get_use_fuzzy() const;
     77
     78  /** Set a charset that will be set on the returned dictionaries */
     79  void set_charset(const std::string& charset);
     80
     81  /** Add a directory to the search path for dictionaries, earlier
     82      added directories have higher priority then later added ones */
     83  void add_directory(const std::string& pathname);
     84
     85  /** Return a set of the available languages in their country code */
     86  std::set<Language> get_languages();
     87
     88  void set_filesystem(std::auto_ptr<FileSystem> filesystem);
     89
     90private:
     91  DictionaryManager (const DictionaryManager&);
     92  DictionaryManager& operator= (const DictionaryManager&);
     93};
     94
     95} // namespace tinygettext
     96
     97#endif
     98
     99/* EOF */
  • libraries/source/tinygettext/tinygettext/file_system.hpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_FILE_SYSTEM_HPP
     19#define HEADER_TINYGETTEXT_FILE_SYSTEM_HPP
     20
     21#include <vector>
     22#include <memory>
     23#include <iosfwd>
     24#include <string>
     25
     26namespace tinygettext {
     27
     28class FileSystem
     29{
     30public:
     31  virtual ~FileSystem() {}
     32
     33  virtual std::vector<std::string>    open_directory(const std::string& pathname) =0;
     34  virtual std::auto_ptr<std::istream> open_file(const std::string& filename)      =0;
     35};
     36
     37} // namespace tinygettext
     38
     39#endif
     40
     41/* EOF */
     42
  • libraries/source/tinygettext/tinygettext/iconv.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include <ctype.h>
     19#include <assert.h>
     20#include <sstream>
     21#include <errno.h>
     22#include <stdexcept>
     23#include <string.h>
     24#include <stdlib.h>
     25
     26#include "iconv.hpp"
     27#include "log_stream.hpp"
     28
     29namespace tinygettext {
     30
     31#ifndef tinygettext_ICONV_CONST
     32#  define tinygettext_ICONV_CONST
     33#endif
     34
     35IConv::IConv()
     36  : to_charset(),
     37    from_charset(),
     38    cd(0)
     39{}
     40 
     41IConv::IConv(const std::string& from_charset_, const std::string& to_charset_)
     42  : to_charset(),
     43    from_charset(),
     44    cd(0)
     45{
     46  set_charsets(from_charset_, to_charset_);
     47}
     48 
     49IConv::~IConv()
     50{
     51  if (cd)
     52    tinygettext_iconv_close(cd);
     53}
     54 
     55void
     56IConv::set_charsets(const std::string& from_charset_, const std::string& to_charset_)
     57{
     58  if (cd)
     59    tinygettext_iconv_close(cd);
     60
     61  from_charset = from_charset_;
     62  to_charset   = to_charset_;
     63
     64  for(std::string::iterator i = to_charset.begin(); i != to_charset.end(); ++i)
     65    *i = static_cast<char>(toupper(*i));
     66
     67  for(std::string::iterator i = from_charset.begin(); i != from_charset.end(); ++i)
     68    *i = static_cast<char>(toupper(*i));
     69
     70  if (to_charset == from_charset)
     71  {
     72    cd = 0;
     73  }
     74  else
     75  {
     76    cd = tinygettext_iconv_open(to_charset.c_str(), from_charset.c_str());
     77    if (cd == reinterpret_cast<tinygettext_iconv_t>(-1))
     78    {
     79      if(errno == EINVAL)
     80      {
     81        std::ostringstream str;
     82        str << "IConv construction failed: conversion from '" << from_charset
     83            << "' to '" << to_charset << "' not available";
     84        throw std::runtime_error(str.str());
     85      }
     86      else
     87      {
     88        std::ostringstream str;
     89        str << "IConv: construction failed: " << strerror(errno);
     90        throw std::runtime_error(str.str());
     91      }
     92    }
     93  }
     94}
     95
     96/// Convert a string from encoding to another.
     97std::string
     98IConv::convert(const std::string& text)
     99{
     100  if (!cd)
     101  {
     102    return text;
     103  }
     104  else
     105  {
     106    size_t inbytesleft  = text.size();
     107    size_t outbytesleft = 4*inbytesleft; // Worst case scenario: ASCII -> UTF-32?
     108
     109    // We try to avoid to much copying around, so we write directly into
     110    // a std::string
     111    tinygettext_ICONV_CONST char* inbuf = const_cast<char*>(&text[0]);
     112    std::string result(outbytesleft, 'X');
     113    char* outbuf = &result[0];
     114 
     115    // Try to convert the text.
     116    size_t ret = tinygettext_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
     117    if (ret == static_cast<size_t>(-1))
     118    {
     119      if (errno == EILSEQ || errno == EINVAL)
     120      { // invalid multibyte sequence
     121        tinygettext_iconv(cd, NULL, NULL, NULL, NULL); // reset state
     122
     123        // FIXME: Could try to skip the invalid byte and continue
     124        log_error << "error: tinygettext:iconv: invalid multibyte sequence in:  \"" << text << "\"" << std::endl;
     125      }
     126      else if (errno == E2BIG)
     127      { // output buffer to small
     128        assert(!"tinygettext/iconv.cpp: E2BIG: This should never be reached");
     129      }
     130      else if (errno == EBADF)
     131      {
     132        assert(!"tinygettext/iconv.cpp: EBADF: This should never be reached");
     133      }
     134      else
     135      {
     136        assert(!"tinygettext/iconv.cpp: <unknown>: This should never be reached");
     137      }
     138    }
     139
     140    result.resize(4*text.size() - outbytesleft);
     141
     142    return result;
     143  }
     144}
     145
     146} // namespace tinygettext
     147
     148/* EOF */
  • libraries/source/tinygettext/tinygettext/iconv.hpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software: you can redistribute it and/or modify
     5//  it under the terms of the GNU General Public License as published by
     6//  the Free Software Foundation, either version 3 of the License, or
     7//  (at your option) any later version.
     8// 
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13// 
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16
     17#ifndef HEADER_TINYGETTEXT_ICONV_HPP
     18#define HEADER_TINYGETTEXT_ICONV_HPP
     19
     20#include <string>
     21
     22#ifdef HAVE_SDL
     23#  include "SDL.h"
     24
     25#  define tinygettext_ICONV_CONST const
     26#  define tinygettext_iconv_t     SDL_iconv_t
     27#  define tinygettext_iconv       SDL_iconv
     28#  define tinygettext_iconv_open  SDL_iconv_open
     29#  define tinygettext_iconv_close SDL_iconv_close
     30#else
     31#  include <iconv.h>
     32
     33#  ifdef HAVE_ICONV_CONST
     34#    define tinygettext_ICONV_CONST ICONV_CONST
     35#  else
     36#    define tinygettext_ICONV_CONST
     37#  endif
     38
     39#  define tinygettext_iconv_t     iconv_t
     40#  define tinygettext_iconv       iconv
     41#  define tinygettext_iconv_open  iconv_open
     42#  define tinygettext_iconv_close iconv_close
     43#endif
     44
     45namespace tinygettext {
     46
     47class IConv
     48{
     49private:
     50  std::string to_charset;
     51  std::string from_charset;
     52  tinygettext_iconv_t cd;
     53
     54public:
     55  IConv();
     56  IConv(const std::string& fromcode, const std::string& tocode);
     57  ~IConv();
     58
     59  void set_charsets(const std::string& fromcode, const std::string& tocode);
     60  std::string convert(const std::string& text);
     61
     62private:
     63  IConv (const IConv&);
     64  IConv& operator= (const IConv&);
     65};
     66
     67} // namespace tinygettext
     68
     69#endif
     70
     71/* EOF */
  • libraries/source/tinygettext/tinygettext/language.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include "language.hpp"
     19
     20#include <map>
     21#include <assert.h>
     22#include <vector>
     23
     24namespace tinygettext {
     25
    026
     27struct LanguageSpec {
     28  /** Language code: "de", "en", ... */
     29  const char* language;
     30
     31  /** Country code: "BR", "DE", ..., can be 0 */
     32  const char* country;
     33
     34  /** Modifier/Varint: "Latn", "ije", "latin"..., can be 0 */
     35  const char* modifier;
     36
     37  /** Language name: "German", "English", "French", ... */
     38  const char* name;
     39};
     40
    141
     42/** Language Definitions */
     43//*{
     44LanguageSpec languages[] = {
     45  { "aa", 0,    0, "Afar"                        },
     46  { "af", 0,    0, "Afrikaans"                   },
     47  { "af", "ZA", 0, "Afrikaans (South Africa)"    },
     48  { "am", 0,    0, "Amharic"                     },
     49  { "ar", 0,    0, "Arabic"                      },
     50  { "ar", "AR", 0, "Arabic (Argentina)"          },
     51  { "ar", "OM", 0, "Arabic (Oman)"               },
     52  { "ar", "SA", 0, "Arabic (Saudi Arabia)"       },
     53  { "ar", "SY", 0, "Arabic (Syrian Arab Republic)" },
     54  { "ar", "TN", 0, "Arabic (Tunisia)"            },
     55  { "as", 0,    0, "Assamese"                    },
     56  { "ast",0,    0, "Asturian"                    },
     57  { "ay", 0,    0, "Aymara"                      },
     58  { "az", 0,    0, "Azerbaijani"                 },
     59  { "az", "IR", 0, "Azerbaijani (Iran)"          },
     60  { "be", 0,    0, "Belarusian"                  },
     61  { "be", 0, "latin", "Belarusian"               },
     62  { "bg", 0,    0, "Bulgarian"                   },
     63  { "bg", "BG", 0, "Bulgarian (Bulgaria)"        },
     64  { "bn", 0,    0, "Bengali"                     },
     65  { "bn", "BD", 0, "Bengali (Bangladesh)"        },
     66  { "bn", "IN", 0, "Bengali (India)"             },
     67  { "bo", 0,    0, "Tibetan"                     },
     68  { "br", 0,    0, "Breton"                      },
     69  { "bs", 0,    0, "Bosnian"                     },
     70  { "bs", "BA", 0, "Bosnian (Bosnia/Herzegovina)"},
     71  { "bs", "BS", 0, "Bosnian (Bahamas)"           },
     72  { "ca", "ES", "valencia", "Catalan (valencia)" },
     73  { "ca", "ES", 0, "Catalan (Spain)"             },
     74  { "ca", 0,    "valencia", "Catalan (valencia)" },
     75  { "ca", 0,    0, "Catalan"                     },
     76  { "co", 0,    0, "Corsican"                    },
     77  { "cs", 0,    0, "Czech"                       },
     78  { "cs", "CZ", 0, "Czech (Czech Republic)"      },
     79  { "cy", 0,    0, "Welsh"                       },
     80  { "cy", "GB", 0, "Welsh (Great Britain)"       },
     81  { "cz", 0,    0, "Unknown language"            },
     82  { "da", 0,    0, "Danish"                      },
     83  { "da", "DK", 0, "Danish (Denmark)"            },
     84  { "de", 0,    0, "German"                      },
     85  { "de", "AT", 0, "German (Austria)"            },
     86  { "de", "CH", 0, "German (Switzerland)"        },
     87  { "de", "DE", 0, "German (Germany)"            },
     88  { "dk", 0,    0, "Unknown language"            },
     89  { "dz", 0,    0, "Dzongkha"                    },
     90  { "el", 0,    0, "Greek"                       },
     91  { "el", "GR", 0, "Greek (Greece)"              },
     92  { "en", 0,    0, "English"                     },
     93  { "en", "AU", 0, "English (Australia)"         },
     94  { "en", "CA", 0, "English (Canada)"            },
     95  { "en", "GB", 0, "English (Great Britain)"     },
     96  { "en", "US", 0, "English (United States)"     },
     97  { "en", "ZA", 0, "English (South Africa)"      },
     98  { "en", 0, "boldquot", "English"               },
     99  { "en", 0, "quot", "English"                   },
     100  { "en", "US", "piglatin", "English"            },
     101  { "eo", 0,    0, "Esperanto"                   },
     102  { "es", 0,    0, "Spanish"                     },
     103  { "es", "AR", 0, "Spanish (Argentina)"         },
     104  { "es", "CL", 0, "Spanish (Chile)"             },
     105  { "es", "CO", 0, "Spanish (Colombia)"          },
     106  { "es", "CR", 0, "Spanish (Costa Rica)"        },
     107  { "es", "DO", 0, "Spanish (Dominican Republic)"},
     108  { "es", "EC", 0, "Spanish (Ecuador)"           },
     109  { "es", "ES", 0, "Spanish (Spain)"             },
     110  { "es", "GT", 0, "Spanish (Guatemala)"         },
     111  { "es", "HN", 0, "Spanish (Honduras)"          },
     112  { "es", "LA", 0, "Spanish (Laos)"              },
     113  { "es", "MX", 0, "Spanish (Mexico)"            },
     114  { "es", "NI", 0, "Spanish (Nicaragua)"         },
     115  { "es", "PA", 0, "Spanish (Panama)"            },
     116  { "es", "PE", 0, "Spanish (Peru)"              },
     117  { "es", "PR", 0, "Spanish (Puerto Rico)"       },
     118  { "es", "SV", 0, "Spanish (El Salvador)"       },
     119  { "es", "UY", 0, "Spanish (Uruguay)"           },
     120  { "es", "VE", 0, "Spanish (Venezuela)"         },
     121  { "et", 0,    0, "Estonian"                    },
     122  { "et", "EE", 0, "Estonian (Estonia)"          },
     123  { "et", "ET", 0, "Estonian (Ethiopia)"         },
     124  { "eu", 0,    0, "Basque"                      },
     125  { "eu", "ES", 0, "Basque (Spain)"              },
     126  { "fa", 0,    0, "Persian"                     },
     127  { "fa", "AF", 0, "Persian (Afghanistan)"       },
     128  { "fa", "IR", 0, "Persian (Iran)"              },
     129  { "fi", 0,    0, "Finnish"                     },
     130  { "fi", "FI", 0, "Finnish (Finland)"           },
     131  { "fo", 0,    0, "Faroese"                     },
     132  { "fo", "FO", 0, "Faeroese (Faroe Islands)"    },
     133  { "fr", 0,    0, "French"                      },
     134  { "fr", "CA", 0, "French (Canada)"             },
     135  { "fr", "CH", 0, "French (Switzerland)"        },
     136  { "fr", "FR", 0, "French (France)"             },
     137  { "fr", "LU", 0, "French (Luxembourg)"         },
     138  { "fy", 0,    0, "Frisian"                     },
     139  { "ga", 0,    0, "Irish"                       },
     140  { "gd", 0,    0, "Gaelic Scots"                },
     141  { "gl", 0,    0, "Galician"                    },
     142  { "gl", "ES", 0, "Galician (Spain)"            },
     143  { "gn", 0,    0, "Guarani"                     },
     144  { "gu", 0,    0, "Gujarati"                    },
     145  { "gv", 0,    0, "Manx"                        },
     146  { "ha", 0,    0, "Hausa"                       },
     147  { "he", 0,    0, "Hebrew"                      },
     148  { "he", "IL", 0, "Hebrew (Israel)"             },
     149  { "hi", 0,    0, "Hindi"                       },
     150  { "hr", 0,    0, "Croatian"                    },
     151  { "hr", "HR", 0, "Croatian (Croatia)"          },
     152  { "hu", 0,    0, "Hungarian"                   },
     153  { "hu", "HU", 0, "Hungarian (Hungary)"         },
     154  { "hy", 0,    0, "Armenian"                    },
     155  { "ia", 0,    0, "Interlingua"                 },
     156  { "id", 0,    0, "Indonesian"                  },
     157  { "id", "ID", 0, "Indonesian (Indonesia)"      },
     158  { "is", 0,    0, "Icelandic"                   },
     159  { "is", "IS", 0, "Icelandic (Iceland)"         },
     160  { "it", 0,    0, "Italian"                     },
     161  { "it", "CH", 0, "Italian (Switzerland)"       },
     162  { "it", "IT", 0, "Italian (Italy)"             },
     163  { "iu", 0,    0, "Inuktitut"                   },
     164  { "ja", 0,    0, "Japanese"                    },
     165  { "ja", "JP", 0, "Japanese (Japan)"            },
     166  { "ka", 0,    0, "Georgian"                    },
     167  { "kk", 0,    0, "Kazakh"                      },
     168  { "kl", 0,    0, "Kalaallisut"                 },
     169  { "km", 0,    0, "Khmer"                       },
     170  { "km", "KH", 0, "Khmer (Cambodia)"            },
     171  { "kn", 0,    0, "Kannada"                     },
     172  { "ko", 0,    0, "Korean"                      },
     173  { "ko", "KR", 0, "Korean (Korea)"              },
     174  { "ku", 0,    0, "Kurdish"                     },
     175  { "kw", 0,    0, "Cornish"                     },
     176  { "ky", 0,    0, "Kirghiz"                     },
     177  { "la", 0,    0, "Latin"                       },
     178  { "lo", 0,    0, "Lao"                         },
     179  { "lt", 0,    0, "Lithuanian"                  },
     180  { "lt", "LT", 0, "Lithuanian (Lithuania)"      },
     181  { "lv", 0,    0, "Latvian"                     },
     182  { "lv", "LV", 0, "Latvian (Latvia)"            },
     183  { "mg", 0,    0, "Malagasy"                    },
     184  { "mi", 0,    0, "Maori"                       },
     185  { "mk", 0,    0, "Macedonian"                  },
     186  { "mk", "MK", 0, "Macedonian (Macedonia)"      },
     187  { "ml", 0,    0, "Malayalam"                   },
     188  { "mn", 0,    0, "Mongolian"                   },
     189  { "mr", 0,    0, "Marathi"                     },
     190  { "ms", 0,    0, "Malay"                       },
     191  { "ms", "MY", 0, "Malay (Malaysia)"            },
     192  { "mt", 0,    0, "Maltese"                     },
     193  { "my", 0,    0, "Burmese"                     },
     194  { "my", "MM", 0, "Burmese (Myanmar)"           },
     195  { "nb", 0,    0, "Norwegian Bokmal"            },
     196  { "nb", "NO", 0, "Norwegian Bokmål (Norway)"   },
     197  { "ne", 0,    0, "Nepali"                      },
     198  { "nl", 0,    0, "Dutch"                       },
     199  { "nl", "BE", 0, "Dutch (Belgium)"             },
     200  { "nl", "NL", 0, "Dutch (Netherlands)"         },
     201  { "nn", 0,    0, "Norwegian Nynorsk"           },
     202  { "nn", "NO", 0, "Norwegian Nynorsk (Norway)"  },
     203  { "no", 0,    0, "Norwegian"                   },
     204  { "no", "NO", 0, "Norwegian (Norway)"          },
     205  { "no", "NY", 0, "Norwegian (NY)"              },
     206  { "nr", 0,    0, "Ndebele, South"              },
     207  { "oc", 0,    0, "Occitan post 1500"           },
     208  { "om", 0,    0, "Oromo"                       },
     209  { "or", 0,    0, "Oriya"                       },
     210  { "pa", 0,    0, "Punjabi"                     },
     211  { "pl", 0,    0, "Polish"                      },
     212  { "pl", "PL", 0, "Polish (Poland)"             },
     213  { "ps", 0,    0, "Pashto"                      },
     214  { "pt", 0,    0, "Portuguese"                  },
     215  { "pt", "BR", 0, "Brazilian"                   },
     216  { "pt", "PT", 0, "Portuguese (Portugal)"       },
     217  { "qu", 0,    0, "Quechua"                     },
     218  { "rm", 0,    0, "Rhaeto-Romance"              },
     219  { "ro", 0,    0, "Romanian"                    },
     220  { "ro", "RO", 0, "Romanian (Romania)"          },
     221  { "ru", 0,    0, "Russian"                     },
     222  { "ru", "RU", 0, "Russian (Russia"             },
     223  { "rw", 0,    0, "Kinyarwanda"                 },
     224  { "sa", 0,    0, "Sanskrit"                    },
     225  { "sd", 0,    0, "Sindhi"                      },
     226  { "se", 0,    0, "Sami"                        },
     227  { "se", "NO", 0, "Sami (Norway)"               },
     228  { "si", 0,    0, "Sinhalese"                   },
     229  { "sk", 0,    0, "Slovak"                      },
     230  { "sk", "SK", 0, "Slovak (Slovakia)"           },
     231  { "sl", 0,    0, "Slovenian"                   },
     232  { "sl", "SI", 0, "Slovenian (Slovenia)"        },
     233  { "sl", "SL", 0, "Slovenian (Sierra Leone)"    },
     234  { "sm", 0,    0, "Samoan"                      },
     235  { "so", 0,    0, "Somali"                      },
     236  { "sp", 0,    0, "Unknown language"            },
     237  { "sq", 0,    0, "Albanian"                    },
     238  { "sq", "AL", 0, "Albanian (Albania)"          },
     239  { "sr", 0,    0, "Serbian"                     },
     240  { "sr", "YU", 0, "Serbian (Yugoslavia)"        },
     241  { "sr", 0,"ije", "Serbian"                     },
     242  { "sr", 0, "latin", "Serbian"                  },
     243  { "sr", 0, "Latn",  "Serbian"                  },
     244  { "ss", 0,    0, "Swati"                       },
     245  { "st", 0,    0, "Sotho"                       },
     246  { "sv", 0,    0, "Swedish"                     },
     247  { "sv", "SE", 0, "Swedish (Sweden)"            },
     248  { "sv", "SV", 0, "Swedish (El Salvador)"       },
     249  { "sw", 0,    0, "Swahili"                     },
     250  { "ta", 0,    0, "Tamil"                       },
     251  { "te", 0,    0, "Telugu"                      },
     252  { "tg", 0,    0, "Tajik"                       },
     253  { "th", 0,    0, "Thai"                        },
     254  { "th", "TH", 0, "Thai (Thailand)"             },
     255  { "ti", 0,    0, "Tigrinya"                    },
     256  { "tk", 0,    0, "Turkmen"                     },
     257  { "tl", 0,    0, "Tagalog"                     },
     258  { "to", 0,    0, "Tonga"                       },
     259  { "tr", 0,    0, "Turkish"                     },
     260  { "tr", "TR", 0, "Turkish (Turkey)"            },
     261  { "ts", 0,    0, "Tsonga"                      },
     262  { "tt", 0,    0, "Tatar"                       },
     263  { "ug", 0,    0, "Uighur"                      },
     264  { "uk", 0,    0, "Ukrainian"                   },
     265  { "uk", "UA", 0, "Ukrainian (Ukraine)"         },
     266  { "ur", 0,    0, "Urdu"                        },
     267  { "ur", "PK", 0, "Urdu (Pakistan)"             },
     268  { "uz", 0,    0, "Uzbek"                       },
     269  { "uz", 0, "cyrillic", "Uzbek"                 },
     270  { "vi", 0,    0, "Vietnamese"                  },
     271  { "vi", "VN", 0, "Vietnamese (Vietnam)"        },
     272  { "wa", 0,    0, "Walloon"                     },
     273  { "wo", 0,    0, "Wolof"                       },
     274  { "xh", 0,    0, "Xhosa"                       },
     275  { "yi", 0,    0, "Yiddish"                     },
     276  { "yo", 0,    0, "Yoruba"                      },
     277  { "zh", 0,    0, "Chinese"                     },
     278  { "zh", "CN", 0, "Chinese (simplified)"        },
     279  { "zh", "HK", 0, "Chinese (Hong Kong)"         },
     280  { "zh", "TW", 0, "Chinese (traditional)"       },
     281  { "zu", 0,    0, "Zulu"                        },
     282  { NULL, 0,    0, NULL                          }
     283};
     284//*}
     285
    2286
     287std::string
     288resolve_language_alias(const std::string& name)
     289{
     290  typedef std::map<std::string, std::string> Aliases;
     291  static Aliases language_aliases;
     292  if (language_aliases.empty())
     293  {
     294    // FIXME: Many of those are not useful for us, since we leave
     295    // encoding to the app, not to the language, we could/should
     296    // also match against all language names, not just aliases from
     297    // locale.alias
     298
     299    // Aliases taken from /etc/locale.alias
     300    language_aliases["bokmal"]           = "nb_NO.ISO-8859-1";
     301    language_aliases["bokmål"]           = "nb_NO.ISO-8859-1";
     302    language_aliases["catalan"]          = "ca_ES.ISO-8859-1";
     303    language_aliases["croatian"]         = "hr_HR.ISO-8859-2";
     304    language_aliases["czech"]            = "cs_CZ.ISO-8859-2";
     305    language_aliases["danish"]           = "da_DK.ISO-8859-1";
     306    language_aliases["dansk"]            = "da_DK.ISO-8859-1";
     307    language_aliases["deutsch"]          = "de_DE.ISO-8859-1";
     308    language_aliases["dutch"]            = "nl_NL.ISO-8859-1";
     309    language_aliases["eesti"]            = "et_EE.ISO-8859-1";
     310    language_aliases["estonian"]         = "et_EE.ISO-8859-1";
     311    language_aliases["finnish"]          = "fi_FI.ISO-8859-1";
     312    language_aliases["français"]         = "fr_FR.ISO-8859-1";
     313    language_aliases["french"]           = "fr_FR.ISO-8859-1";
     314    language_aliases["galego"]           = "gl_ES.ISO-8859-1";
     315    language_aliases["galician"]         = "gl_ES.ISO-8859-1";
     316    language_aliases["german"]           = "de_DE.ISO-8859-1";
     317    language_aliases["greek"]            = "el_GR.ISO-8859-7";
     318    language_aliases["hebrew"]           = "he_IL.ISO-8859-8";
     319    language_aliases["hrvatski"]         = "hr_HR.ISO-8859-2";
     320    language_aliases["hungarian"]        = "hu_HU.ISO-8859-2";
     321    language_aliases["icelandic"]        = "is_IS.ISO-8859-1";
     322    language_aliases["italian"]          = "it_IT.ISO-8859-1";
     323    language_aliases["japanese"]         = "ja_JP.eucJP";
     324    language_aliases["japanese.euc"]     = "ja_JP.eucJP";
     325    language_aliases["ja_JP"]            = "ja_JP.eucJP";
     326    language_aliases["ja_JP.ujis"]       = "ja_JP.eucJP";
     327    language_aliases["japanese.sjis"]    = "ja_JP.SJIS";
     328    language_aliases["korean"]           = "ko_KR.eucKR";
     329    language_aliases["korean.euc"]       = "ko_KR.eucKR";
     330    language_aliases["ko_KR"]            = "ko_KR.eucKR";
     331    language_aliases["lithuanian"]       = "lt_LT.ISO-8859-13";
     332    language_aliases["no_NO"]            = "nb_NO.ISO-8859-1";
     333    language_aliases["no_NO.ISO-8859-1"] = "nb_NO.ISO-8859-1";
     334    language_aliases["norwegian"]        = "nb_NO.ISO-8859-1";
     335    language_aliases["nynorsk"]          = "nn_NO.ISO-8859-1";
     336    language_aliases["polish"]           = "pl_PL.ISO-8859-2";
     337    language_aliases["portuguese"]       = "pt_PT.ISO-8859-1";
     338    language_aliases["romanian"]         = "ro_RO.ISO-8859-2";
     339    language_aliases["russian"]          = "ru_RU.ISO-8859-5";
     340    language_aliases["slovak"]           = "sk_SK.ISO-8859-2";
     341    language_aliases["slovene"]          = "sl_SI.ISO-8859-2";
     342    language_aliases["slovenian"]        = "sl_SI.ISO-8859-2";
     343    language_aliases["spanish"]          = "es_ES.ISO-8859-1";
     344    language_aliases["swedish"]          = "sv_SE.ISO-8859-1";
     345    language_aliases["thai"]             = "th_TH.TIS-620";
     346    language_aliases["turkish"]          = "tr_TR.ISO-8859-9";
     347  }
     348
     349  std::string name_lowercase;
     350  name_lowercase.resize(name.size());
     351  for(std::string::size_type i = 0; i < name.size(); ++i)
     352    name_lowercase[i] = static_cast<char>(tolower(name[i]));
     353
     354  Aliases::iterator i = language_aliases.find(name_lowercase);
     355  if (i != language_aliases.end())
     356  {
     357    return i->second;
     358  }
     359  else
     360  {
     361    return name;
     362  }
     363}
     364
    3365
     366Language
     367Language::from_spec(const std::string& language, const std::string& country, const std::string& modifier)
     368{
     369  static std::map<std::string, std::vector<LanguageSpec*> > language_map;
     370
     371  if (language_map.empty())
     372  { // Init language_map
     373    for(int i = 0; languages[i].language != NULL; ++i)
     374      language_map[languages[i].language].push_back(&languages[i]);
     375  }
     376 
     377  std::map<std::string, std::vector<LanguageSpec*> >::iterator i = language_map.find(language);
     378  if (i != language_map.end())
     379  {
     380    std::vector<LanguageSpec*>& lst = i->second;
     381
     382    LanguageSpec tmpspec;
     383    tmpspec.language = language.c_str();
     384    tmpspec.country  = country.c_str();
     385    tmpspec.modifier = modifier.c_str();
     386    Language tmplang(&tmpspec);
     387     
     388    LanguageSpec* best_match = 0;
     389    int best_match_score = 0;
     390    for(std::vector<LanguageSpec*>::iterator j = lst.begin(); j != lst.end(); ++j)
     391    { // Search for the language that best matches the given spec, value country more then modifier
     392      int score = Language::match(Language(*j), tmplang);
     393
     394      if (score > best_match_score)
     395      {
     396        best_match = *j;
     397        best_match_score = score;
     398      }
     399    }
     400    assert(best_match);
     401    return Language(best_match);
     402  }
     403  else
     404  {
     405    return Language();
     406  }
     407}
     408
     409Language
     410Language::from_name(const std::string& spec_str)
     411{
     412  return from_env(resolve_language_alias(spec_str));
     413}
     414
     415Language
     416Language::from_env(const std::string& env)
     417{
     418  // Split LANGUAGE_COUNTRY.CODESET@MODIFIER into parts
     419  std::string::size_type ln = env.find('_');
     420  std::string::size_type dt = env.find('.');
     421  std::string::size_type at = env.find('@');
     422
     423  std::string language;
     424  std::string country;
     425  std::string codeset;
     426  std::string modifier;
     427
     428  //std::cout << ln << " " << dt << " " << at << std::endl;
     429
     430  language = env.substr(0, std::min(std::min(ln, dt), at));
     431
     432  if (ln != std::string::npos && ln+1 < env.size()) // _
     433  {
     434    country = env.substr(ln+1, (std::min(dt, at) == std::string::npos) ? std::string::npos : std::min(dt, at) - (ln+1));
     435  }
     436
     437  if (dt != std::string::npos && dt+1 < env.size()) // .
     438  {
     439    codeset = env.substr(dt+1, (at == std::string::npos) ? std::string::npos : (at - (dt+1)));
     440  }
     441
     442  if (at != std::string::npos && at+1 < env.size()) // @
     443  {
     444    modifier = env.substr(at+1);
     445  }
     446
     447  return from_spec(language, country, modifier);
     448}
     449
    4450
     451Language::Language(LanguageSpec* language_spec_)
     452  : language_spec(language_spec_)
     453{
     454}
     455
     456Language::Language()
     457  : language_spec(0)
     458{
     459}
     460
     461int
     462Language::match(const Language& lhs, const Language& rhs)
     463{
     464  if (lhs.get_language() != rhs.get_language())
     465  {
     466    return 0;
     467  }
     468  else
     469  {
     470    static int match_tbl[3][3] = {
     471      // modifier match, wildchard, miss
     472      { 9, 8, 5 }, // country match
     473      { 7, 6, 3 }, // country wildcard
     474      { 4, 2, 1 }, // country miss
     475    };
     476 
     477    int c;
     478    if (lhs.get_country() == rhs.get_country())
     479      c = 0;
     480    else if (lhs.get_country().empty() || rhs.get_country().empty())
     481      c = 1;
     482    else
     483      c = 2;
     484 
     485    int m;
     486    if (lhs.get_modifier() == rhs.get_modifier())
     487      m = 0;
     488    else if (lhs.get_modifier().empty() || rhs.get_modifier().empty())
     489      m = 1;
     490    else
     491      m = 2;
     492
     493    return match_tbl[c][m];
     494  }
     495}
     496
     497std::string
     498Language::get_language() const
     499{
     500  if (language_spec)
     501    return language_spec->language;
     502  else
     503    return "";
     504}
     505
     506std::string
     507Language::get_country()  const
     508{
     509  if (language_spec && language_spec->country)
     510    return language_spec->country;
     511  else
     512    return "";
     513}
     514
     515std::string
     516Language::get_modifier() const
     517{
     518  if (language_spec && language_spec->modifier)
     519    return language_spec->modifier;
     520  else
     521    return "";
     522}
     523
     524std::string
     525Language::get_name()  const
     526{
     527  if (language_spec)
     528    return language_spec->name;
     529  else
     530    return "";
     531}
     532
     533std::string
     534Language::str() const
     535{
     536  if (language_spec)
     537  {
     538    std::string var;
     539    var += language_spec->language;
     540    if (language_spec->country)
     541    {
     542      var += "_";
     543      var += language_spec->country;
     544    }
     545
     546    if (language_spec->modifier)
     547    {
     548      var += "@";
     549      var += language_spec->modifier;
     550    }
     551    return var;
     552  }
     553  else
     554  {
     555    return "";
     556  }
     557}
     558
     559bool
     560Language::operator==(const Language& rhs) const
     561{
     562  return language_spec == rhs.language_spec;
     563}
     564
     565bool
     566Language::operator!=(const Language& rhs) const
     567{
     568  return language_spec != rhs.language_spec;
  • libraries/source/tinygettext/tinygettext/language.hpp

    +}
    +
    
    +} // namespace tinygettext
    +
    +/* EOF */
     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_LANGUAGE_HPP
     19#define HEADER_TINYGETTEXT_LANGUAGE_HPP
     20
     21#include <string>
     22
     23namespace tinygettext {
     24
     25struct LanguageSpec;
     26
     27/** Lightweight wrapper around LanguageSpec */
     28class Language
     29{
     30private:
     31  LanguageSpec* language_spec;
     32
     33  Language(LanguageSpec* language_spec);
     34
     35public:
     36  /** Create a language from language and country code:
     37      Example: Languge("de", "DE"); */
     38  static Language from_spec(const std::string& language,
     39                            const std::string& country = std::string(),
     40                            const std::string& modifier = std::string());
     41
     42  /** Create a language from language and country code:
     43      Example: Languge("deutsch");
     44      Example: Languge("de_DE"); */
     45  static Language from_name(const std::string& str);
     46
     47  /** Create a language from an environment variable style string (e.g de_DE.UTF-8@modifier) */
     48  static Language from_env(const std::string& env);
     49
     50  /** Compares two Languages, returns 0 on missmatch and a score
     51      between 1 and 9 on match, the higher the score the better the
     52      match */
     53  static int match(const Language& lhs, const Language& rhs);
     54
     55  /** Create an undefined Language object */
     56  Language();
     57 
     58  operator bool() const { return language_spec; }
     59
     60  /** Returns the language code (i.e. de, en, fr) */
     61  std::string get_language() const;
     62
     63  /** Returns the country code (i.e. DE, AT, US) */
     64  std::string get_country()  const;
     65
     66  /** Returns the modifier of the language (i.e. latn or Latn for
     67      Serbian with non-cyrilic characters) */
     68  std::string get_modifier()  const;
     69
     70  /** Returns the human readable name of the Language */
     71  std::string get_name() const;
     72
     73  /** Returns the Language as string in the form of an environment
     74      variable: {language}_{country}@{modifier} */
     75  std::string str() const;
     76
     77  bool operator==(const Language& rhs) const;
     78  bool operator!=(const Language& rhs) const;
     79
     80  friend bool operator<(const Language& lhs, const Language& rhs);
     81};
     82
     83inline bool operator<(const Language& lhs, const Language& rhs) {
     84  return lhs.language_spec < rhs.language_spec;
     85}
     86
     87} // namespace tinygettext
     88
     89#endif
     90
     91/* EOF */
  • libraries/source/tinygettext/tinygettext/log.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include <iostream>
     19#include "log.hpp"
     20
     21namespace tinygettext {
     22
    023
     24Log::log_callback_t Log::log_info_callback    = &Log::default_log_callback;
     25Log::log_callback_t Log::log_warning_callback = &Log::default_log_callback;
     26Log::log_callback_t Log::log_error_callback   = &Log::default_log_callback;
     27
    128
     29void
     30Log::default_log_callback(const std::string& str)
     31{
     32  std::cerr << "tinygettext: " << str;
     33}
     34
     35void
     36Log::set_log_info_callback(log_callback_t callback)
     37{
     38  log_info_callback = callback;
     39}
     40
     41void
     42Log::set_log_warning_callback(log_callback_t callback)
     43{
     44  log_warning_callback = callback;
     45}
     46
     47void
     48Log::set_log_error_callback(log_callback_t callback)
     49{
     50  log_error_callback = callback;
     51}
     52
    253
     54Log::Log(log_callback_t callback_) :
     55  callback(callback_),
     56  out()
     57{
     58}
     59
     60Log::~Log()
     61{
     62  callback(out.str());
     63}
     64
     65std::ostream&
     66Log::get()
     67{
     68  return out;
     69}
     70
  • libraries/source/tinygettext/tinygettext/log.hpp

    +} // namespace tinygettext
    +
    +/* EOF */
     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_LOG_HPP
     19#define HEADER_TINYGETTEXT_LOG_HPP
     20
     21#include <sstream>
     22
     23namespace tinygettext {
     24
     25class Log
     26{
     27public:
     28  typedef void (*log_callback_t)(const std::string&);
     29
     30  static log_callback_t log_info_callback;
     31  static log_callback_t log_warning_callback;
     32  static log_callback_t log_error_callback;
     33
     34
     35  static void default_log_callback(const std::string& str);
     36
     37  static void set_log_info_callback(log_callback_t callback);
     38  static void set_log_warning_callback(log_callback_t callback);
     39  static void set_log_error_callback(log_callback_t callback);
     40
     41private:
     42  log_callback_t callback;
     43  std::ostringstream out;
     44
     45public:
     46  Log(log_callback_t callback);
     47  ~Log();
     48 
     49  std::ostream& get();
     50};
     51
     52} // namespace tinygettext
     53
     54#endif
     55
     56/* EOF */
  • libraries/source/tinygettext/tinygettext/log_stream.hpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_LOG_STREAM_HPP
     19#define HEADER_TINYGETTEXT_LOG_STREAM_HPP
     20
     21#include "log.hpp"
     22
     23namespace tinygettext {
     24
     25// FIXME: very bad to have such things in the API
     26#define log_error   if (!Log::log_error_callback);   else (Log(Log::log_error_callback)).get()
     27#define log_warning if (!Log::log_warning_callback); else (Log(Log::log_warning_callback)).get()
     28#define log_info    if (!Log::log_info_callback);    else (Log(Log::log_warning_callback)).get()
     29
     30} // namespace tinygettext
     31
     32#endif
     33
     34/* EOF */
  • libraries/source/tinygettext/tinygettext/plural_forms.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include "plural_forms.hpp"
     19
     20#include <map>
     21
     22namespace tinygettext {
     23
    024
     25/**
     26 *  Plural functions are used to select a string that matches a given
     27 *  count. \a n is the count and the return value is the string index
     28 *  used in the .po file, for example:
     29 *   
     30 *   msgstr[0] = "You got %d error";
     31 *   msgstr[1] = "You got %d errors";       
     32 *          ^-- return value of plural function
     33 */
     34unsigned int plural1(int )     { return 0; }
     35unsigned int plural2_1(int n)  { return (n != 1); }
     36unsigned int plural2_2(int n)  { return (n > 1); }
     37unsigned int plural2_mk(int n) { return n==1 || n%10==1 ? 0 : 1; }
     38unsigned int plural3_lv(int n) { return static_cast<unsigned int>(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2); }
     39unsigned int plural3_ga(int n) { return static_cast<unsigned int>(n==1 ? 0 : n==2 ? 1 : 2); }
     40unsigned int plural3_lt(int n) { return static_cast<unsigned int>(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2); }
     41unsigned int plural3_1(int n)  { return static_cast<unsigned int>(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
     42unsigned int plural3_sk(int n) { return static_cast<unsigned int>( (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2 ); }
     43unsigned int plural3_pl(int n) { return static_cast<unsigned int>(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
     44unsigned int plural3_sl(int n) { return static_cast<unsigned int>(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3); }
     45unsigned int plural4_ar(int n) { return static_cast<unsigned int>( n==1 ? 0 : n==2 ? 1 : n>=3 && n<=10 ? 2 : 3 ); }
     46
    147
     48PluralForms
     49PluralForms::from_string(const std::string& str)
     50{
     51  static std::map<std::string, struct PluralForms> plural_forms;
     52   
     53  if (plural_forms.empty())
     54  {
     55    // Note that the plural forms here shouldn't contain any spaces
     56    plural_forms["Plural-Forms:nplurals=1;plural=0;"] = PluralForms(1, plural1);
     57    plural_forms["Plural-Forms:nplurals=2;plural=(n!=1);"] = PluralForms(2, plural2_1);
     58    plural_forms["Plural-Forms:nplurals=2;plural=n!=1;"] = PluralForms(2, plural2_1);
     59    plural_forms["Plural-Forms:nplurals=2;plural=(n>1);"] = PluralForms(2, plural2_2);
     60    plural_forms["Plural-Forms:nplurals=2;plural=n==1||n%10==1?0:1;"] = PluralForms(2, plural2_mk);
     61    plural_forms["Plural-Forms:nplurals=3;plural=n%10==1&&n%100!=11?0:n!=0?1:2);"] = PluralForms(2, plural3_lv);
     62    plural_forms["Plural-Forms:nplurals=3;plural=n==1?0:n==2?1:2;"] = PluralForms(3, plural3_ga);
     63    plural_forms["Plural-Forms:nplurals=3;plural=(n%10==1&&n%100!=11?0:n%10>=2&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_lt);
     64    plural_forms["Plural-Forms:nplurals=3;plural=(n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_1);
     65    plural_forms["Plural-Forms:nplurals=3;plural=(n==1)?0:(n>=2&&n<=4)?1:2;"] = PluralForms(3, plural3_sk);
     66    plural_forms["Plural-Forms:nplurals=3;plural=(n==1?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_pl);
     67    plural_forms["Plural-Forms:nplurals=3;plural=(n%100==1?0:n%100==2?1:n%100==3||n%100==4?2:3);"] = PluralForms(3, plural3_sl);
     68
     69    plural_forms["Plural-Forms:nplurals=4;plural=n==1?0:n==2?1:n>=3&&n<=10?2:3;"]=PluralForms(4, plural4_ar);
     70  }
     71 
     72  // Remove spaces from string before lookup
     73  std::string space_less_str;
     74  for(std::string::size_type i = 0; i < str.size(); ++i)
     75    if (!isspace(str[i]))
     76      space_less_str += str[i];
     77 
     78  std::map<std::string, struct PluralForms>::const_iterator it= plural_forms.find(space_less_str);
     79  if (it != plural_forms.end())
     80  {
     81    return it->second;
     82  }
     83  else
     84  {
     85    return PluralForms();
     86  }
     87}
     88
     89} // namespace tinygettext
  • libraries/source/tinygettext/tinygettext/plural_forms.hpp

    +
    +/* EOF */
     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_PLURAL_FORMS_HPP
     19#define HEADER_TINYGETTEXT_PLURAL_FORMS_HPP
     20
     21#include <string>
     22
     23namespace tinygettext {
     24
     25typedef unsigned int (*PluralFunc)(int n);
     26
     27class PluralForms
     28{
     29private:
     30  unsigned int nplural;
     31  PluralFunc   plural;
     32
     33public:
     34  static PluralForms from_string(const std::string& str);
     35
     36  PluralForms()
     37    : nplural(0),
     38      plural(0)
     39  {}
     40
     41  PluralForms(unsigned int nplural_, PluralFunc plural_)
     42    : nplural(nplural_),
     43      plural(plural_)
     44  {}
     45
     46  unsigned int get_nplural() const { return nplural; }
     47  unsigned int get_plural(int n) const { if (plural) return plural(n); else return 0; }
     48
     49  bool operator==(const PluralForms& other) { return nplural == other.nplural && plural == other.plural; }
     50  bool operator!=(const PluralForms& other) { return !(*this == other); }
     51
     52  operator bool() const {
     53    return plural;
     54  }
     55};
     56
     57} // namespace tinygettext
     58
     59#endif
     60
     61/* EOF */
  • libraries/source/tinygettext/tinygettext/po_parser.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include "po_parser.hpp"
     19
     20#include <iostream>
     21#include <ctype.h>
     22#include <string>
     23#include <istream>
     24#include <string.h>
     25#include <map>
     26#include <stdlib.h>
     27
     28#include "language.hpp"
     29#include "log_stream.hpp"
     30#include "iconv.hpp"
     31#include "dictionary.hpp"
     32#include "plural_forms.hpp"
     33
     34namespace tinygettext {
     35
     36bool POParser::pedantic = true;
     37
    038
     39void
     40POParser::parse(const std::string& filename, std::istream& in, Dictionary& dict)
     41{
     42  POParser parser(filename, in, dict);
     43  parser.parse();
     44}
     45
    146
     47class POParserError {};
     48
     49POParser::POParser(const std::string& filename_, std::istream& in_, Dictionary& dict_, bool use_fuzzy_) :
     50  filename(filename_),
     51  in(in_),
     52  dict(dict_),
     53  use_fuzzy(use_fuzzy_),
     54  running(false),
     55  eof(false),
     56  big5(false),
     57  line_number(0),
     58  current_line(),
     59  conv()
     60{
     61}
     62
     63POParser::~POParser()
     64{
     65}
     66
     67void
     68POParser::warning(const std::string& msg)
     69{
     70  log_warning << filename << ":" << line_number << ": warning: " << msg << ": " << current_line << std::endl;
     71  //log_warning << "Line: " << current_line << std::endl;
     72}
     73
     74void
     75POParser::error(const std::string& msg)
     76{
     77  log_error << filename << ":" << line_number << ": error: " << msg  << ": " << current_line << std::endl;
     78
     79  // Try to recover from an error by searching for start of another entry
     80  do
     81    next_line();
     82  while(!eof && !is_empty_line());
     83
     84  throw POParserError();
     85}
     86
     87void
     88POParser::next_line()
     89{
     90  line_number += 1;
     91  if (!std::getline(in, current_line))
     92    eof = true;
     93}
     94
     95void
     96POParser::get_string_line(std::ostringstream& out,std::string::size_type skip)
     97{
     98  if (skip+1 >= static_cast<std::string::size_type>(current_line.size()))
     99    error("unexpected end of line");
     100
     101  if (current_line[skip] != '"')
     102    error("expected start of string '\"'");
     103 
     104  std::string::size_type i;
     105  for(i = skip+1; current_line[i] != '\"'; ++i)
     106  {
     107    if (big5 && static_cast<unsigned char>(current_line[i]) >= 0x81 && static_cast<unsigned char>(current_line[i]) <= 0xfe)
     108    {
     109      out << current_line[i];
     110
     111      i += 1;
     112         
     113      if (i >= current_line.size())
     114        error("invalid big5 encoding");
     115         
     116      out << current_line[i];
     117    }
     118    else if (i >= current_line.size())
     119    {
     120      error("unexpected end of string");
     121    }
     122    else if (current_line[i] == '\\')
     123    {
     124      i += 1;
     125
     126      if (i >= current_line.size())
     127        error("unexpected end of string in handling '\\'");
     128
     129      switch (current_line[i])
     130      {
     131        case 'a':  out << '\a'; break;
     132        case 'b':  out << '\b'; break;
     133        case 'v':  out << '\v'; break;
     134        case 'n':  out << '\n'; break;
     135        case 't':  out << '\t'; break;
     136        case 'r':  out << '\r'; break;
     137        case '"':  out << '"'; break;
     138        case '\\': out << '\\'; break;
     139        default:
     140          std::ostringstream err;
     141          err << "unhandled escape '\\" << current_line[i] << "'";
     142          warning(err.str());
     143
     144          out << current_line[i-1] << current_line[i];
     145          break;
     146      }
     147    }
     148    else
     149    {
     150      out << current_line[i];
     151    }
     152  }
     153
     154  // process trailing garbage in line and warn if there is any
     155  for(i = i+1; i < current_line.size(); ++i)
     156    if (!isspace(current_line[i]))
     157    {
     158      warning("unexpected garbage after string ignoren");
     159      break;
     160    }
     161}
     162
     163std::string
     164POParser::get_string(std::string::size_type skip)
     165{
     166  std::ostringstream out;
     167
     168  if (skip+1 >= static_cast<std::string::size_type>(current_line.size()))
     169    error("unexpected end of line");
     170
     171  if (current_line[skip] == ' ' && current_line[skip+1] == '"')
     172  {
     173    get_string_line(out, skip+1);
     174  }
     175  else
     176  {
     177    if (pedantic)
     178      warning("keyword and string must be seperated by a single space");
     179
     180    for(;;)
     181    {
     182      if (skip >= static_cast<std::string::size_type>(current_line.size()))
     183        error("unexpected end of line");
     184      else if (current_line[skip] == '\"')
     185      {
     186        get_string_line(out, skip);
     187        break;
     188      }
     189      else if (!isspace(current_line[skip]))
     190      {
     191        error("string must start with '\"'");
     192      }
     193      else
     194      {
     195        // skip space
     196      }
     197
     198      skip += 1;
     199    }
     200  }
     201 
     202next:
     203  next_line();
     204  for(std::string::size_type i = 0; i < current_line.size(); ++i)
     205  {
     206    if (current_line[i] == '"')
     207    {
     208      if (i == 1)
     209        if (pedantic)
     210          warning("leading whitespace before string");
     211
     212      get_string_line(out, i);
     213      goto next;
     214    }
     215    else if (isspace(current_line[i]))
     216    {
     217      // skip
     218    }
     219    else
     220    {
     221      break;
     222    }
     223  }
     224
     225  return out.str();
     226}
     227
     228static bool has_prefix(const std::string& lhs, const std::string rhs)
     229{
     230  if (lhs.length() < rhs.length())
     231    return false;
     232  else
     233    return lhs.compare(0, rhs.length(), rhs) == 0;
     234}
     235
     236void
     237POParser::parse_header(const std::string& header)
     238{
     239  std::string from_charset;
     240  std::string::size_type start = 0;
     241  for(std::string::size_type i = 0; i < header.length(); ++i)
     242  {
     243    if (header[i] == '\n')
     244    {
     245      std::string line = header.substr(start, i - start);
     246
     247      if (has_prefix(line, "Content-Type:"))
     248      {
     249        // from_charset = line.substr(len);
     250        std::string::size_type len = strlen("Content-Type: text/plain; charset=");
     251        if (line.compare(0, len, "Content-Type: text/plain; charset=") == 0)
     252        {
     253          from_charset = line.substr(len);
     254
     255          for(std::string::iterator ch = from_charset.begin(); ch != from_charset.end(); ++ch)
     256            *ch = static_cast<char>(toupper(*ch));
     257        }
     258        else
     259        {
     260          warning("malformed Content-Type header");
     261        }
     262      }
     263      else if (has_prefix(line, "Plural-Forms:"))
     264      {
     265        PluralForms plural_forms = PluralForms::from_string(line);
     266        if (!plural_forms)
     267        {
     268          warning("unknown Plural-Forms given");
     269        }
     270        else
     271        {
     272          if (!dict.get_plural_forms())
     273          {
     274            dict.set_plural_forms(plural_forms);
     275          }
     276          else
     277          {
     278            if (dict.get_plural_forms() != plural_forms)
     279            {
     280              warning("Plural-Forms missmatch between .po file and dictionary");
     281            }
     282          }
     283        }
     284      }
     285      start = i+1;
     286    }
     287  }
     288
     289  if (from_charset.empty() || from_charset == "CHARSET")
     290  {
     291    warning("charset not specified for .po, fallback to utf-8");
     292    from_charset = "UTF-8";
     293  }
     294  else if (from_charset == "BIG5")
     295  {
     296    big5 = true;
     297  }
     298
     299  conv.set_charsets(from_charset, dict.get_charset());
     300}
     301
     302bool
     303POParser::is_empty_line()
     304{
     305  if (current_line.empty())
     306  {
     307    return true;
     308  }
     309  else if (current_line[0] == '#')
     310  { // handle comments as empty lines
     311    if (current_line.size() == 1 || (current_line.size() >= 2 && isspace(current_line[1])))
     312      return true;
     313    else
     314      return false;
     315  }
     316  else
     317  {
     318    for(std::string::iterator i = current_line.begin(); i != current_line.end(); ++i)
     319    {
     320      if (!isspace(*i))
     321        return false;
     322    }
     323  }
     324  return true;
     325}
     326
     327bool
     328POParser::prefix(const char* prefix_str)
     329{
     330  return current_line.compare(0, strlen(prefix_str), prefix_str) == 0;
     331}
     332
     333void
     334POParser::parse()
     335{
     336  next_line();
     337
     338  // skip UTF-8 intro that some text editors produce
     339  // see http://en.wikipedia.org/wiki/Byte-order_mark
     340  if (current_line.size() >= 3 &&
     341      current_line[0] == static_cast<char>(0xef) &&
     342      current_line[1] == static_cast<char>(0xbb) &&
     343      current_line[2] == static_cast<char>(0xbf))
     344  {
     345    current_line = current_line.substr(3);
     346  }
     347
     348  // Parser structure
     349  while(!eof)
     350  {
     351    try
     352    {
     353      bool fuzzy =  false;
     354      bool has_msgctxt = false;
     355      std::string msgctxt;
     356      std::string msgid;
     357
     358      while(prefix("#"))
     359      {
     360        if (current_line.size() >= 2 && current_line[1] == ',')
     361        {
     362          // FIXME: Rather simplistic hunt for fuzzy flag
     363          if (current_line.find("fuzzy", 2) != std::string::npos)
     364            fuzzy = true;
     365        }
     366
     367        next_line();
     368      }
     369
     370      if (!is_empty_line())
     371      {
     372        if (prefix("msgctxt"))
     373        {
     374          has_msgctxt = true;
     375          msgctxt = get_string(7);
     376        }
     377
     378        if (prefix("msgid"))
     379          msgid = get_string(5);
     380        else
     381          error("expected 'msgid'");
     382
     383        if (prefix("msgid_plural"))
     384        {
     385          std::string msgid_plural = get_string(12);
     386          std::vector<std::string> msgstr_num;
     387      bool saw_nonempty_msgstr = false;
     388
     389        next:
     390          if (is_empty_line())
     391          {
     392            if (msgstr_num.empty())
     393              error("expected 'msgstr[N] (0 <= N <= 9)'");
     394          }
     395          else if (prefix("msgstr[") &&
     396                   current_line.size() > 8 &&
     397                   isdigit(current_line[7]) && current_line[8] == ']')
     398          {
     399            std::string::size_type number = static_cast<std::string::size_type>(current_line[7] - '0');
     400        std::string msgstr = get_string(9);
     401
     402        if(!msgstr.empty())
     403          saw_nonempty_msgstr = true;
     404
     405            if (number >= msgstr_num.size())
     406              msgstr_num.resize(number+1);
     407
     408            msgstr_num[number] = conv.convert(msgstr);
     409            goto next;
     410          }
     411          else
     412          {
     413            error("expected 'msgstr[N]'");
     414          }
     415
     416          if (!is_empty_line())
     417            error("expected 'msgstr[N]' or empty line");
     418
     419      if (saw_nonempty_msgstr)
     420      {
     421        if (use_fuzzy || !fuzzy)
     422            {
     423          if (!dict.get_plural_forms())
     424          {
     425        warning("msgstr[N] seen, but no Plural-Forms given");
     426          }
     427          else
     428          {
     429        if (msgstr_num.size() != dict.get_plural_forms().get_nplural())
     430        {
     431          warning("msgstr[N] count doesn't match Plural-Forms.nplural");
     432        }
     433          }
     434
     435          if (has_msgctxt)
     436        dict.add_translation(msgctxt, msgid, msgid_plural, msgstr_num);
     437          else
     438        dict.add_translation(msgid, msgid_plural, msgstr_num);
     439        }
     440
     441        if (0)
     442        {
     443          std::cout << (fuzzy?"fuzzy":"not-fuzzy") << std::endl;
     444          std::cout << "msgid \"" << msgid << "\"" << std::endl;
     445          std::cout << "msgid_plural \"" << msgid_plural << "\"" << std::endl;
     446          for(std::vector<std::string>::size_type i = 0; i < msgstr_num.size(); ++i)
     447        std::cout << "msgstr[" << i << "] \"" << conv.convert(msgstr_num[i]) << "\"" << std::endl;
     448          std::cout << std::endl;
     449        }
     450      }
     451        }
     452        else if (prefix("msgstr"))
     453        {
     454          std::string msgstr = get_string(6);
     455
     456          if (msgid.empty())
     457          {
     458            parse_header(msgstr);
     459          }
     460          else if(!msgstr.empty())
     461          {
     462            if (use_fuzzy || !fuzzy)
     463            {
     464              if (has_msgctxt)
     465                dict.add_translation(msgctxt, msgid, conv.convert(msgstr));
     466              else
     467                dict.add_translation(msgid, conv.convert(msgstr));
     468            }
     469
     470            if (0)
     471            {
     472              std::cout << (fuzzy?"fuzzy":"not-fuzzy") << std::endl;
     473              std::cout << "msgid \"" << msgid << "\"" << std::endl;
     474              std::cout << "msgstr \"" << conv.convert(msgstr) << "\"" << std::endl;
     475              std::cout << std::endl;
     476            }
     477          }
     478        }
     479        else
     480        {
     481          error("expected 'msgstr' or 'msgid_plural'");
     482        }
     483      }
     484     
     485      if (!is_empty_line())
     486        error("expected empty line");
     487
     488      next_line();
     489    }
     490    catch(POParserError&)
     491    {         
     492    }
     493  }
     494}
     495
     496} // namespace tinygettext
  • libraries/source/tinygettext/tinygettext/po_parser.hpp

    +
    +/* EOF */
     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_PO_PARSER_HPP
     19#define HEADER_TINYGETTEXT_PO_PARSER_HPP
     20
     21#include <iosfwd>
     22
     23#include "iconv.hpp"
     24
     25namespace tinygettext {
     26
     27class Dictionary;
     28
     29class POParser
     30{
     31private:
     32  std::string filename;
     33  std::istream& in;
     34  Dictionary& dict;
     35  bool  use_fuzzy;
     36
     37  bool running;
     38  bool eof;
     39  bool big5;
     40
     41  int line_number;
     42  std::string current_line;
     43
     44  IConv conv;
     45 
     46  POParser(const std::string& filename, std::istream& in_, Dictionary& dict_, bool use_fuzzy = true);
     47  ~POParser();
     48
     49  void parse_header(const std::string& header);
     50  void parse();
     51  void next_line();
     52  std::string get_string(std::string::size_type skip);
     53  void get_string_line(std::ostringstream& str,std::string::size_type skip);
     54  bool is_empty_line();
     55  bool prefix(const char* );
     56  void error(const std::string& msg) __attribute__((__noreturn__));
     57  void warning(const std::string& msg);
     58
     59public:
     60  /** @param filename name of the istream, only used in error messages
     61      @param in stream from which the PO file is read.
     62      @param dict dictionary to which the strings are written */
     63  static void parse(const std::string& filename, std::istream& in, Dictionary& dict);
     64  static bool pedantic;
     65
     66private:
     67  POParser (const POParser&);
     68  POParser& operator= (const POParser&);
     69};
     70
     71} // namespace tinygettext
     72
     73#endif
     74
     75/* EOF */
  • libraries/source/tinygettext/tinygettext/tinygettext.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18namespace tinygettext {
     19
     20} // namespace tinygettext
     21
     22/* EOF */
  • libraries/source/tinygettext/tinygettext/tinygettext.hpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_TINYGETTEXT_HPP
     19#define HEADER_TINYGETTEXT_TINYGETTEXT_HPP
     20
     21#include "dictionary.hpp"
     22#include "dictionary_manager.hpp"
     23#include "language.hpp"
     24
     25#endif
     26
     27/* EOF */
  • libraries/source/tinygettext/tinygettext/unix_file_system.cpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#include "unix_file_system.hpp"
     19
     20#include <sys/types.h>
     21#include <fstream>
     22#include <dirent.h>
     23#include <stdlib.h>
     24#include <dirent.h>
     25#include <string.h>
     26
     27namespace tinygettext {
     28
     29UnixFileSystem::UnixFileSystem()
     30{
     31}
     32
     33std::vector<std::string>
     34UnixFileSystem::open_directory(const std::string& pathname)
     35{
     36  DIR* dir = opendir(pathname.c_str());
     37  if (!dir)
     38  {
     39    // FIXME: error handling
     40    return std::vector<std::string>();
     41  }
     42  else
     43  {
     44    std::vector<std::string> files;
     45
     46    struct dirent* dp;
     47    while((dp = readdir(dir)) != 0)
     48    {
     49      files.push_back(dp->d_name);
     50    }
     51    closedir(dir);
     52
     53    return files;
     54  }
     55}
     56 
     57std::auto_ptr<std::istream>
     58UnixFileSystem::open_file(const std::string& filename)
     59{
     60  return std::auto_ptr<std::istream>(new std::ifstream(filename.c_str()));
     61}
     62
     63} // namespace tinygettext
     64
     65/* EOF */
  • libraries/source/tinygettext/tinygettext/unix_file_system.hpp

     
     1//  tinygettext - A gettext replacement that works directly on .po files
     2//  Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
     3//
     4//  This program is free software; you can redistribute it and/or
     5//  modify it under the terms of the GNU General Public License
     6//  as published by the Free Software Foundation; either version 2
     7//  of the License, or (at your option) any later version.
     8//
     9//  This program is distributed in the hope that it will be useful,
     10//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12//  GNU General Public License for more details.
     13//
     14//  You should have received a copy of the GNU General Public License
     15//  along with this program; if not, write to the Free Software
     16//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     17
     18#ifndef HEADER_TINYGETTEXT_UNIX_FILE_SYSTEM_HPP
     19#define HEADER_TINYGETTEXT_UNIX_FILE_SYSTEM_HPP
     20
     21#include "file_system.hpp"
     22
     23namespace tinygettext {
     24
     25class UnixFileSystem : public FileSystem
     26{
     27public:
     28  UnixFileSystem();
     29
     30  std::vector<std::string>    open_directory(const std::string& pathname);
     31  std::auto_ptr<std::istream> open_file(const std::string& filename);
     32};
     33
     34} // namespace tinygettext
     35
     36#endif
     37
     38/* EOF */
  • libraries/source/tinygettext/tinygettext.pc.in

     
     1# Unfortunately, since this project is built with cmake,
     2# these variables can't properly be set.
     3
     4prefix=@CMAKE_INSTALL_PREFIX@
     5exec_prefix=${prefix}
     6libdir=${exec_prefix}/@LIB_SUBDIR@
     7includedir=${prefix}/include
     8
     9Name: @PROJECT_NAME@
     10Description: tiny, minimal gettext replacement
     11Version: @VERSION@
     12URL: http://tinygettext.googlecode.com/
     13Requires:
     14Libs: -L${libdir} -ltinygettext
     15Libs.private:
     16Cflags: -I${includedir}
  • localization/gui.its

     
     1<its:rules
     2    xmlns:its="http://www.w3.org/2005/11/its"
     3    version="1.0">
     4 
     5  <its:translateRule selector="//objects" translate="no" />
     6  <its:translateRule selector="//page" translate="no" />
     7  <its:translateRule selector="//setup" translate="no" />
     8  <its:translateRule selector="//sprites" translate="no" />
     9  <its:translateRule selector="//styles" translate="no" />
     10 
     11  <!-- Translate the value of these elements only. -->
     12  <its:translateRule selector="//localizableAttribute" translate="yes" />
     13  <its:translateRule selector="//localize" translate="yes" />
     14 
     15</its:rules>
  • localization/update-pot.sh

     
     1#!/bin/bash
     2
     3basedir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
     4
     5# Go to the 0ad root, so that the paths in the POT file go from there.
     6pushd $basedir/.. &> /dev/null
     7
     8for modFolderPath in binaries/data/mods/*
     9do   
     10    modName=$(basename $modFolderPath)
     11   
     12    if [ -d "$modFolderPath/gui" ]; then
     13       
     14        declare -a guiXmlFiles
     15        for guiXmlFile in $(find $modFolderPath/gui -name "*.xml")
     16        do
     17            guiXmlFiles=("${guiXmlFiles[@]}" "$guiXmlFile")
     18        done
     19       
     20        outputPot=$modFolderPath/po/${modName}.pot
     21
     22        itstool -o ${outputPot} -i $basedir/gui.its ${guiXmlFiles[@]}
     23        unset guiXmlFiles
     24
     25        sed -e "s/\&amp;/\&/g" -i ${outputPot}
     26    fi
     27
     28done
     29
     30popd &> /dev/null
     31
     32
     33
  • source/gui/CGUI.cpp

     
    4545#include "graphics/TextRenderer.h"
    4646#include "lib/input.h"
    4747#include "lib/bits.h"
     48#include "lib/localization.h"
    4849#include "lib/timer.h"
    4950#include "lib/sysdep/sysdep.h"
     51#include <lib/utf8.h>
    5052#include "ps/CLogger.h"
    5153#include "ps/Filesystem.h"
    5254#include "ps/Font.h"
     
    11781180    #define ELMT(x) int elmt_##x = pFile->GetElementID(#x)
    11791181    #define ATTR(x) int attr_##x = pFile->GetAttributeID(#x)
    11801182    ELMT(object);
    1181     ELMT(action);
     1183    ELMT(action);
    11821184    ELMT(repeat);
     1185    ELMT(localizableAttribute);
     1186    ELMT(localize);
     1187    ELMT(attribute);
     1188    ELMT(keep);
    11831189    ATTR(style);
    11841190    ATTR(type);
    11851191    ATTR(name);
    11861192    ATTR(hotkey);
    11871193    ATTR(z);
    1188     ATTR(on);
    1189     ATTR(file);
     1194    ATTR(on);
     1195    ATTR(file);
     1196    ATTR(id);
    11901197
    11911198    //
    11921199    //  Read Style and set defaults
     
    13271334                code = scriptfile.DecodeUTF8(); // assume it's UTF-8
    13281335            }
    13291336
    1330             // Read the inline code (concatenating to the file code, if both are specified)
    1331             code += CStr(child.GetText());
     1337            XMBElementList grandchildren = child.GetChildNodes();
     1338            if (grandchildren.Count > 0) // The <action> element contains <keep> and <localize> tags.
     1339            {
     1340                for (int i = 0; i < grandchildren.Count; ++i)
     1341                {
     1342                    XMBElement grandchild = grandchildren.Item(i);
     1343                    if (grandchild.GetNodeName() == elmt_localize)
     1344                    {
     1345                        code += Localization::getInstance().localize(grandchild.GetText());
     1346                    }
     1347                    else if (grandchild.GetNodeName() == elmt_keep)
     1348                    {
     1349                        code += grandchild.GetText();
     1350                    }
     1351                }
     1352            }
     1353            else // It’s pure JavaScript code.
     1354            {
     1355                // Read the inline code (concatenating to the file code, if both are specified)
     1356                code += CStr(child.GetText());
     1357            }
    13321358
    13331359            CStr action = CStr(child.GetAttributes().GetNamedItem(attr_on));
    13341360            object->RegisterScriptHandler(action.LowerCase(), code, this);
     
    13371363        {
    13381364            Xeromyces_ReadRepeat(child, pFile, object, Paths);
    13391365        }
     1366        else if (element_name == elmt_localizableAttribute)
     1367        {
     1368            // This is an element in the form “<localizableAttribute id="attributeName">attributeValue</localizableAttribute>”.
     1369            CStr attributeName(child.GetAttributes().GetNamedItem(attr_id)); // Read the attribute name.
     1370            if (!attributeName.empty())
     1371            {
     1372                CStr value(child.GetText());
     1373                if (!value.empty())
     1374                {
     1375                    CStr localizedValue(Localization::getInstance().localize(value));
     1376                    object->SetSetting(attributeName, localizedValue.UnescapeBackslashes().FromUTF8(), true);
     1377                }
     1378            }
     1379            else // Ignore.
     1380            {
     1381                LOGERROR(L"GUI: ‘attribute’ XML element with empty ‘id’ XML attribute found. (object: %hs)", object->GetPresentableName().c_str());
     1382            }
     1383        }
     1384        else if (element_name == elmt_attribute)
     1385        {
     1386            // This is an element in the form “<attribute id="attributeName"><keep>Don’t translate this part
     1387            // </keep><localize>but translate this one.</localize></attribute>”.
     1388            CStr attributeName(child.GetAttributes().GetNamedItem(attr_id)); // Read the attribute name.
     1389            if (!attributeName.empty())
     1390            {
     1391                CStr localizedValue;
     1392
     1393                XMBElementList grandchildren = child.GetChildNodes();
     1394                for (int i = 0; i < grandchildren.Count; ++i)
     1395                {
     1396                    XMBElement grandchild = grandchildren.Item(i);
     1397                    if (grandchild.GetNodeName() == elmt_localize)
     1398                    {
     1399                        localizedValue += Localization::getInstance().localize(grandchild.GetText());
     1400                    }
     1401                    else if (grandchild.GetNodeName() == elmt_keep)
     1402                    {
     1403                        localizedValue += grandchild.GetText();
     1404                    }
     1405                }
     1406                object->SetSetting(attributeName, localizedValue.UnescapeBackslashes().FromUTF8(), true);
     1407            }
     1408            else // Ignore.
     1409            {
     1410                LOGERROR(L"GUI: ‘attribute’ XML element with empty ‘id’ XML attribute found. (object: %hs)", object->GetPresentableName().c_str());
     1411            }
     1412        }
    13401413        else
    13411414        {
    13421415            // Try making the object read the tag.
  • source/lib/external_libraries/tinygettext.h

     
     1/* Copyright (c) 2011 Wildfire Games
     2 *
     3 * Permission is hereby granted, free of charge, to any person obtaining
     4 * a copy of this software and associated documentation files (the
     5 * "Software"), to deal in the Software without restriction, including
     6 * without limitation the rights to use, copy, modify, merge, publish,
     7 * distribute, sublicense, and/or sell copies of the Software, and to
     8 * permit persons to whom the Software is furnished to do so, subject to
     9 * the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included
     12 * in all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
     18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 */
     22
     23/*
     24 * Bring in the TinyGettext header file.
     25 */
     26
     27#ifndef INCLUDED_TINYGETTEXT
     28#define INCLUDED_TINYGETTEXT
     29
     30#include <tinygettext/tinygettext.hpp>
     31#include <tinygettext/po_parser.hpp>
     32
     33#endif  // INCLUDED_TINYGETTEXT
  • source/lib/localization.cpp

     
     1/* Copyright (c) 2013 Wildfire Games
     2 *
     3 * Permission is hereby granted, free of charge, to any person obtaining
     4 * a copy of this software and associated documentation files (the
     5 * "Software"), to deal in the Software without restriction, including
     6 * without limitation the rights to use, copy, modify, merge, publish,
     7 * distribute, sublicense, and/or sell copies of the Software, and to
     8 * permit persons to whom the Software is furnished to do so, subject to
     9 * the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included
     12 * in all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
     18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 */
     22
     23#include "lib/localization.h"
     24
     25#include <iostream>
     26#include <boost/concept_check.hpp>
     27
     28#include "lib/file/file_system.h"
     29#include "lib/utf8.h"
     30
     31#include "ps/CLogger.h"
     32#include "ps/Filesystem.h"
     33
     34
     35static std::vector<std::string> split(const std::string& target, char separator)
     36{
     37    std::vector<std::string> result;
     38
     39    std::string::size_type start = 0;
     40    while (start != std::string::npos && start < target.size())
     41    {
     42        std::string::size_type i = target.find(separator, start);
     43        if (i!=std::string::npos)
     44        {
     45            result.push_back(std::string(target,start, i-start));
     46            start = i+1;
     47        }
     48        else // End of string reached.
     49        {
     50            result.push_back(std::string(target,start));
     51            start = i;
     52        }
     53    }
     54    return result;
     55}
     56
     57Localization& Localization::getInstance()
     58{
     59    static Localization instance;
     60    return instance;
     61}
     62
     63Localization::Localization()
     64: currentLocaleIsOriginalGameLocale(false) // determineCurrentLocale() takes care of setting this value to true.
     65{
     66    loadListOfAvailableLocales();
     67    determineCurrentLocale();
     68    loadDictionaryFromCurrentLocale();
     69}
     70
     71Localization::~Localization()
     72{
     73    delete dictionary;
     74}
     75
     76std::string Localization::localize(const std::string& sourceString)
     77{
     78    if (!currentLocaleIsOriginalGameLocale)
     79    {
     80        return dictionary->translate(sourceString);
     81    }
     82    else
     83    {
     84        return sourceString;
     85    }
     86}
     87
     88void Localization::determineCurrentLocale()
     89{
     90    // LC_ALL does not work, sscanf will then not always be able
     91    // to scan for example: s=-1.1,-2.3,-3.3 correctly, which is
     92    // used in driveline files.
     93#if defined(WIN32) && !defined(__CYGWIN__)
     94    // Windows does not have LC_MESSAGES
     95    setlocale(LC_CTYPE,    "");
     96#else
     97    setlocale(LC_MESSAGES, "");
     98#endif
     99
     100//     m_dictionary_manager.add_directory( file_manager->getTranslationDir());
     101
     102    const char *p_language = getenv("LANGUAGE");
     103    std::string language;
     104
     105    if(strlen(p_language))
     106    {
     107        language = p_language;
     108    }
     109    else
     110    {
     111        const char *p_lang = getenv("LANG");
     112
     113        if (p_lang)
     114        {
     115            language = p_lang;
     116        }
     117        else
     118        {
     119#ifdef WIN32
     120            char characters[1024];
     121            GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, characters, 1024);
     122            if(characters[0])
     123            {
     124                language = characters;
     125                GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, characters, 1024);
     126                if (characters[0])
     127                {
     128                    language += std::string("_")+characters;
     129                }
     130            }
     131#endif
     132        }   // neither LANGUAGE nor LANG defined
     133
     134    }
     135
     136    if (language != "")
     137    {
     138        if (language.find(":") != std::string::npos)
     139        {
     140            std::vector<std::string> locales = split(language, ':');
     141
     142            for (unsigned int i = 0; i < locales.size(); ++i)
     143            {
     144                tinygettext::Language locale = tinygettext::Language::from_env(locales[i]);
     145                if (locale)
     146                {
     147                    for(std::set<tinygettext::Language>::iterator it = availableLocales.begin(); it != availableLocales.end(); ++it) {
     148                        if (it->get_language() == locale.get_language())
     149                        {
     150                            currentLocale = locale;
     151                            currentLocaleIsOriginalGameLocale = false;
     152                            return;
     153                        }
     154                    }
     155                }
     156            }
     157        }
     158        else
     159        {
     160            tinygettext::Language locale = tinygettext::Language::from_env(language);
     161            for(std::set<tinygettext::Language>::iterator it = availableLocales.begin(); it != availableLocales.end(); ++it) {
     162                if (it->get_language() == locale.get_language())
     163                {
     164                    currentLocale = locale;
     165                    currentLocaleIsOriginalGameLocale = false;
     166                    return;
     167                }
     168            }
     169        }
     170    }
     171
     172    currentLocale = tinygettext::Language::from_env("en");
     173    currentLocaleIsOriginalGameLocale = true;
     174}
     175
     176void Localization::loadDictionaryFromCurrentLocale()
     177{
     178    if (!currentLocaleIsOriginalGameLocale)
     179    {
     180        delete dictionary;
     181        dictionary = new tinygettext::Dictionary();
     182
     183        VfsPaths filenames;
     184        if (vfs::GetPathnames(g_VFS, L"po/", (wstring_from_utf8(currentLocale.get_language()) + L".*.po").c_str(), filenames) < 0)
     185            return;
     186
     187        for (VfsPaths::iterator it = filenames.begin(); it != filenames.end(); ++it)
     188        {
     189            VfsPath filename = *it;
     190            CVFSFile file;
     191            file.Load(g_VFS, filename);
     192            std::string content = file.DecodeUTF8();
     193            readPoIntoDictionary(content, dictionary);
     194        }
     195    }
     196}
     197
     198void Localization::loadListOfAvailableLocales()
     199{
     200    availableLocales.clear();
     201    availableLocales.insert(tinygettext::Language::from_env("en")); // Always available.
     202
     203    VfsPaths filenames;
     204    if (vfs::GetPathnames(g_VFS, L"po/", L"*.po", filenames) < 0)
     205        return;
     206
     207    for (VfsPaths::iterator it = filenames.begin(); it != filenames.end(); ++it)
     208    {
     209        // Note: PO files follow this naming convention: “po/<language code>.<mod name>.po”. For example: “po/gl.public.po”.
     210        VfsPath filepath = *it;
     211        std::string filename = utf8_from_wstring(filepath.string()).substr(3);
     212        std::size_t lengthToFirstDot = filename.find('.');
     213        std::string localeCode = filename.substr(0, lengthToFirstDot);
     214        tinygettext::Language locale = tinygettext::Language::from_env(localeCode);
     215        availableLocales.insert(locale);
     216    }
     217}
     218
     219void Localization::readPoIntoDictionary(const std::string& poContent, tinygettext::Dictionary* dictionary)
     220{
     221    try
     222    {
     223        std::istringstream inputStream(poContent);
     224        tinygettext::POParser::parse("virtual PO file", inputStream, *dictionary);
     225    }
     226    catch(std::exception& e)
     227    {
     228        LOGERROR(L"[Localization] Exception while reading virtual PO file");
     229    }
     230}
     231 No newline at end of file
  • source/lib/localization.h

     
     1/* Copyright (c) 2013 Wildfire Games
     2 *
     3 * Permission is hereby granted, free of charge, to any person obtaining
     4 * a copy of this software and associated documentation files (the
     5 * "Software"), to deal in the Software without restriction, including
     6 * without limitation the rights to use, copy, modify, merge, publish,
     7 * distribute, sublicense, and/or sell copies of the Software, and to
     8 * permit persons to whom the Software is furnished to do so, subject to
     9 * the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included
     12 * in all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
     18 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     19 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 */
     22
     23#ifndef LOCALIZATION_H
     24#define LOCALIZATION_H
     25
     26#include <string>
     27#include <set>
     28
     29#include "lib/external_libraries/tinygettext.h"
     30
     31#include "lib/os_path.h"
     32
     33class Localization
     34{
     35public:
     36
     37    static Localization& getInstance();
     38
     39    Localization();
     40    Localization(Localization const&); // Don’t implement.
     41    void operator=(Localization const&); // Don’t implement.
     42    ~Localization();
     43
     44    std::string localize(const std::string& sourceString);
     45
     46//  bool               isRTLLanguage() const;
     47
     48//  std::string        getCurrentLanguageName();
     49
     50private:
     51    tinygettext::Dictionary* dictionary;
     52    bool isRtlLanguage;
     53    tinygettext::Language currentLocale;
     54    std::set<tinygettext::Language> availableLocales;
     55    bool currentLocaleIsOriginalGameLocale;
     56
     57
     58    void determineCurrentLocale();
     59    void loadDictionaryFromCurrentLocale();
     60    void loadListOfAvailableLocales();
     61
     62    void readPoIntoDictionary(const std::string& poContent, tinygettext::Dictionary* dictionary);
     63};
     64
     65
     66extern Localization* localization;
     67
     68#endif // LOCALIZATION_H