git-svn-id: svn://db.shs.com.ru/libs@99 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
152
cd_utils/cdutils_k_parser.cpp
Normal file
152
cd_utils/cdutils_k_parser.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include "cdutils_k_parser.h"
|
||||
#include "cdutils_k_types.h"
|
||||
#include "piiostring.h"
|
||||
#include "pifile.h"
|
||||
|
||||
using namespace CDUtils;
|
||||
|
||||
enum Phase {
|
||||
eName = 1,
|
||||
eBracketOpen,
|
||||
eBracketClose,
|
||||
eMemberName,
|
||||
eMemberEqual,
|
||||
eMemberValue,
|
||||
eMemberComma,
|
||||
eComment,
|
||||
eMultiComment
|
||||
};
|
||||
|
||||
|
||||
void removeComment(PIString & line, PIString * comment = 0) {
|
||||
int ci = line.find("//");
|
||||
if (ci >= 0) {
|
||||
if (comment) *comment = line.right(line.size_s() - ci - 2).trim();
|
||||
line.cutRight(line.size_s() - ci).trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void parseEnumLine(PIString & line, int * value, PIString * comment = 0) {
|
||||
removeComment(line, comment);
|
||||
int ci = line.find("=");
|
||||
if (ci >= 0) {
|
||||
if (value) *value = line.right(line.size_s() - ci - 1).trim().toInt();
|
||||
line.cutRight(line.size_s() - ci).trim();
|
||||
}
|
||||
if (line.trim().endsWith(",")) line.cutRight(1);
|
||||
}
|
||||
|
||||
|
||||
void parseInsert(PIString line, PIString & alias, PIStringList & out) {
|
||||
out.clear();
|
||||
int ci = line.find("=");
|
||||
if (ci < 0) return;
|
||||
alias = line.right(line.size_s() - ci - 1).trim();
|
||||
line.cutRight(line.size_s() - ci).trim();
|
||||
while (line.find("[") > 0) {
|
||||
int is = line.find("["), ie = line.find("]");
|
||||
PIString arr = line.mid(is + 1, ie - is - 1);
|
||||
out << arr;
|
||||
line.cutMid(is, ie - is + 1);
|
||||
}
|
||||
if (!line.isEmpty()) out.insert(0, line);
|
||||
}
|
||||
|
||||
|
||||
PIVector<int> enumValues(const PIString & e, const PIMap<PIString, KSection> & sections) {
|
||||
PIVector<int> ret;
|
||||
if (sections.contains(e)) {
|
||||
ret = sections[e].indexes();
|
||||
} else {
|
||||
int v = e.toInt();
|
||||
if (v < 2) return ret;
|
||||
for (int i = 0; i < v; ++i)
|
||||
ret << i;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
KSection KParser::parse(PIIODevice * d) {
|
||||
if (!d) return KSection();
|
||||
if (!d->canRead()) return KSection();
|
||||
KSection cs;
|
||||
KType ck;
|
||||
PIMap<PIString, KSection> sections;
|
||||
PIMap<PIString, int> enum_values, cevalues;
|
||||
PIString content, line, alias, comment;
|
||||
PIStringList iarr;
|
||||
if (PIStringAscii(d->className()) == PIStringAscii("PIFile")) content = ((PIFile*)d)->readAll();
|
||||
if (PIStringAscii(d->className()) == PIStringAscii("PIIOString")) content = *(((PIIOString*)d)->string());
|
||||
PIIOString ios(&content);
|
||||
int phase = 0;
|
||||
int cind = -1;
|
||||
while ((cind = content.find("enum", cind)) >= 0) {
|
||||
ios.seek(cind);
|
||||
line = ios.readLine().trim();
|
||||
comment.clear();
|
||||
removeComment(line, &comment);
|
||||
if (line.find("{") < 0) {
|
||||
cind += 4;
|
||||
continue;
|
||||
}
|
||||
line.cutLeft(line.find("enum") + 4).trim();
|
||||
line.cutRight(line.size_s() - line.find("{")).trim();
|
||||
if (line.isEmpty()) {
|
||||
cind += 4;
|
||||
continue;
|
||||
}
|
||||
cs = KSection();
|
||||
cs.name = line;
|
||||
piCout << "enum" << cs.name;
|
||||
int cev = 0;
|
||||
cevalues.clear();
|
||||
while (!ios.isEnd()) {
|
||||
line = ios.readLine().trim();
|
||||
comment.clear();
|
||||
removeComment(line, &comment);
|
||||
if (line.find("}") >= 0) break;
|
||||
if (line.isEmpty()) {
|
||||
if (comment.find("=") >= 0) {
|
||||
parseInsert(comment, alias, iarr);
|
||||
if (!iarr.isEmpty()) {
|
||||
if (!enum_values.contains(alias)) {
|
||||
piCout << "Parse error: can`t find section alias \"" << alias << "\"!";
|
||||
return KSection();
|
||||
}
|
||||
if (!sections.contains(iarr.front())) {
|
||||
piCout << "Parse error: can`t find section \"" << iarr.front() << "\"!";
|
||||
return KSection();
|
||||
}
|
||||
piCout << "insert" << alias << iarr;
|
||||
int aval = enum_values.value(alias);
|
||||
KSection is = sections.value(iarr.take_front()), ts;
|
||||
piForeachRC (PIString & a, iarr) {
|
||||
PIVector<int> evals = enumValues(a, sections);
|
||||
//piCout << a << evals;
|
||||
piForeachC (int e, evals)
|
||||
ts.section(e) = is;
|
||||
is = ts;
|
||||
ts = KSection();
|
||||
}
|
||||
cs.section(aval) = is;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parseEnumLine(line, &cev, &comment);
|
||||
//piCout << line << "=" << cev << "//" << comment;
|
||||
ck = KType(cev, "", "", comment);
|
||||
ck.name = line;
|
||||
cs[cev] = ck;
|
||||
cevalues[ck.name] = cev;
|
||||
++cev;
|
||||
}
|
||||
}
|
||||
//piCout << cs.name << cs.k;
|
||||
sections[cs.name] = cs;
|
||||
enum_values << cevalues;
|
||||
cind += 4;
|
||||
}
|
||||
return sections.value("KDescription");
|
||||
}
|
||||
Reference in New Issue
Block a user