/** * Copyright (c) 2021 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "GeneratedLanguages.hpp" using namespace Dawn; std::vector GeneratedLanguages::getRequiredFlags() { return std::vector{ "input", "output" }; } int32_t GeneratedLanguages::start() { // Generate list of languages std::string inNormal = File::normalizeSlashes(flags["input"]); std::string error; std::vector files; int32_t ret = this->scanDir(inNormal, &error, &files); if(ret != 0) { std::cout << error << std::endl; return ret; } // Now process each language file std::map> strings; std::vector knownKeys; auto itFiles = files.begin(); while(itFiles != files.end()) { File file(*itFiles); file.open(FILE_MODE_READ); std::string buffer; size_t n = 0; while(n < file.length) { char lang[32]; char key[128]; char string[32178]; // Read lang if(n != 0) file.setPosition(n); auto langSize = file.readAhead(lang, 32, '|'); lang[langSize] = '\0'; n += langSize + 1; if(langSize <= 0) { std::cout << "Error reading language name: " << langSize << std::endl; return 1; } // Read Key file.setPosition(n); auto keySize = file.readAhead(key, 128, '|'); key[keySize] = '\0'; n += keySize + 1; if(keySize <= 0) { std::cout << "Error reading language key: " << keySize << std::endl; return 1; } // Read String file.setPosition(n); auto stringSize = file.readAhead(string, 32178, '|'); string[stringSize] = '\0'; n += stringSize + 1; if(stringSize <= 0) { std::cout << "Error reading language string: " << stringSize << std::endl; return 1; } strings[lang][key] = string; auto exist = std::find(knownKeys.begin(), knownKeys.end(), key); if(exist == knownKeys.end()) knownKeys.push_back(key); } ++itFiles; } // Now prepare output file auto itLang = strings.begin(); std::string bufferOut = ""; while(itLang != strings.end()) { File langOut(flags["output"] + FILE_PATH_SEP + "language_" + itLang->first + ".language"); bufferOut.clear(); auto itKeys = knownKeys.begin(); while(itKeys != knownKeys.end()) { auto key = *itKeys; auto exist = itLang->second.find(key); if(exist == itLang->second.end()) { std::cout << "Language " << itLang->first << " is missing key " << key << std::endl; return 1; } bufferOut += exist->first + "|" + exist->second + "|"; ++itKeys; } // Write out. langOut.mkdirp(); if(!langOut.writeString(bufferOut)) { std::cout << "Failed to create output file \"" + langOut.filename + "\"" << std::endl; return 1; } ++itLang; } return 0; } int32_t GeneratedLanguages::scanDir( std::string dir, std::string *error, std::vector *files ) { DIR* handle = opendir(dir.c_str()); if(ENOENT == errno) { *error = "Input directory \"" + dir + "\" does not exist"; return 0; } if(!handle) return 0; struct dirent *entry; while((entry=readdir(handle))) { std::string name(entry->d_name); if(name.size() == 0 || name[0] == '.') continue; auto path = dir + FILE_PATH_SEP + entry->d_name; if(entry->d_type == DT_DIR) { auto ret = this->scanDir(dir, error, files); if(ret != 0) return ret; } else if(entry->d_type == DT_REG) { files->push_back(path); } } closedir(handle); return 0; }