#include #include #include #include #include #include #ifndef _WIN32 static const std::string C_LBLUE = "\033[1;34m"; static const std::string C_RED = "\033[1;31m"; static const std::string C_GREEN = "\033[1;32m"; static const std::string C_NONE = "\033[m"; #else static const std::string C_LBLUE = ""; static const std::string C_NONE = ""; #endif class Indexes { public: std::string comment; std::string text; int fm; std::string fmt; }; class Language { public: std::string shortname; std::string langname; std::vector comments; std::map idx; }; std::map data; void read_old_langfile(const std::string filename, const std::string lng) { std::ifstream in(filename.c_str()); if (!in.is_open()) { std::cout << C_LBLUE << "Could not open " << filename << " for reading" << C_NONE << std::endl; return; } data[lng].shortname = lng; std::string line, index; while (getline(in, line)) { if (line.empty()) continue; // do nothing if (line[0] == '#') { // we found a comment data[lng].comments.push_back(line); } else if (line[0] != '\t') // starting with a tabulator { index = line; //std::cout << C_RED << "New Index: " << C_NONE << index << std::endl; } else if (!index.empty() && line[0] == '\t') { line.erase(line.begin()); // remove the leading tabstop, we dont like tabs! // line += std::endl; data[lng].idx[index].text += "\n" + line; //std::cout << C_GREEN << "Text: " << C_NONE << line << std::endl; } } // std::cout << "Found " << data[lng].idx.size() << " indexes in \"" << lng << "\" (" << data[lng].idx["LANG_NAME"][0] << ")" << std::endl; in.close(); } void check_languages() { size_t pos; std::string lng; std::map::iterator it1, end1; std::map::iterator it2, end2; // compare all langs with the english one, search for missing for (it1 = data["en"].idx.begin(), end1 = data["en"].idx.end(); it1 != end1; it1++) { for ( it2 = data.begin(), end2 = data.end(); it2 != end2; it2++) { if (it2->first == "en") continue; // we dont want to compare with it self if (it2->second.idx.find(it1->first) == it2->second.idx.end()) { std::cout << "Index " << it1->first << " missing in language " << it2->first << ", adding it now" << std::endl; it2->second.idx[it1->first] = it1->second; } } } // now lets search for old, unneeded indexes for (it2 = data.begin(), end2 = data.end(); it2!=end2; it2++) { if (it2->first == "en") continue; for (it1 = data[it2->first].idx.begin(), end1 = data[it2->first].idx.end(); it1 != end1; it1++) { if (data["en"].idx.find(it1->first) == data["en"].idx.end()) { std::cout << "Index " << it1->first << "found in language " << it2->first << ", but is not in the english lang file. Deleting it now." << std::endl; data[it2->first].idx.erase(it1->first); } } } // count format params on each language for (it2 = data.begin(), end2 = data.end(); it2!=end2; it2++) { for (it1 = data[it2->first].idx.begin(), end1 = data[it2->first].idx.end(); it1 != end1; it1++) { if (it1->first.find("STRFTIME") != std::string::npos) continue; it1->second.fm = 0; for (pos = it1->second.text.find("%"); pos != std::string::npos; pos = it1->second.text.find("%", pos+1)) { if (it1->second.text[pos+1] > 'a' && it1->second.text[pos+1] < 'z') { it1->second.fm++; it1->second.fmt.append(it1->second.text.substr(pos,2)); pos++; } } } } // compare all format parameters with the english lang file for (it2 = data.begin(), end2 = data.end(); it2!=end2; it2++) { if (it2->first == "en") continue; for (it1 = data[it2->first].idx.begin(), end1 = data[it2->first].idx.end(); it1 != end1; it1++) { if (data["en"].idx.find(it1->first)->second.fmt != it1->second.fmt) { std::cout << it1->first << " en=" << data["en"].idx.find(it1->first)->second.fm << ": " << data["en"].idx.find(it1->first)->second.fmt << " " << it2->first << "=" << it1->second.fm << ": " << it1->second.fmt << std::endl; // std::cout << "en: " << data["en"].idx.find(it1->first)->second.text << std::endl; // std::cout << it2->first << ": " << it1->second.text << std::endl << std::endl; } } } } int main(int argc, char *argv[]) { std::cout << C_LBLUE << "Anope 1.9.x language file tool" << C_NONE << std::endl << std::endl; std::cout << "parsing languages files and reading all data into memory now" << std::endl; read_old_langfile("en_us.l", "en"); read_old_langfile("de.l", "de"); read_old_langfile("cat.l", "cat"); read_old_langfile("es.l", "es"); read_old_langfile("fr.l", "fr"); read_old_langfile("gr.l", "gr"); read_old_langfile("hun.l", "hun"); read_old_langfile("it.l", "it"); read_old_langfile("nl.l", "nl"); read_old_langfile("pl.l", "pl"); read_old_langfile("pt.l", "pt"); read_old_langfile("ru.l", "ru"); read_old_langfile("tr.l", "tr"); read_old_langfile("ja_utf8.l", "ja"); std::cout << "finished" << std::endl; check_languages(); std::cout << "check completed, checking again :-) " << std::endl; // check_languages(); // std::cout << "second check completed, I hope there were no messages" << std::endl; // std::cout << "now we can write the langfiles (code is still missing)" << std::endl; // write_langfile("de.l", "de"); std::cout << "Language File Maintenance complete!" << std::endl; return 0; }