141 lines
3.6 KiB
C++
141 lines
3.6 KiB
C++
/**
|
|
* 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<std::string> GeneratedLanguages::getRequiredFlags() {
|
|
return std::vector<std::string>{ "input", "output" };
|
|
}
|
|
|
|
int32_t GeneratedLanguages::start() {
|
|
// Generate list of languages
|
|
std::string inNormal = File::normalizeSlashes(flags["input"]);
|
|
std::string error;
|
|
std::vector<std::string> 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<std::string, std::map<std::string, std::string>> strings;
|
|
|
|
std::vector<std::string> 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<std::string> *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;
|
|
} |