Finished Language Generation Tool
This commit is contained in:
@ -26,6 +26,8 @@ void Xml::load(Xml *xml, std::string data, size_t *j) {
|
|||||||
bool_t insideTag = false;
|
bool_t insideTag = false;
|
||||||
std::string buffer = "";
|
std::string buffer = "";
|
||||||
std::string attrKey = "";
|
std::string attrKey = "";
|
||||||
|
std::string bufferWhitespaces;
|
||||||
|
bool_t valueIsInWhitespace = false;
|
||||||
size_t i = *j;
|
size_t i = *j;
|
||||||
|
|
||||||
while(c = data[i++]) {
|
while(c = data[i++]) {
|
||||||
@ -131,10 +133,29 @@ void Xml::load(Xml *xml, std::string data, size_t *j) {
|
|||||||
// In HTML Spec there could be a child here but not in XML spec.
|
// In HTML Spec there could be a child here but not in XML spec.
|
||||||
doing = XML_PARSE_STATE_PARSING_CLOSE;
|
doing = XML_PARSE_STATE_PARSING_CLOSE;
|
||||||
xml->value = buffer;
|
xml->value = buffer;
|
||||||
buffer = "";
|
buffer.clear();
|
||||||
|
valueIsInWhitespace = false;
|
||||||
|
bufferWhitespaces.clear();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
buffer += c;
|
|
||||||
|
if(Xml::isWhitespace(c)) {
|
||||||
|
if(!valueIsInWhitespace) {
|
||||||
|
bufferWhitespaces.clear();
|
||||||
|
bufferWhitespaces += c;
|
||||||
|
valueIsInWhitespace = true;
|
||||||
|
} else {
|
||||||
|
if(c != ' ') bufferWhitespaces += c;
|
||||||
|
}
|
||||||
|
// TODO: I can maybe consider indentation here
|
||||||
|
} else {
|
||||||
|
if(valueIsInWhitespace) {
|
||||||
|
buffer += bufferWhitespaces;
|
||||||
|
valueIsInWhitespace = false;
|
||||||
|
}
|
||||||
|
buffer += c;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XML_PARSE_STATE_PARSING_CHILD:
|
case XML_PARSE_STATE_PARSING_CHILD:
|
||||||
|
@ -25,7 +25,86 @@ int32_t GeneratedLanguages::start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now process each language file
|
// 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;
|
||||||
|
}
|
||||||
|
std::cout << "bruh " << exist->second << std::endl;
|
||||||
|
bufferOut += exist->first + "|" + exist->second + "|";
|
||||||
|
++itKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out.
|
||||||
|
if(!langOut.writeString(bufferOut)) {
|
||||||
|
std::cout << "Failed to create output file \"" + langOut.filename + "\"" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
++itLang;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,46 @@ bool_t File::readString(std::string *out) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t File::readAhead(char *buffer, size_t max, char needle) {
|
||||||
|
assertNotNull(buffer);
|
||||||
|
assertTrue(max > 0);
|
||||||
|
|
||||||
|
if(!this->isOpen()) {
|
||||||
|
if(!this->open(FILE_MODE_READ)) return 0;
|
||||||
|
}
|
||||||
|
assertTrue(this->mode == FILE_MODE_READ);
|
||||||
|
|
||||||
|
// Buffer
|
||||||
|
size_t pos = ftell(this->file);
|
||||||
|
size_t amountLeftToRead = mathMin<size_t>(max, this->length - pos);
|
||||||
|
char temporary[FILE_BUFFER_SIZE];
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
while(amountLeftToRead > 0) {
|
||||||
|
size_t toRead = mathMin<size_t>(amountLeftToRead, FILE_BUFFER_SIZE);
|
||||||
|
amountLeftToRead -= toRead;
|
||||||
|
// Read bytes
|
||||||
|
size_t read = fread(temporary, sizeof(char), toRead, this->file);
|
||||||
|
|
||||||
|
// Read error?
|
||||||
|
if(toRead != read) return 0;
|
||||||
|
|
||||||
|
// Did we read the needle?
|
||||||
|
size_t i = 0;
|
||||||
|
while(i < read) {
|
||||||
|
char c = temporary[i++];
|
||||||
|
if(c == needle) {
|
||||||
|
return n;
|
||||||
|
} else {
|
||||||
|
buffer[n++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needle was not found.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
bool_t File::writeString(std::string in) {
|
bool_t File::writeString(std::string in) {
|
||||||
if(!this->isOpen()) {
|
if(!this->isOpen()) {
|
||||||
if(!this->open(FILE_MODE_WRITE)) return false;
|
if(!this->open(FILE_MODE_WRITE)) return false;
|
||||||
@ -143,6 +183,11 @@ bool_t File::writeRaw(char *data, size_t len) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void File::setPosition(size_t n) {
|
||||||
|
fseek(this->file, 0, SEEK_SET);
|
||||||
|
fseek(this->file, n, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
File::~File() {
|
File::~File() {
|
||||||
if(this->file != nullptr) this->close();
|
if(this->file != nullptr) this->close();
|
||||||
}
|
}
|
@ -33,14 +33,14 @@ namespace Dawn {
|
|||||||
class File {
|
class File {
|
||||||
private:
|
private:
|
||||||
enum FileMode mode;
|
enum FileMode mode;
|
||||||
size_t length;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FILE *file = nullptr;
|
|
||||||
static std::string normalizeSlashes(std::string str);
|
static std::string normalizeSlashes(std::string str);
|
||||||
static void mkdirp(std::string path);
|
static void mkdirp(std::string path);
|
||||||
|
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
size_t length;
|
||||||
|
FILE *file = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new File interface class.
|
* Constructs a new File interface class.
|
||||||
@ -95,6 +95,20 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
bool_t readString(std::string *out);
|
bool_t readString(std::string *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads ahead from the current position to a specific needle (character).
|
||||||
|
*
|
||||||
|
* @param buffer Buffer to output read chars to.
|
||||||
|
* @param max Max length of the buffer / amount of chars to read ahead.
|
||||||
|
* @param needle The character (needle) to look for.
|
||||||
|
* @return Amount of chars read, or <= 0 on error.
|
||||||
|
*/
|
||||||
|
size_t readAhead(
|
||||||
|
char *buffer,
|
||||||
|
size_t max,
|
||||||
|
char needle
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the entire contents of a string to a file.
|
* Writes the entire contents of a string to a file.
|
||||||
*
|
*
|
||||||
@ -111,6 +125,8 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
bool_t writeRaw(char *data, size_t );
|
bool_t writeRaw(char *data, size_t );
|
||||||
|
|
||||||
|
void setPosition(size_t pos);
|
||||||
|
|
||||||
~File();
|
~File();
|
||||||
};
|
};
|
||||||
}
|
}
|
Reference in New Issue
Block a user