#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 enumValues(const PIString & e, const PIMap & sections) { PIVector 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 sections; PIMap 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 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"); }