- Ifc/Step: support line continuations in parser.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1304 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/6/merge
aramis_acg 2012-10-02 14:19:24 +00:00
parent 54a5088e14
commit fa1016ddc8
1 changed files with 89 additions and 9 deletions

View File

@ -160,6 +160,30 @@ STEP::DB* STEP::ReadFileHeader(boost::shared_ptr<IOStream> stream)
} }
namespace {
// ------------------------------------------------------------------------------------------------
// check whether the given line contains an entity definition (i.e. starts with "#<number>=")
bool IsEntityDef(const std::string& snext)
{
if (snext[0] == '#') {
// it is only a new entity if it has a '=' after the
// entity ID.
for(std::string::const_iterator it = snext.begin()+1; it != snext.end(); ++it) {
if (*it == '=') {
return true;
}
if (*it < '0' || *it > '9') {
break;
}
}
}
return false;
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
const char* const* types_to_track, size_t len, const char* const* types_to_track, size_t len,
@ -171,8 +195,9 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
const DB::ObjectMap& map = db.GetObjects(); const DB::ObjectMap& map = db.GetObjects();
LineSplitter& splitter = db.GetSplitter(); LineSplitter& splitter = db.GetSplitter();
for(; splitter; ++splitter) { while (splitter) {
const std::string& s = *splitter; bool has_next = false;
std::string s = *splitter;
if (s == "ENDSEC;") { if (s == "ENDSEC;") {
break; break;
} }
@ -184,6 +209,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
ai_assert(s.length()); ai_assert(s.length());
if (s[0] != '#') { if (s[0] != '#') {
DefaultLogger::get()->warn(AddLineNumber("expected token \'#\'",line)); DefaultLogger::get()->warn(AddLineNumber("expected token \'#\'",line));
++splitter;
continue; continue;
} }
@ -195,26 +221,76 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
const std::string::size_type n0 = s.find_first_of('='); const std::string::size_type n0 = s.find_first_of('=');
if (n0 == std::string::npos) { if (n0 == std::string::npos) {
DefaultLogger::get()->warn(AddLineNumber("expected token \'=\'",line)); DefaultLogger::get()->warn(AddLineNumber("expected token \'=\'",line));
++splitter;
continue; continue;
} }
const uint64_t id = strtoul10_64(s.substr(1,n0-1).c_str()); const uint64_t id = strtoul10_64(s.substr(1,n0-1).c_str());
if (!id) { if (!id) {
DefaultLogger::get()->warn(AddLineNumber("expected positive, numeric entity id",line)); DefaultLogger::get()->warn(AddLineNumber("expected positive, numeric entity id",line));
++splitter;
continue; continue;
} }
const std::string::size_type n1 = s.find_first_of('(',n0); std::string::size_type n1 = s.find_first_of('(',n0);
if (n1 == std::string::npos) { if (n1 == std::string::npos) {
has_next = true;
bool ok = false;
for( ++splitter; splitter; ++splitter) {
const std::string& snext = *splitter;
if (snext.empty()) {
continue;
}
// the next line doesn't start an entity, so maybe it is
// just a continuation for this line, keep going
if (!IsEntityDef(snext)) {
s.append(snext);
n1 = s.find_first_of('(',n0);
ok = (n1 != std::string::npos);
}
else {
break;
}
}
if(!ok) {
DefaultLogger::get()->warn(AddLineNumber("expected token \'(\'",line)); DefaultLogger::get()->warn(AddLineNumber("expected token \'(\'",line));
continue; continue;
} }
}
const std::string::size_type n2 = s.find_last_of(')'); std::string::size_type n2 = s.find_last_of(')');
if (n2 == std::string::npos || n2 < n1) { if (n2 == std::string::npos || n2 < n1 || n2 == s.length() - 1 || s[n2 + 1] != ';') {
has_next = true;
bool ok = false;
for( ++splitter; splitter; ++splitter) {
const std::string& snext = *splitter;
if (snext.empty()) {
continue;
}
// the next line doesn't start an entity, so maybe it is
// just a continuation for this line, keep going
if (!IsEntityDef(snext)) {
s.append(snext);
n2 = s.find_last_of(')');
ok = !(n2 == std::string::npos || n2 < n1 || n2 == s.length() - 1 || s[n2 + 1] != ';');
}
else {
break;
}
}
if(!ok) {
DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line)); DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line));
continue; continue;
} }
}
if (map.find(id) != map.end()) { if (map.find(id) != map.end()) {
DefaultLogger::get()->warn(AddLineNumber((Formatter::format(),"an object with the id #",id," already exists"),line)); DefaultLogger::get()->warn(AddLineNumber((Formatter::format(),"an object with the id #",id," already exists"),line));
@ -239,6 +315,10 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
db.InternInsert(new LazyObject(db,id,line,sz,copysz)); db.InternInsert(new LazyObject(db,id,line,sz,copysz));
} }
if(!has_next) {
++splitter;
}
} }
if (!splitter) { if (!splitter) {