Skip to content

Commit

Permalink
Fix segfault with imports across multiple directories
Browse files Browse the repository at this point in the history
  • Loading branch information
agarny authored Nov 24, 2024
2 parents d84057b + bd0b2e9 commit b3fb67a
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ struct Debug
bool mNewLine;
};

void listModelsUnits(const ModelPtr &model);
void printAnalyserModelEquations(const AnalyserModelPtr &model);
void printAnalyserModelVariables(const AnalyserModelPtr &model);
void printAstAsTree(const AnalyserEquationAstPtr &ast);
Expand All @@ -101,16 +102,15 @@ void printComponentMap(const ComponentMap &map);
void printConnectionMap(const ConnectionMap &map);
void printEquivalenceMap(const EquivalenceMap &map);
void printEquivalenceMapWithModelInfo(const EquivalenceMap &map, const ModelPtr &model);
void printEquivalences(const VariablePtr &variable);
void printHistory(const History &history);
void printHistoryEpoch(const HistoryEpochPtr &historyEpoch);
void printImportLibrary(const ImportLibrary &importlibrary);
void printNamedPath(const ParentedEntityPtr &parented);
void printStack(const IndexStack &stack);
void printStackWithModelInfo(const IndexStack &stack, const ModelPtr &model);
void printStringStringMap(const StringStringMap &map);
void printVariableMap(const VariableMap &map);
void printUnits(const UnitsPtr &units);
void listModelsUnits(const ModelPtr &model);
void printNamedPath(const ParentedEntityPtr &parented);
void printEquivalences(const VariablePtr &variable);
void printVariableMap(const VariableMap &map);

} // namespace libcellml
2 changes: 1 addition & 1 deletion src/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ ComponentPtr flattenComponent(const ComponentEntityPtr &parent, ComponentPtr &co
}
}

auto replacementUnits = (flattenedUnits != nullptr) ? flattenedUnits->clone() : units;
auto replacementUnits = (flattenedUnits != nullptr) ? flattenedUnits : units;

for (size_t unitIndex = 0; unitIndex < replacementUnits->unitCount(); ++unitIndex) {
const std::string ref = replacementUnits->unitAttributeReference(unitIndex);
Expand Down
25 changes: 25 additions & 0 deletions tests/importer/model_flattening.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1918,3 +1918,28 @@ TEST(ModelFlattening, modelWithCnUnitsNotDefinedInImportedComponent)
EXPECT_EQ(size_t(1), importer->errorCount());
EXPECT_EQ("The model is not fully defined.", importer->error(0)->description());
}

TEST(ModelFlattening, multiLayeredImportOfNonStandardUnits)
{
auto parser = libcellml::Parser::create(false);
auto model = parser->parseModel(fileContents("importer/periodicstimulus/experiments/periodic-stimulus.xml"));

EXPECT_EQ(size_t(0), parser->errorCount());

auto validator = libcellml::Validator::create();

validator->validateModel(model);

EXPECT_EQ(size_t(0), validator->issueCount());
EXPECT_TRUE(model->hasUnresolvedImports());

auto importer = libcellml::Importer::create(false);

importer->resolveImports(model, resourcePath("importer/periodicstimulus/experiments"));

EXPECT_FALSE(model->hasUnresolvedImports());

auto flattenModel = importer->flattenModel(model);

EXPECT_NE(nullptr, flattenModel);
}
9 changes: 9 additions & 0 deletions tests/resources/importer/periodicstimulus/components/INa.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version='1.0' encoding='UTF-8'?>
<model name="INa" xmlns="http://www.cellml.org/cellml/1.1#" xmlns:cellml="http://www.cellml.org/cellml/1.1#" xmlns:cmeta="http://www.cellml.org/metadata/1.0#" xmlns:xlink="http://www.w3.org/1999/xlink">
<import xlink:href="units.xml">
<units name="uA_per_cmsq" units_ref="uA_per_cmsq"/>
</import>
<component name="INa">
<variable name="INa" private_interface="out" public_interface="out" units="uA_per_cmsq"/>
</component>
</model>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version='1.0' encoding='UTF-8'?>
<model name="stimulated" xmlns="http://www.cellml.org/cellml/1.1#" xmlns:cellml="http://www.cellml.org/cellml/1.1#" xmlns:cmeta="http://www.cellml.org/metadata/1.0#" xmlns:xlink="http://www.w3.org/1999/xlink">
<import xlink:href="units.xml">
<units name="uA_per_cmsq" units_ref="uA_per_cmsq"/>
</import>
<import xlink:href="INa.xml">
<component component_ref="INa" name="INa"/>
</import>
<component name="action_potential">
<!-- <variable name="Istim" private_interface="out" public_interface="in" units="uA_per_cmsq"/>-->
<variable name="INa" private_interface="in" public_interface="out" units="uA_per_cmsq"/>
</component>
<group>
<relationship_ref relationship="encapsulation"/>
<component_ref component="action_potential">
<component_ref component="INa"/>
</component_ref>
</group>
<connection>
<map_components component_1="action_potential" component_2="INa"/>
<map_variables variable_1="INa" variable_2="INa"/>
</connection>
</model>
13 changes: 13 additions & 0 deletions tests/resources/importer/periodicstimulus/components/units.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version='1.0' encoding='UTF-8'?>
<model name="units" xmlns="http://www.cellml.org/cellml/1.1#" xmlns:cellml="http://www.cellml.org/cellml/1.1#">
<units name="cm">
<unit prefix="centi" units="metre"/>
</units>
<units name="uA">
<unit prefix="micro" units="ampere"/>
</units>
<units name="uA_per_cmsq">
<unit units="uA"/>
<unit exponent="-2" units="cm"/>
</units>
</model>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version='1.0' encoding='UTF-8'?>
<model name="periodic_stimulus" xmlns="http://www.cellml.org/cellml/1.1#" xmlns:cellml="http://www.cellml.org/cellml/1.1#" xmlns:xlink="http://www.w3.org/1999/xlink">
<import xlink:href="../components/units.xml">
<units name="uA_per_cmsq" units_ref="uA_per_cmsq"/>
</import>
<import xlink:href="../components/stimulated.xml">
<component component_ref="action_potential" name="_model"/>
</import>
</model>
4 changes: 2 additions & 2 deletions tests/test_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ static const std::string FIXED_INDENT = " ";

void printComponent(const libcellml::ComponentPtr &component, size_t c, const std::string &indent, bool includeMaths)
{
if (c == -1) {
if (c == SIZE_MAX) {
std::cout << "COMPONENT: '" << component->name() << "'";
} else {
std::cout << indent << "[" << c + 1 << "]: " << component->name();
Expand Down Expand Up @@ -162,7 +162,7 @@ void printComponent(const libcellml::ComponentPtr &component, size_t c, const st

void printComponent(const libcellml::ComponentPtr &component, bool includeMaths)
{
printComponent(component, -1, {}, includeMaths);
printComponent(component, SIZE_MAX, {}, includeMaths);
}

void printModel(const libcellml::ModelPtr &model, bool includeMaths)
Expand Down

0 comments on commit b3fb67a

Please sign in to comment.