summaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/base64.cpp4
-rw-r--r--src/utils/langs.cpp87
-rw-r--r--src/utils/langs.h41
-rw-r--r--src/utils/paths.cpp22
-rw-r--r--src/utils/paths.h4
-rw-r--r--src/utils/physfsrwops.h1
-rw-r--r--src/utils/process.cpp2
-rw-r--r--src/utils/stringutils.cpp127
-rw-r--r--src/utils/stringutils.h12
-rw-r--r--src/utils/stringutils_unittest.cc517
-rw-r--r--src/utils/translation/podict.cpp55
-rw-r--r--src/utils/translation/podict.h59
-rw-r--r--src/utils/translation/poparser.cpp221
-rw-r--r--src/utils/translation/poparser.h78
-rw-r--r--src/utils/translation/translationmanager.cpp78
-rw-r--r--src/utils/translation/translationmanager.h41
-rw-r--r--src/utils/xml.cpp12
-rw-r--r--src/utils/xml.h6
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);