first release of translation facility
* runtime - loading and translating * design-time - works with *.ts file (pip_tr utility) * compile-time - CMake macro for compile *.ts
This commit is contained in:
139
utils/translator/parser.cpp
Normal file
139
utils/translator/parser.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
#include "parser.h"
|
||||
|
||||
#include "piliterals_string.h"
|
||||
#include "pistringlist.h"
|
||||
|
||||
|
||||
PIString fromCode(const PIString & in) {
|
||||
return in.replacedAll("\\n", '\n')
|
||||
.replaceAll("\\r", '\r')
|
||||
.replaceAll("\\t", '\t')
|
||||
.replaceAll("\\\"", '"')
|
||||
.replaceAll("\\'", '\'')
|
||||
.replaceAll("\\\\", '\\');
|
||||
}
|
||||
|
||||
|
||||
void gatherStrings(TSFile::Content & content, const PIString & file, const PIString & file_loc, int & count_all, int & count_new) {
|
||||
static const PIStringList methods({"PITranslator::tr", "PITranslator::trNoOp", "piTr", "piTrNoOp"});
|
||||
static const PIStringList literals({"_tr", "_trNoOp"});
|
||||
PIString source, context;
|
||||
int pos = -1, ppos = 0, line = -1;
|
||||
int len = 0;
|
||||
auto isCLetter = [](const PIChar c) { return c.isAlpha() || c.isDigit() || c == '_'; };
|
||||
auto add = [&content, file_loc, &count_all, &count_new](const PIString & source, const PIString & context, int line) {
|
||||
if (source.isEmpty()) return;
|
||||
++count_all;
|
||||
if (content.contexts[context].confirm(fromCode(source), file_loc, line)) ++count_new;
|
||||
// piCout << "Context = \"" << context << "\", message = \"" << source << "\" (" << file_loc << ":" << line << ")";
|
||||
};
|
||||
// piCout << "file" << file_loc;
|
||||
for (const auto & kw: methods) {
|
||||
// piCout << "method" << kw;
|
||||
for (;;) {
|
||||
source.clear();
|
||||
context.clear();
|
||||
|
||||
pos = file.find(kw, pos + 1);
|
||||
if (pos < 0) break;
|
||||
if (pos > 0) {
|
||||
auto pc = file[pos - 1];
|
||||
if (isCLetter(pc) || pc == ':') {
|
||||
pos += kw.size_s();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
pos += kw.size_s();
|
||||
if (pos < file.size_s() - 1) {
|
||||
auto pc = file[pos];
|
||||
if (isCLetter(pc) || pc == ':') {
|
||||
pos += kw.size_s();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// piCout << "PITranslator" << pos;
|
||||
|
||||
pos = file.find('(', pos);
|
||||
if (pos < 0) break;
|
||||
// piCout << "(" << pos;
|
||||
pos += 1;
|
||||
|
||||
pos = file.findRange('"', '"', '\\', pos, &len);
|
||||
if (pos < 0) break;
|
||||
// piCout << "\"" << pos;
|
||||
source = file.mid(pos, len);
|
||||
pos += len + 1;
|
||||
line = file.lineNumber(pos);
|
||||
ppos = pos;
|
||||
|
||||
while (pos < file.size_s()) {
|
||||
if (!file[pos].isSpace() && file[pos] != '\n' && file[pos] != '\r') break;
|
||||
++pos;
|
||||
}
|
||||
if (pos < file.size_s()) {
|
||||
// piCout << "check comma" << file[pos];
|
||||
if (file[pos] == ',') {
|
||||
pos += 1;
|
||||
pos = file.findRange('"', '"', '\\', pos, &len);
|
||||
// piCout << "check range" << file.mid(pos, len);
|
||||
if (pos >= 0) {
|
||||
context = file.mid(pos, len);
|
||||
pos += len + 1;
|
||||
ppos = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos = ppos;
|
||||
add(source, context, line);
|
||||
}
|
||||
}
|
||||
for (const auto & kw: literals) {
|
||||
// piCout << "literal" << kw;
|
||||
pos = -1;
|
||||
for (;;) {
|
||||
source.clear();
|
||||
context.clear();
|
||||
|
||||
pos = file.find('"', pos + 1);
|
||||
if (pos < 0) break;
|
||||
pos = file.findRange('"', '"', '\\', pos, &len);
|
||||
if (pos < 0) break;
|
||||
// piCout << "\"" << pos;
|
||||
source = file.mid(pos, len);
|
||||
pos += len + 1;
|
||||
if (file.mid(pos, kw.size_s()) == kw) {
|
||||
// piCout << "line" << file.lineNumber(pos);
|
||||
pos += kw.size_s();
|
||||
if (pos < file.size_s() - 1) {
|
||||
auto pc = file[pos];
|
||||
if (isCLetter(pc) || pc == ':') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ppos = pos;
|
||||
while (pos < file.size_s()) {
|
||||
if (!file[pos].isSpace() && file[pos] != '\n' && file[pos] != '\r') break;
|
||||
++pos;
|
||||
}
|
||||
if (pos < file.size_s()) {
|
||||
// piCout << "check comma" << file[pos];
|
||||
if (file[pos] == '(') {
|
||||
pos += 1;
|
||||
pos = file.findRange('"', '"', '\\', pos, &len);
|
||||
// piCout << "check range" << file.mid(pos, len);
|
||||
if (pos >= 0) {
|
||||
context = file.mid(pos, len);
|
||||
pos += len + 1;
|
||||
ppos = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
pos = ppos;
|
||||
if (source.isEmpty()) continue;
|
||||
line = file.lineNumber(pos);
|
||||
add(source, context, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user