NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
language.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2016 Erik Haenel et al.
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 3 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, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19
20
21#include "language.hpp"
22#include "../utils/stringtools.hpp"
23
24using namespace std;
25
26bool fileExists(const string&);
27
32{
33 mLangStrings.clear();
34 sYES = "j";
35 sNO = "n";
36}
37
38
47{
49 sYES = _lang.sYES;
50 sNO = _lang.sNO;
51}
52
53
63map<string,string> Language::getLangFileContent(const string& sFile) const
64{
65 map<string,string> mLangFileContent;
66 ifstream fFile_in;
67 string sLine;
68
69 fFile_in.open(FileSystem::ValidFileName(sFile, ".nlng").c_str());
70
71 // Check, if file has been successfully opened
72 if (fFile_in.fail())
73 {
74 fFile_in.close();
75 return mLangFileContent;
76 }
77
78 // Read the complete file
79 while (!fFile_in.eof())
80 {
81 getline(fFile_in, sLine);
82 StripSpaces(sLine);
83
84 // Ignore empty lines
85 if (!sLine.length())
86 continue;
87
88 // Ignore comments
89 if (sLine.front() == '#')
90 continue;
91
92 // Replace included tab characters with
93 // whitespaces
94 for (size_t i = 0; i < sLine.length(); i++)
95 {
96 if (sLine[i] == '\t')
97 sLine[i] = ' ';
98 }
99
100 // Remove whitespaces in front of the first
101 // equal sign
102 for (unsigned int i = 1; i < sLine.find('='); i++)
103 {
104 if (sLine[i] == ' ')
105 {
106 sLine.erase(i, 1);
107 i--;
108 }
109 }
110
111 // Replace tabs
112 while (sLine.find("%%TAB%%") != string::npos)
113 sLine.replace(sLine.find("%%TAB%%"), 7, "\t");
114
115 // Replace linebreaks
116 while (sLine.find("%%LINEBREAK%%") != string::npos)
117 sLine.replace(sLine.find("%%LINEBREAK%%"), 13, "\n");
118
119 // Replace linebreaks
120 while (sLine.find("%%ITEMIZE%%") != string::npos)
121 sLine.replace(sLine.find("%%ITEMIZE%%"), 11, "\n - ");
122
123 // Replace linebreaks
124 while (sLine.find("%%ITEMIZE_END%%") != string::npos)
125 sLine.replace(sLine.find("%%ITEMIZE_END%%"), 15, "\n ");
126
127 // Store the token in the map
128 mLangFileContent[sLine.substr(0, sLine.find('='))] = sLine.substr(sLine.find_first_not_of(' ', sLine.find('=')+1));
129 }
130
131 return mLangFileContent;
132}
133
134
143void Language::loadAndInsert(const string& sLanguageFileName)
144{
145 // Load language file
146 map<string,string> mLangFileContent = getLangFileContent(sLanguageFileName);
147
148 // Insert the strings
149 for (auto iter = mLangFileContent.begin(); iter != mLangFileContent.end(); ++iter)
150 mLangStrings[iter->first] = iter->second;
151}
152
153
164void Language::loadStrings(bool bloadUserFiles)
165{
166 string sLine;
167 map<string,string> mLangFileContent;
168
169 // Clear already existing strings first
170 if (mLangStrings.size())
171 mLangStrings.clear();
172
173 // Load main file
174 mLangFileContent = getLangFileContent("<>/lang/main.nlng");
175 mLangStrings.insert(mLangFileContent.begin(), mLangFileContent.end());
176
177 // Load errors file
178 loadAndInsert("<>/lang/error.nlng");
179
180 // Load NumeRe specific syntax language files
181 loadAndInsert("<>/lang/numere.nlng");
182
183 // Shall user language files be loaded?
184 if (bloadUserFiles)
185 {
186 // Load user main language file, if it exists
187 if (fileExists(FileSystem::ValidFileName("<>/user/lang/main.nlng", ".nlng")))
188 loadAndInsert("<>/user/lang/main.nlng");
189
190 // Load user error language file, if it exists
191 if (fileExists(FileSystem::ValidFileName("<>/user/lang/error.nlng", ".nlng")))
192 loadAndInsert("<>/user/lang/error.nlng");
193
194 // Load user NumeRe specific syntax language file, if it exists
195 if (fileExists(FileSystem::ValidFileName("<>/user/lang/numere.nlng", ".nlng")))
196 loadAndInsert("<>/user/lang/numere.nlng");
197 }
198
199 // Replace all named tokens with their corresponding
200 // language string
201 for (auto iter = mLangStrings.begin(); iter != mLangStrings.end(); ++iter)
202 {
203 // Ignore too short strings
204 if ((iter->second).length() < 5)
205 continue;
206
207 // Search tokens, check, whether they exist
208 // and replace them with their corresponding
209 // strings
210 for (size_t i = 0; i < (iter->second).length()-3; i++)
211 {
212 if ((iter->second).substr(i, 2) == "%%" && isalpha((iter->second)[i+3]) && (iter->second).find("%%", i+3) != string::npos)
213 {
214 sLine = (iter->second).substr(i+2, (iter->second).find("%%", i+3)-i-2);
215
216 if (mLangStrings.find(sLine) != mLangStrings.end())
217 (iter->second).replace(i, (iter->second).find("%%", i+3)-i+2, mLangStrings[sLine]);
218 }
219 }
220 }
221
222 sYES = mLangStrings["COMMON_YES_NO"].front();
223 sNO = mLangStrings["COMMON_YES_NO"].back();
224
225 return;
226}
227
228
238void Language::addToLanguage(const map<string,string>& _langstrings)
239{
240 for (auto iter = _langstrings.begin(); iter != _langstrings.end(); ++iter)
241 mLangStrings[iter->first] = iter->second;
242}
243
244
257string Language::getKey(const string& sMessage) const
258{
259 string sKey = sMessage;
260
261 // Do only something, when a wildcard is available
262 if (sKey.find('*') != string::npos)
263 {
264 sKey.erase(sKey.find('*'));
265
266 // Find a candidate for the passed token
267 for (auto iter = mLangStrings.begin(); iter != mLangStrings.end(); ++iter)
268 {
269 if ((iter->first).substr(0, sKey.length()) == sKey)
270 {
271 sKey = iter->first;
272 return sKey;
273 }
274 }
275 }
276
277 return sMessage;
278}
279
280
292string Language::get(const string& sMessage, const vector<string>& vTokens) const
293{
294 if (!mLangStrings.size())
295 return sMessage;
296
297 string sLangString = sMessage;
298
299 // Search for the language string
300 if (sLangString.find('*') != string::npos)
301 {
302 sLangString.erase(sLangString.find('*'));
303
304 // Find a candidate for the passed identifier
305 // containing an asteriks
306 for (auto iter = mLangStrings.begin(); iter != mLangStrings.end(); ++iter)
307 {
308 if ((iter->first).substr(0,sLangString.length()) == sLangString)
309 sLangString = iter->second;
310 }
311
312 if (sMessage.substr(0, sLangString.length()) == sLangString)
313 return sMessage;
314 }
315 else if (mLangStrings.find(sMessage) != mLangStrings.end())
316 sLangString = mLangStrings.at(sMessage);
317 else
318 return sMessage;
319
320 string sToken;
321
322 // Replace all enumerated tokens
323 for (size_t i = 0; i < vTokens.size(); i++)
324 {
325 sToken = "%%" + toString(i+1) + "%%";
326 size_t pos = 0;
327
328 // As long as further tokens can be found
329 while ((pos = sLangString.find(sToken, pos)) != string::npos)
330 {
331 sLangString.replace(pos, sToken.length(), vTokens[i]);
332 pos += vTokens[i].length();
333 }
334 }
335
336 return sLangString;
337}
338
339
349vector<string> Language::getList(const string& sMessageScheme) const
350{
351 vector<string> vListResults;
352 string sPrefix = sMessageScheme.substr(0, sMessageScheme.find('*'));
353 string sType = "";
354
355 // Extract the type (available in command and function
356 // documentations, for example)
357 if (sPrefix.find('[') != string::npos)
358 {
359 sPrefix.erase(sPrefix.find('['));
360 sType = sMessageScheme.substr(sMessageScheme.find('[')+1, sMessageScheme.find(']')-sMessageScheme.find('[')-1);
361 }
362 else if (sMessageScheme.find('[') != string::npos)
363 sType = sMessageScheme.substr(sMessageScheme.find('[')+1, sMessageScheme.find(']')-sMessageScheme.find('[')-1);
364
365 for (auto iter = mLangStrings.begin(); iter != mLangStrings.end(); ++iter)
366 {
367 if ((iter->first).substr(0, sPrefix.length()) != sPrefix)
368 continue;
369
370 // Ensure that the found identifier has the
371 // the correct type if a type was selected
372 if (sType.length() && (iter->first).find('[') != string::npos)
373 {
374 string sCurrentType = (iter->first).substr((iter->first).find('['), (iter->first).find(']')+1-(iter->first).find('['));
375
376 if (sCurrentType.find(sType) == string::npos)
377 continue;
378 }
379
380 // Append the found occurence to the vector
381 vListResults.push_back(iter->second);
382 }
383
384 return vListResults;
385}
386
387
This class implements the basic input/ output file system and provides functionalities to work with f...
Definition: filesystem.hpp:92
std::string ValidFileName(std::string _sFileName, const std::string sExtension=".dat", bool checkExtension=true, bool doCleanPath=true) const
This member function evaluates, whether the passed filename is a valid filename. One may supply a pre...
Definition: filesystem.cpp:280
This class handles the internal language system and returns the language strings of the selected lang...
Definition: language.hpp:38
void addToLanguage(const std::map< std::string, std::string > &_langstrings)
This member function adds the contents of the passed language file into the internal map.
Definition: language.cpp:238
Language()
Contructor of the language class.
Definition: language.cpp:31
void loadStrings(bool bloadUserFiles=true)
This member function loads the language files to the internal map and replaces the named tokens with ...
Definition: language.cpp:164
std::string getKey(const std::string &sMessage) const
This member function searches the internal language map for an identifier, which starts similar with ...
Definition: language.cpp:257
std::string sYES
Definition: language.hpp:41
void loadAndInsert(const std::string &sLanguageFileName)
This private member function is a simple helper for Language::loadStrings().
Definition: language.cpp:143
std::vector< std::string > getList(const std::string &sMessageScheme) const
This member function returns a vector of language strings matching to the passed identifier containin...
Definition: language.cpp:349
std::string sNO
Definition: language.hpp:42
std::map< std::string, std::string > mLangStrings
Definition: language.hpp:40
std::string get(const std::string &sMessage, const std::vector< std::string > &vTokens) const
This member function returns the language string for the passed language identifier and replaces all ...
Definition: language.cpp:292
std::map< std::string, std::string > getLangFileContent(const std::string &sFile) const
This private member function decodes a single language file into a map and returns it.
Definition: language.cpp:63
Language _lang
Definition: kernel.cpp:39
bool fileExists(const string &)
This function checks, whether the file with the passed file name exists.
Definition: tools.cpp:2500
void StripSpaces(std::string &)
Removes leading and trailing white spaces and tabulator characters.
std::string toString(int)
Converts an integer to a string without the Settings bloat.