Don't print the fixed name ("main") of the top-level default class when saving XMLs.
Also insert newlines between top level sections in saved XML. PiperOrigin-RevId: 646802227 Change-Id: If16b93409bda88aee8ef75f4a78d7ba0419fcfae
This commit is contained in:
committed by
Copybara-Service
parent
6be4e0697e
commit
8c380e7ba4
@@ -69,7 +69,45 @@ static string WriteDoc(XMLDocument& doc, char *error, size_t error_sz) {
|
||||
mjCopyError(error, doc.ErrorStr(), error_sz);
|
||||
return "";
|
||||
}
|
||||
return string(stream.CStr());
|
||||
std::string str = string(stream.CStr());
|
||||
|
||||
// top level sections
|
||||
auto sections = {"<actuator", "<asset", "<compiler", "<contact",
|
||||
"<custom", "<default>", "<deformable", "<equality",
|
||||
"<extension", "<keyframe", "<option", "<sensor",
|
||||
"<size", "<statistic", "<tendon", "<visual",
|
||||
"<worldbody"};
|
||||
|
||||
// position of newline before first section
|
||||
size_t first_pos = std::string::npos;
|
||||
|
||||
// insert newlines before section headers
|
||||
for (const std::string& section : sections) {
|
||||
size_t pos = 0;
|
||||
while ((pos = str.find(section, pos)) != std::string::npos) {
|
||||
// find newline before this section
|
||||
size_t line_pos = str.rfind('\n', pos);
|
||||
|
||||
// save position of first section
|
||||
if (line_pos < first_pos) first_pos = line_pos;
|
||||
|
||||
// insert another newline
|
||||
if (line_pos != std::string::npos) {
|
||||
str.insert(line_pos + 1, "\n");
|
||||
pos++; // account for inserted newline
|
||||
}
|
||||
|
||||
// advance
|
||||
pos += section.length();
|
||||
}
|
||||
}
|
||||
|
||||
// remove added newline before the first section
|
||||
if (first_pos != std::string::npos) {
|
||||
str.erase(first_pos, 1);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -1143,7 +1181,9 @@ void mjXWriter::Default(XMLElement* root, mjCDef* def) {
|
||||
|
||||
// create section, write class name
|
||||
section = InsertEnd(root, "default");
|
||||
WriteAttrTxt(section, "class", def->name);
|
||||
if (def->name != "main") {
|
||||
WriteAttrTxt(section, "class", def->name);
|
||||
}
|
||||
|
||||
// mesh
|
||||
elem = InsertEnd(section, "mesh");
|
||||
|
||||
@@ -124,8 +124,8 @@ TEST_F(MujocoTest, SaveXmlShortString) {
|
||||
|
||||
std::array<char, 10> out;
|
||||
EXPECT_THAT(mj_saveXMLString(spec, out.data(), out.size(),
|
||||
error.data(), error.size()), 272);
|
||||
EXPECT_STREQ(error.data(), "Output string too short, should be at least 273");
|
||||
error.data(), error.size()), 273);
|
||||
EXPECT_STREQ(error.data(), "Output string too short, should be at least 274");
|
||||
|
||||
mj_deleteSpec(spec);
|
||||
mj_deleteModel(model);
|
||||
@@ -139,7 +139,7 @@ TEST_F(MujocoTest, SaveXml) {
|
||||
mjModel* model = mj_compile(spec, 0);
|
||||
EXPECT_THAT(model, NotNull()) << "Failed to compile model: " << error.data();
|
||||
|
||||
std::array<char, 273> out;
|
||||
std::array<char, 274> out;
|
||||
EXPECT_THAT(mj_saveXMLString(spec, out.data(), out.size(), error.data(),
|
||||
error.size()), 0) << error.data();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user