Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix segfault with imports across multiple directories #1304

Merged
merged 6 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
2 changes: 1 addition & 1 deletion 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_t(-1)) {
agarny marked this conversation as resolved.
Show resolved Hide resolved
std::cout << "COMPONENT: '" << component->name() << "'";
} else {
std::cout << indent << "[" << c + 1 << "]: " << component->name();
Expand Down
Loading