diff options
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/base64.cpp | 4 | ||||
-rw-r--r-- | src/utils/langs.cpp | 87 | ||||
-rw-r--r-- | src/utils/langs.h | 41 | ||||
-rw-r--r-- | src/utils/paths.cpp | 22 | ||||
-rw-r--r-- | src/utils/paths.h | 4 | ||||
-rw-r--r-- | src/utils/physfsrwops.h | 1 | ||||
-rw-r--r-- | src/utils/process.cpp | 2 | ||||
-rw-r--r-- | src/utils/stringutils.cpp | 127 | ||||
-rw-r--r-- | src/utils/stringutils.h | 12 | ||||
-rw-r--r-- | src/utils/stringutils_unittest.cc | 517 | ||||
-rw-r--r-- | src/utils/translation/podict.cpp | 55 | ||||
-rw-r--r-- | src/utils/translation/podict.h | 59 | ||||
-rw-r--r-- | src/utils/translation/poparser.cpp | 221 | ||||
-rw-r--r-- | src/utils/translation/poparser.h | 78 | ||||
-rw-r--r-- | src/utils/translation/translationmanager.cpp | 78 | ||||
-rw-r--r-- | src/utils/translation/translationmanager.h | 41 | ||||
-rw-r--r-- | src/utils/xml.cpp | 12 | ||||
-rw-r--r-- | src/utils/xml.h | 6 |
18 files changed, 1274 insertions, 93 deletions
diff --git a/src/utils/base64.cpp b/src/utils/base64.cpp index 24a3a58e3..cd7d59cdb 100644 --- a/src/utils/base64.cpp +++ b/src/utils/base64.cpp @@ -125,7 +125,7 @@ unsigned char *php3_base64_decode(const unsigned char *string, continue; ch = static_cast<int>(chp - base64_table); - switch(i % 4) + switch (i % 4) { case 0: result[j] = ch << 2; @@ -151,7 +151,7 @@ unsigned char *php3_base64_decode(const unsigned char *string, /* mop things up if we ended on a boundary */ if (ch == base64_pad) { - switch(i % 4) + switch (i % 4) { case 0: case 1: diff --git a/src/utils/langs.cpp b/src/utils/langs.cpp new file mode 100644 index 000000000..2efbd781a --- /dev/null +++ b/src/utils/langs.cpp @@ -0,0 +1,87 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011-2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/langs.h" + +#include "configuration.h" + +#include <string.h> +#include <algorithm> +#include <cstdarg> +#include <cstdio> +#include <list> + +#include "debug.h" + +std::vector<std::string> getLang() +{ + std::vector<std::string> langs; + + std::string lang = config.getValue("lang", "").c_str(); + if (lang.empty()) + { + char *lng = getenv("LANG"); + if (!lng) + return langs; + lang = lng; + } + + int dot = lang.find("."); + if (dot != (signed)std::string::npos) + lang = lang.substr(0, dot); + langs.push_back(lang); + dot = lang.find("_"); + if (dot != (signed)std::string::npos) + langs.push_back(lang.substr(0, dot)); + return langs; +} + +std::string getLangSimple() +{ + std::string lang = config.getValue("lang", "").c_str(); + if (lang.empty()) + { + char *lng = getenv("LANG"); + if (!lng) + return ""; + return lng; + } + return lang; +} + +std::string getLangShort() +{ + std::string lang = config.getValue("lang", "").c_str(); + if (lang.empty()) + { + char *lng = getenv("LANG"); + if (!lng) + return ""; + lang = lng; + } + + int dot = lang.find("."); + if (dot != (signed)std::string::npos) + lang = lang.substr(0, dot); + dot = lang.find("_"); + if (dot != (signed)std::string::npos) + return lang.substr(0, dot); + return lang; +} diff --git a/src/utils/langs.h b/src/utils/langs.h new file mode 100644 index 000000000..3b9f49f71 --- /dev/null +++ b/src/utils/langs.h @@ -0,0 +1,41 @@ +/* + * The ManaPlus Client + * Copyright (C) 2007-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UTILS_LANGS_H +#define UTILS_LANGS_H + +#include <string> +#include <sstream> +#include <list> +#include <set> +#include <vector> + +typedef std::vector<std::string> LangVect; +typedef LangVect::const_iterator LangIter; + +std::vector<std::string> getLang(); + +std::string getLangSimple(); + +std::string getLangShort(); + +#endif // UTILS_LANGS_H diff --git a/src/utils/paths.cpp b/src/utils/paths.cpp index 8decb6e95..04f553ca9 100644 --- a/src/utils/paths.cpp +++ b/src/utils/paths.cpp @@ -20,10 +20,12 @@ #include "utils/paths.h" +#include "utils/stringutils.h" + #include <string.h> #include <cstdarg> #include <cstdio> - +#include <physfs.h> #include <stdlib.h> #ifdef WIN32 @@ -55,3 +57,21 @@ bool isRealPath(const std::string &str) std::string path = getRealPath(str); return str == path; } + +bool checkPath(std::string path) +{ + if (path.empty()) + return true; + return path.find("../") == std::string::npos + && path.find("..\\") == std::string::npos + && path.find("/..") == std::string::npos + && path.find("\\..") == std::string::npos; +} + +std::string &fixDirSeparators(std::string &str) +{ + if (*PHYSFS_getDirSeparator() == '/') + return str; + + return replaceAll(str, "/", "\\"); +} diff --git a/src/utils/paths.h b/src/utils/paths.h index 804900587..b89671adc 100644 --- a/src/utils/paths.h +++ b/src/utils/paths.h @@ -27,4 +27,8 @@ std::string getRealPath(const std::string &str); bool isRealPath(const std::string &str); +bool checkPath(std::string path); + +std::string &fixDirSeparators(std::string &str); + #endif // UTILS_PATHS_H diff --git a/src/utils/physfsrwops.h b/src/utils/physfsrwops.h index efa004ac6..1f52f40aa 100644 --- a/src/utils/physfsrwops.h +++ b/src/utils/physfsrwops.h @@ -79,4 +79,3 @@ SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle); #endif /* include-once blocker */ /* end of physfsrwops.h ... */ - diff --git a/src/utils/process.cpp b/src/utils/process.cpp index 4a2081514..fd0ec0fa8 100644 --- a/src/utils/process.cpp +++ b/src/utils/process.cpp @@ -130,7 +130,7 @@ int execFile(std::string pathName, std::string name, } else if (!sleep_pid) { // sleep pid - sleep (timeOut); + sleep (waitTime); // printf ("time out\n"); exit(-1); } diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp index 08bcac9e6..2f478a909 100644 --- a/src/utils/stringutils.cpp +++ b/src/utils/stringutils.cpp @@ -22,14 +22,14 @@ #include "utils/stringutils.h" -#include "configuration.h" - #include <string.h> #include <algorithm> #include <cstdarg> #include <cstdio> #include <list> +#include <sys/time.h> + #include "debug.h" static int UTF8_MAX_SIZE = 10; @@ -107,6 +107,7 @@ std::string strprintf(char const *format, ...) return res; } +/* std::string &removeBadChars(std::string &str) { std::string::size_type pos; @@ -120,6 +121,7 @@ std::string &removeBadChars(std::string &str) return str; } +*/ std::string removeColors(std::string msg) { @@ -318,27 +320,37 @@ void getSafeUtf8String(std::string text, char *buf) std::string getFileName(std::string path) { - size_t pos = path.rfind("/"); - if (pos == std::string::npos) - pos = path.rfind("\\"); - if (pos == std::string::npos) + size_t pos1 = path.rfind("/"); + size_t pos2 = path.rfind("\\"); + if (pos1 == std::string::npos) + pos1 = pos2; + else if (pos2 != std::string::npos && pos2 > pos1) + pos1 = pos2; + + if (pos1 == std::string::npos) return path; - return path.substr(pos + 1); + return path.substr(pos1 + 1); } std::string getFileDir(std::string path) { - size_t pos = path.rfind("/"); - if (pos == std::string::npos) - pos = path.rfind("\\"); - if (pos == std::string::npos) - return ""; - return path.substr(0, pos); + size_t pos1 = path.rfind("/"); + size_t pos2 = path.rfind("\\"); + if (pos1 == std::string::npos) + pos1 = pos2; + else if (pos2 != std::string::npos && pos2 > pos1) + pos1 = pos2; + + if (pos1 == std::string::npos) + return path; + return path.substr(0, pos1); } std::string& replaceAll(std::string& context, const std::string& from, const std::string& to) { + if (from.empty()) + return context; size_t lookHere = 0; size_t foundHere; while ((foundHere = context.find(from, lookHere)) != std::string::npos) @@ -405,7 +417,7 @@ std::set<int> splitToIntSet(const std::string &text, char separator) std::set<int> tokens; std::stringstream ss(text); std::string item; - while(std::getline(ss, item, separator)) + while (std::getline(ss, item, separator)) tokens.insert(atoi(item.c_str())); return tokens; @@ -416,7 +428,7 @@ std::list<int> splitToIntList(const std::string &text, char separator) std::list<int> tokens; std::stringstream ss(text); std::string item; - while(std::getline(ss, item, separator)) + while (std::getline(ss, item, separator)) tokens.push_back(atoi(item.c_str())); return tokens; @@ -429,7 +441,7 @@ std::list<std::string> splitToStringList(const std::string &text, std::list<std::string> tokens; std::stringstream ss(text); std::string item; - while(std::getline(ss, item, separator)) + while (std::getline(ss, item, separator)) tokens.push_back(item); return tokens; @@ -440,7 +452,7 @@ void splitToStringVector(std::vector<std::string> &tokens, { std::stringstream ss(text); std::string item; - while(std::getline(ss, item, separator)) + while (std::getline(ss, item, separator)) { item = trim(item); if (!item.empty()) @@ -486,62 +498,6 @@ std::string combineDye2(std::string file, std::string dye) } } -std::vector<std::string> getLang() -{ - std::vector<std::string> langs; - - std::string lang = config.getValue("lang", "").c_str(); - if (lang.empty()) - { - char *lng = getenv("LANG"); - if (!lng) - return langs; - lang = lng; - } - - int dot = lang.find("."); - if (dot != (signed)std::string::npos) - lang = lang.substr(0, dot); - langs.push_back(lang); - dot = lang.find("_"); - if (dot != (signed)std::string::npos) - langs.push_back(lang.substr(0, dot)); - return langs; -} - -std::string getLangSimple() -{ - std::string lang = config.getValue("lang", "").c_str(); - if (lang.empty()) - { - char *lng = getenv("LANG"); - if (!lng) - return ""; - return lng; - } - return lang; -} - -std::string getLangShort() -{ - std::string lang = config.getValue("lang", "").c_str(); - if (lang.empty()) - { - char *lng = getenv("LANG"); - if (!lng) - return ""; - lang = lng; - } - - int dot = lang.find("."); - if (dot != (signed)std::string::npos) - lang = lang.substr(0, dot); - dot = lang.find("_"); - if (dot != (signed)std::string::npos) - return lang.substr(0, dot); - return lang; -} - std::string packList(std::list<std::string> &list) { std::list<std::string>::const_iterator i = list.begin(); @@ -649,12 +605,23 @@ std::string &removeProtocol(std::string &url) return url; } -bool checkPath(std::string path) +bool strStartWith(std::string str1, std::string str2) { - if (path.empty()) - return true; - return path.find("../") == std::string::npos - && path.find("..\\") == std::string::npos - && path.find("/..") == std::string::npos - && path.find("\\..") == std::string::npos; + if (str1.size() < str2.size()) + return false; + return str1.substr(0, str2.size()) == str2; +} + +std::string getDateString() +{ + char buffer[80]; + + time_t rawtime; + struct tm *timeinfo; + + time (&rawtime); + timeinfo = localtime(&rawtime); + + strftime(buffer, 79, "%Y-%m-%d", timeinfo); + return std::string(buffer); } diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h index 0b22ef847..31ee6d51f 100644 --- a/src/utils/stringutils.h +++ b/src/utils/stringutils.h @@ -103,7 +103,7 @@ std::string strprintf(char const *, ...) * @param str the string to remove the bad chars from * @return a reference to the string without bad chars */ -std::string &removeBadChars(std::string &str); +//std::string &removeBadChars(std::string &str); /** * Removes colors from a string @@ -186,12 +186,6 @@ std::string combineDye(std::string file, std::string dye); std::string combineDye2(std::string file, std::string dye); -std::vector<std::string> getLang(); - -std::string getLangSimple(); - -std::string getLangShort(); - std::string packList(std::list<std::string> &list); std::list<std::string> unpackList(const std::string &str); @@ -210,6 +204,8 @@ bool findCutFirst(std::string &str1, std::string str2); std::string &removeProtocol(std::string &url); -bool checkPath(std::string path); +bool strStartWith(std::string str, std::string start); + +std::string getDateString(); #endif // UTILS_STRINGUTILS_H diff --git a/src/utils/stringutils_unittest.cc b/src/utils/stringutils_unittest.cc new file mode 100644 index 000000000..81030631a --- /dev/null +++ b/src/utils/stringutils_unittest.cc @@ -0,0 +1,517 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/stringutils.h" + +#include "gtest/gtest.h" + +#include <list> +#include <string> +#include <vector> + +#include "debug.h" + +TEST(stringuntils, trim1) +{ + std::string str = "str"; + EXPECT_EQ("str", trim(str)); + + str = " str"; + EXPECT_EQ("str", trim(str)); + EXPECT_EQ("str", trim(str)); + + str = " str this IS Long Стринг " + "~!@#$%^&*()_+`-=[]\\{}|;':\",./<>? "; + EXPECT_EQ("str this IS Long Стринг ~!@#$%^&*()_+`-=[]\\{}|;':\",./<>?", + trim(str)); + + str = ""; + EXPECT_EQ("", trim(str)); +} + +TEST(stringuntils, toLower1) +{ + std::string str = "str"; + EXPECT_EQ("str", toLower(str)); + + str = " StR"; + EXPECT_EQ(" str", toLower(str)); + + str = " str this IS Long " + "~!@#$%^&*()_+`-=[]\\{}|;':\",./<>? "; + + EXPECT_EQ(" str this is long ~!@#$%^&*()_+`-=[]\\{}|;':\",./<>? ", + toLower(str)); + + str = ""; + EXPECT_EQ("", toLower(str)); +} + +TEST(stringuntils, toUpper1) +{ + std::string str = "str"; + EXPECT_EQ("STR", toUpper(str)); + + str = " StR"; + EXPECT_EQ(" STR", toUpper(str)); + + str = " str this IS Long " + "~!@#$%^&*()_+`-=[]\\{}|;':,./<>? "; + + EXPECT_EQ(" STR THIS IS LONG ~!@#$%^&*()_+`-=[]\\{}|;':,./<>? ", + toUpper(str)); + + str = ""; + EXPECT_EQ("", toUpper(str)); +} + +TEST(stringuntils, atox1) +{ + std::string str = "0x10"; + EXPECT_EQ(16, atox(str)); + + str = "0x0"; + EXPECT_EQ(0, atox(str)); + + str = "0x1"; + EXPECT_EQ(1, atox(str)); + + str = "0x0x0x0x0x0x0x0"; + EXPECT_EQ(0, atox(str)); + + str = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + atox(str); + + str = ""; + int k = atox(str); + + str = "0"; + k = atox(str); + + str = "0x"; + k = atox(str); +} + +TEST(stringuntils, ipToString1) +{ + EXPECT_EQ("0.0.0.0", std::string(ipToString(0))); + EXPECT_EQ("219.255.210.73", std::string(ipToString(1238564827))); +} + +TEST(stringuntils, removeColors1) +{ + EXPECT_EQ("", removeColors("")); + EXPECT_EQ("#", removeColors("#")); + EXPECT_EQ("##", removeColors("##")); + EXPECT_EQ("", removeColors("##1")); + EXPECT_EQ("2", removeColors("##12")); + EXPECT_EQ("1##", removeColors("1##")); + EXPECT_EQ("1", removeColors("1##2")); + EXPECT_EQ("13", removeColors("1##23")); + EXPECT_EQ("#1#2", removeColors("#1#2")); + EXPECT_EQ("#1", removeColors("#1##2")); +} + +TEST(stringuntils, compareStrI1) +{ + std::string str1 = ""; + std::string str2 = ""; + EXPECT_TRUE(compareStrI(str1, str2) == 0); + + str1 = "test"; + str2 = "test"; + EXPECT_TRUE(compareStrI(str1, str2) == 0); + + str1 = "test"; + str2 = "test1"; + EXPECT_TRUE(compareStrI(str1, str2) < 0); + + str1 = "test"; + str2 = "aest1"; + EXPECT_TRUE(compareStrI(str1, str2) > 0); +} + +TEST(stringuntils, isWordSeparator1) +{ + EXPECT_TRUE(isWordSeparator(' ')); + EXPECT_TRUE(isWordSeparator(',')); + EXPECT_TRUE(isWordSeparator('.')); + EXPECT_TRUE(isWordSeparator('\"')); + EXPECT_TRUE(!isWordSeparator(0)); + EXPECT_TRUE(!isWordSeparator('a')); + EXPECT_TRUE(!isWordSeparator('-')); +} + +TEST(stringuntils, findSameSubstring) +{ + std::string str1 = ""; + std::string str2 = ""; + + EXPECT_EQ("", findSameSubstring("", "")); + + str1 = "test line"; + str2 = "test line"; + EXPECT_EQ("test line", findSameSubstring(str1, str2)); + + str1 = "test li"; + str2 = "test line"; + EXPECT_EQ("test li", findSameSubstring(str1, str2)); + + str1 = "test li"; + str2 = "est li"; + EXPECT_EQ("", findSameSubstring(str1, str2)); +} + +TEST(stringuntils, findSameSubstringI) +{ + std::string str1 = ""; + std::string str2 = ""; + + EXPECT_EQ("", findSameSubstringI("", "")); + + str1 = "tEst line"; + str2 = "tesT line"; + EXPECT_EQ("tEst line", findSameSubstringI(str1, str2)); + + str1 = "test Li"; + str2 = "test lINe"; + EXPECT_EQ("test Li", findSameSubstringI(str1, str2)); + + str1 = "teSt li"; + str2 = "est li"; + EXPECT_EQ("", findSameSubstringI(str1, str2)); +} + +TEST(stringuntils, findI1) +{ + EXPECT_EQ(0, findI("", "")); + EXPECT_EQ(std::string::npos, findI("test", "line")); + EXPECT_EQ(0, findI("test line", "t")); + EXPECT_EQ(0, findI("test line", "te")); + EXPECT_EQ(3, findI("test line", "t l")); +} + +TEST(stringuntils, findI2) +{ + std::vector <std::string> vect1; + vect1.push_back("test"); + vect1.push_back("line"); + vect1.push_back("qwe"); + + EXPECT_EQ(std::string::npos, findI("", vect1)); + EXPECT_EQ(0, findI("test", vect1)); + EXPECT_EQ(0, findI("tesT lIne", vect1)); + EXPECT_EQ(5, findI("teoT line", vect1)); + EXPECT_EQ(std::string::npos, findI("zzz", vect1)); +} + +TEST(stringuntils, encodeStr1) +{ + std::string str = encodeStr(10, 1); + EXPECT_EQ(10, decodeStr(str)); + + str = encodeStr(10, 2); + EXPECT_EQ(10, decodeStr(str)); + + str = encodeStr(100, 3); + EXPECT_EQ(100, decodeStr(str)); + + str = encodeStr(1000, 4); + EXPECT_EQ(1000, decodeStr(str)); +} + +TEST(stringuntils, extractNameFromSprite1) +{ + EXPECT_EQ("", extractNameFromSprite("")); + EXPECT_EQ("test", extractNameFromSprite("test")); + EXPECT_EQ("test", extractNameFromSprite("test.qwe")); + EXPECT_EQ("line", extractNameFromSprite("test/line.zzz")); +} + +TEST(stringuntils, removeSpriteIndex1) +{ + EXPECT_EQ("", removeSpriteIndex("")); + EXPECT_EQ("test", removeSpriteIndex("test")); + EXPECT_EQ("test", removeSpriteIndex("test[1]")); + EXPECT_EQ("line", removeSpriteIndex("test/line[12]")); +} + +TEST(stringuntils, getFileName1) +{ + EXPECT_EQ("", getFileName("")); + EXPECT_EQ("file", getFileName("file")); + EXPECT_EQ("file", getFileName("test/file1\\file")); + EXPECT_EQ("file", getFileName("test\\file1/file")); + EXPECT_EQ("", getFileName("file/")); + EXPECT_EQ("file", getFileName("/file")); +} + +TEST(stringuntils, getFileDir1) +{ + EXPECT_EQ("", getFileDir("")); + EXPECT_EQ("file", getFileDir("file")); + EXPECT_EQ("test/file1", getFileDir("test/file1\\file")); + EXPECT_EQ("test\\file1", getFileDir("test\\file1/file")); + EXPECT_EQ("file", getFileDir("file/")); + EXPECT_EQ("", getFileDir("/file")); +} + +TEST(stringuntils, replaceAll1) +{ + std::string str1 = ""; + std::string str2 = ""; + std::string str3 = ""; + + EXPECT_EQ("", replaceAll(str1, str2, str3)); + + str1 = "this is test line"; + str2 = ""; + str3 = ""; + EXPECT_EQ("this is test line", replaceAll(str1, str2, str3)); + + str1 = "this is test line"; + str2 = "is "; + str3 = ""; + EXPECT_EQ("thtest line", replaceAll(str1, str2, str3)); + + str1 = "this is test line"; + str2 = ""; + str3 = "1"; + EXPECT_EQ("this is test line", replaceAll(str1, str2, str3)); +} + +TEST(stringuntils, getBoolFromString1) +{ + EXPECT_TRUE(getBoolFromString("true")); + EXPECT_TRUE(!getBoolFromString("false")); + EXPECT_TRUE(getBoolFromString("1")); + EXPECT_TRUE(!getBoolFromString("0")); +} + +TEST(stringuntils, replaceSpecialChars1) +{ + std::string str; + + str = ""; + replaceSpecialChars(str); + EXPECT_EQ("", str); + + str = "test"; + replaceSpecialChars(str); + EXPECT_EQ("test", str); + + str = "&"; + replaceSpecialChars(str); + EXPECT_EQ("&", str); + + str = "&1"; + replaceSpecialChars(str); + EXPECT_EQ("&1", str); + + str = "&33"; + replaceSpecialChars(str); + EXPECT_EQ("&33", str); + + str = "&33;"; + replaceSpecialChars(str); + EXPECT_EQ("!", str); + + str = "1&33;"; + replaceSpecialChars(str); + EXPECT_EQ("1!", str); + + str = "&33;2"; + replaceSpecialChars(str); + EXPECT_EQ("!2", str); + + str = "&33;&"; + replaceSpecialChars(str); + EXPECT_EQ("!&", str); + + str = "test line&33;"; + replaceSpecialChars(str); + EXPECT_EQ("test line!", str); +} + +TEST(stringuntils, combineDye1) +{ + EXPECT_EQ("", combineDye("", "")); + EXPECT_EQ("test", combineDye("test", "")); + EXPECT_EQ("|line", combineDye("", "line")); + EXPECT_EQ("test|line", combineDye("test", "line")); +} + +TEST(stringuntils, combineDye2) +{ + EXPECT_EQ("", combineDye2("", "")); + EXPECT_EQ("test", combineDye2("test", "")); + EXPECT_EQ("", combineDye2("", "line")); + EXPECT_EQ("test.xml", combineDye2("test.xml", "123")); + EXPECT_EQ("test.xml|#43413d,59544f,7a706c", + combineDye2("test.xml|#43413d,59544f,7a706c", "")); + EXPECT_EQ("test.xml|#43413d,59544f,7a706c:W;", + combineDye2("test.xml|#43413d,59544f,7a706c", "W")); + EXPECT_EQ("test.xml|#43413d,59544f,7a706c:W;#123456:B;", + combineDye2("test.xml|#43413d,59544f,7a706c;#123456", "W;B")); +} + +TEST(stringuntils, packList1) +{ + std::list <std::string> list; + EXPECT_EQ("", packList(list)); + + list.push_back(""); + EXPECT_EQ("|", packList(list)); + + list.clear(); + list.push_back("test"); + EXPECT_EQ("test", packList(list)); + + list.push_back("line"); + EXPECT_EQ("test|line", packList(list)); + + list.push_back("2"); + EXPECT_EQ("test|line|2", packList(list)); +} + +TEST(stringuntils, stringToHexPath1) +{ + std::string str; + + str = ""; + EXPECT_EQ("", stringToHexPath(str)); + + str = "a"; + EXPECT_EQ("%61/", stringToHexPath(str)); + + str = "ab"; + EXPECT_EQ("%61/%62", stringToHexPath(str)); + + str = "abc"; + EXPECT_EQ("%61/%62%63", stringToHexPath(str)); + + str = "abcd"; + EXPECT_EQ("%61/%62%63%64", stringToHexPath(str)); +} + +TEST(stringuntils, deleteCharLeft1) +{ + std::string str; + unsigned int pos = 0; + + str = ""; + deleteCharLeft(str, nullptr); + EXPECT_EQ("", str); + + str = "test line"; + pos = 4; + deleteCharLeft(str, &pos); + EXPECT_EQ("tes line", str); + + str = "тест line"; + pos = 8; + deleteCharLeft(str, &pos); + EXPECT_EQ("тес line", str); +} + +TEST(stringuntils, findLast1) +{ + std::string str; + + str = ""; + EXPECT_TRUE(findLast(str, "")); + + str = "test line"; + EXPECT_TRUE(findLast(str, "line")); + + str = "test line"; + EXPECT_TRUE(!findLast(str, "lin")); +} + +TEST(stringuntils, findFirst1) +{ + std::string str; + + str = ""; + EXPECT_TRUE(findFirst(str, "")); + + str = "test line"; + EXPECT_TRUE(findFirst(str, "test")); + + str = "test line"; + EXPECT_TRUE(!findFirst(str, "est")); +} + +TEST(stringuntils, findCutLast1) +{ + std::string str; + + str = ""; + EXPECT_TRUE(findCutLast(str, "")); + EXPECT_EQ("", str); + + str = "test line"; + EXPECT_TRUE(findCutLast(str, "line")); + EXPECT_EQ("test ", str); + + str = "test line"; + EXPECT_TRUE(!findCutLast(str, "lin")); + EXPECT_EQ("test line", str); +} + +TEST(stringuntils, findCutFirst1) +{ + std::string str; + + str = ""; + EXPECT_TRUE(findCutFirst(str, "")); + EXPECT_EQ("", str); + + str = "test line"; + EXPECT_TRUE(findCutFirst(str, "test")); + EXPECT_EQ(" line", str); + + str = "test line"; + EXPECT_TRUE(!findCutFirst(str, "est")); + EXPECT_EQ("test line", str); +} + +TEST(stringuntils, removeProtocol1) +{ + std::string str; + + str = ""; + EXPECT_EQ("", removeProtocol(str)); + + str = "http://"; + EXPECT_EQ("", removeProtocol(str)); + + str = "http://test"; + EXPECT_EQ("test", removeProtocol(str)); +} + +TEST(stringuntils, strStartWith1) +{ + EXPECT_TRUE(strStartWith("", "")); + EXPECT_TRUE(!strStartWith("", "1")); + EXPECT_TRUE(strStartWith("test line", "test")); + EXPECT_TRUE(strStartWith("test line", "test line")); + EXPECT_TRUE(!strStartWith("test line", "est")); +} diff --git a/src/utils/translation/podict.cpp b/src/utils/translation/podict.cpp new file mode 100644 index 000000000..0be0b279f --- /dev/null +++ b/src/utils/translation/podict.cpp @@ -0,0 +1,55 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/translation/podict.h" + +#include <string.h> + +#include "localconsts.h" +#include "logger.h" + +#include "debug.h" + +std::string empty; + +PoDict *translator = nullptr; + +PoDict::PoDict(std::string lang) : + mLang(lang) +{ +} + +PoDict::~PoDict() +{ +} + +const std::string PoDict::getStr(std::string &str) +{ + if (mPoLines.find(str) == mPoLines.end()) + return str; + return mPoLines[str]; +} + +const char *PoDict::getChar(const char *str) +{ + if (mPoLines.find(str) == mPoLines.end()) + return str; + return mPoLines[str].c_str(); +} diff --git a/src/utils/translation/podict.h b/src/utils/translation/podict.h new file mode 100644 index 000000000..0b7dd726c --- /dev/null +++ b/src/utils/translation/podict.h @@ -0,0 +1,59 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UTILS_TRANSLATION_PODICT_H +#define UTILS_TRANSLATION_PODICT_H + +#include <string> +#include <map> + +typedef std::map <std::string, std::string> PoMap; + +class PoDict +{ + public: + PoDict(std::string lang); + + ~PoDict(); + + const std::string getStr(std::string &str); + + const char *getChar(const char *str); + + protected: + friend class PoParser; + + PoMap *getMap() + { return &mPoLines; } + + void set(std::string key, std::string value) + { mPoLines[key] = value; } + + void setLang(std::string lang) + { mLang = lang; } + + private: + PoMap mPoLines; + std::string mLang; +}; + +extern PoDict *translator; + +#endif // UTILS_TRANSLATION_PODICT_H diff --git a/src/utils/translation/poparser.cpp b/src/utils/translation/poparser.cpp new file mode 100644 index 000000000..24d2ee4d4 --- /dev/null +++ b/src/utils/translation/poparser.cpp @@ -0,0 +1,221 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/translation/poparser.h" + +#include "resources/resourcemanager.h" + +#include "utils/stringutils.h" + +#include "localconsts.h" +#include "logger.h" + +#include <string.h> +#include <stdlib.h> + +#include "debug.h" + +PoParser::PoParser() : + mDict(nullptr), + mReadingId(false), + mReadingStr(false) +{ +} + +void PoParser::openFile() +{ + ResourceManager *resman = ResourceManager::getInstance(); + int size; + char *buf = static_cast<char*>(resman->loadFile(getFileName(mLang), size)); + + mFile.str(std::string(buf, size)); + free(buf); +} + +PoDict *PoParser::load(std::string lang) +{ + setLang(lang); + mDict = getDict(); + + openFile(); + + mMsgId = ""; + mMsgStr = ""; + + // cycle by msgid+msgstr + while (readLine()) + { + // reading msgid + while (readMsgId()) + { + if (!readLine()) + break; + } + + if (!mMsgId.empty()) + { + // if we got msgid then reading msgstr + while (readMsgStr()) + { + if (!readLine()) + break; + } + } + + if (!mMsgId.empty() && !mMsgStr.empty()) + { +// logger->log("add key: " + mMsgId); +// logger->log("add value: " + mMsgStr); + + // store key and value + mDict->set(mMsgId, mMsgStr); + } + + mMsgId = ""; + mMsgStr = ""; + } + + return mDict; +} + +bool PoParser::readLine() +{ + char line[1001]; + if (!mFile.getline(line, 1000)) + return false; + mLine = line; + return true; +} + +bool PoParser::readMsgId() +{ + // if we reading msgstr then stop here + if (mReadingStr) + return false; + + const std::string msgId1 = "msgid \""; + + // check if in reading process + if (mReadingId) + { + // if we get empty line in file then stop reading + if (mLine.empty()) + { + mReadingId = false; + return false; + } + else if (checkLine()) + { + // reading text from: "text" + mMsgId += mLine.substr(1, mLine.size() - 2); + mLine = ""; + return true; + } + // stop reading in other case + mReadingId = false; + return false; + } + else + { + // check line start from msgid " + if (strStartWith(mLine, msgId1)) + { + mReadingId = true; + // reading text from: msgid "text" + mMsgId += mLine.substr(msgId1.size(), + mLine.size() - 1 - msgId1.size()); + mLine = ""; + return true; + } + // stop reading if we dont read msgid before + return mMsgId.empty(); + } +} + +bool PoParser::readMsgStr() +{ + const std::string msgStr1 = "msgstr \""; + + // check if in reading process + if (mReadingStr) + { + // if we get empty line in file then stop reading + if (mLine.empty()) + { + mReadingStr = false; + return false; + } + if (checkLine()) + { + // reading text from: "text" + mMsgStr += mLine.substr(1, mLine.size() - 2); + mLine = ""; + return true; + } + // stop reading in other case + mReadingStr = false; + } + else + { + // check line start from msgstr " + if (strStartWith(mLine, msgStr1)) + { + mReadingStr = true; + // reading text from: msgid "text" + mMsgStr += mLine.substr(msgStr1.size(), + mLine.size() - 1 - msgStr1.size()); + mLine = ""; + return true; + } + } + + // stop reading in other case + return false; +} + +bool PoParser::checkLine() +{ + // check is line in format: "text" + return mLine.size() > 2 && mLine[0] == '\"' + && mLine[mLine.size() - 1] == '\"'; +} + +PoDict *PoParser::getEmptyDict() +{ + return new PoDict(""); +} + +bool PoParser::checkLang(std::string lang) const +{ + // check is po file exists + ResourceManager *resman = ResourceManager::getInstance(); + return resman->exists(getFileName(lang)); +} + +std::string PoParser::getFileName(std::string lang) const +{ + // get po file name from lang name + return strprintf("translations/%s.po", lang.c_str()); +} + +PoDict *PoParser::getDict() +{ + return new PoDict(mLang); +} diff --git a/src/utils/translation/poparser.h b/src/utils/translation/poparser.h new file mode 100644 index 000000000..799cd2fe7 --- /dev/null +++ b/src/utils/translation/poparser.h @@ -0,0 +1,78 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UTILS_TRANSLATION_POPARSER_H +#define UTILS_TRANSLATION_POPARSER_H + +#include "utils/translation/podict.h" + +#include <sstream> +#include <string> + +class PoParser +{ + public: + PoParser(); + + PoDict *load(std::string fileName); + + bool checkLang(std::string lang) const; + + static PoDict *getEmptyDict(); + + private: + void setLang(std::string lang) + { mLang = lang; } + + void openFile(); + + bool readLine(); + + bool readMsgId(); + + bool readMsgStr(); + + bool checkLine(); + + std::string getFileName(std::string lang) const; + + PoDict *getDict(); + + // current lang + std::string mLang; + + // po file object + std::istringstream mFile; + + // current line from po file + std::string mLine; + + std::string mMsgId; + + std::string mMsgStr; + + PoDict *mDict; + + bool mReadingId; + + bool mReadingStr; +}; + +#endif // UTILS_TRANSLATION_POPARSER_H diff --git a/src/utils/translation/translationmanager.cpp b/src/utils/translation/translationmanager.cpp new file mode 100644 index 000000000..1b68cc91d --- /dev/null +++ b/src/utils/translation/translationmanager.cpp @@ -0,0 +1,78 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "utils/translation/translationmanager.h" + +#include "utils/langs.h" + +#include "utils/translation/podict.h" +#include "utils/translation/poparser.h" + +#include <string.h> + +#include "localconsts.h" +#include "logger.h" + +#include "debug.h" + +void TranslationManager::init() +{ + if (translator) + delete translator; + translator = PoParser::getEmptyDict(); +} + +void TranslationManager::loadCurrentLang() +{ + if (translator) + delete translator; + translator = loadLang(getLang()); +} + +void TranslationManager::close() +{ + delete translator; + translator = nullptr; +} + +PoDict *TranslationManager::loadLang(LangVect lang) +{ + std::string name = ""; + PoParser parser; + + LangIter it = lang.begin(); + LangIter it_end = lang.end(); + + for (; it != it_end; ++ it) + { + if (*it == "C") + continue; + + if (parser.checkLang(*it)) + { + name = *it; + break; + } + } + if (!name.empty()) + return parser.load(name); + logger->log("can't find client data translation"); + return PoParser::getEmptyDict(); +} diff --git a/src/utils/translation/translationmanager.h b/src/utils/translation/translationmanager.h new file mode 100644 index 000000000..39702f4f4 --- /dev/null +++ b/src/utils/translation/translationmanager.h @@ -0,0 +1,41 @@ +/* + * The ManaPlus Client + * Copyright (C) 2012 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UTILS_TRANSLATION_MANAGER_H +#define UTILS_TRANSLATION_MANAGER_H + +#include <string> +#include <vector> + +class PoDict; + +class TranslationManager +{ + public: + static PoDict *loadLang(std::vector<std::string> lang); + + static void init(); + + static void close(); + + static void loadCurrentLang(); +}; + +#endif // UTILS_TRANSLATION_MANAGER_H diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp index 420915d8f..140da72df 100644 --- a/src/utils/xml.cpp +++ b/src/utils/xml.cpp @@ -26,6 +26,8 @@ #include "resources/resourcemanager.h" +#include "utils/translation/podict.h" + #include <iostream> #include <fstream> #include <cstring> @@ -148,6 +150,16 @@ namespace XML return def; } + std::string langProperty(XmlNodePtr node, const char *name, + const std::string &def) + { + std::string str = getProperty(node, name, def); + if (!translator) + return str; + + return translator->getStr(str); + } + bool getBoolProperty(XmlNodePtr node, const char* name, bool def) { xmlChar *prop = xmlGetProp(node, BAD_CAST name); diff --git a/src/utils/xml.h b/src/utils/xml.h index f623fa618..eb5ee88b0 100644 --- a/src/utils/xml.h +++ b/src/utils/xml.h @@ -92,6 +92,12 @@ namespace XML const std::string &def); /** + * Gets a translated string property from an XmlNodePtr. + */ + std::string langProperty(XmlNodePtr node, const char *name, + const std::string &def); + + /** * Gets a boolean property from an XmlNodePtr. */ bool getBoolProperty(XmlNodePtr node, const char *name, bool def); |