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

1724 Enable loading of TOML files #1742

Merged
merged 7 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion src/base/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ template <> struct from<Geometry::GeometryType>
else if (typeString == "torsion")
return Geometry::GeometryType::TorsionType;
else
throw toml::syntax_error(
throw toml::type_error(
fmt::format("Unhandled geometry type '{}' - can't convert from TOML value.\n", std::string(typeString)),
node.location());
}
Expand Down
2 changes: 1 addition & 1 deletion src/classes/isotopologues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void Isotopologues::deserialise(const SerialisedValue &node, const CoreData &cor
{
auto iso = species_->findIsotopologue(name);
if (!iso)
throw toml::syntax_error(fmt::format("Cannot find iso {}", name), location);
throw toml::type_error(fmt::format("Cannot find iso {}", name), location);
add(iso, item.as_floating());
});
}
2 changes: 1 addition & 1 deletion src/classes/speciesIntra.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ template <class Intra, class Functions> class SpeciesIntra : public Serialisable
[&map](const auto &name) { return map[name]; });
break;
default:
throw toml::syntax_error("Cannot understand parameter value", node.location());
throw toml::type_error("Cannot understand parameter value", node.location());
}
setInteractionFormAndParameters(interactionForm(), values);
});
Expand Down
8 changes: 4 additions & 4 deletions src/keywords/atomTypeVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ void AtomTypeVectorKeyword::deserialise(const SerialisedValue &node, const CoreD
[&item](const auto atomType)
{ return DissolveSys::sameString(atomType->name(), std::string_view(std::string(item.as_string()))); });
if (it == coreData.atomTypes().end())
throw toml::syntax_error(fmt::format("Unrecognised AtomType '{}' given to '{}' keyword.\n",
std::string(item.as_string()), name()),
item.location());
throw toml::type_error(fmt::format("Unrecognised AtomType '{}' given to '{}' keyword.\n",
std::string(item.as_string()), name()),
item.location());
auto atomType = *it;

// If the AtomType is already present, complain
if (std::find(data_.begin(), data_.end(), atomType) != data_.end())
throw toml::syntax_error(
throw toml::type_error(
fmt::format("AtomType '{}' specified in selection twice.\n", std::string(item.as_string())),
item.location());

Expand Down
6 changes: 3 additions & 3 deletions src/keywords/configurationVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ void ConfigurationVectorKeyword::deserialise(const SerialisedValue &node, const
{
auto *cfg = coreData.findConfiguration(std::string_view(std::string(name.as_string())));
if (!cfg)
throw toml::syntax_error(
throw toml::type_error(
fmt::format("Error defining Configuration targets - no Configuration named '{}' exists.\n",
std::string(name.as_string())),
name.location());

// Check that the configuration isn't already present
if (std::find(data_.begin(), data_.end(), cfg) != data_.end())
throw toml::syntax_error(fmt::format("Configuration '{}' has already been referenced.\n", cfg->name()),
name.location());
throw toml::type_error(fmt::format("Configuration '{}' has already been referenced.\n", cfg->name()),
name.location());

data_.push_back(cfg);
});
Expand Down
2 changes: 1 addition & 1 deletion src/keywords/layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void LayerKeyword::deserialise(const SerialisedValue &node, const CoreData &core
{
data_ = coreData.findProcessingLayer(std::string(node.as_string()));
if (!data_)
throw toml::syntax_error(
throw toml::type_error(
fmt::format("Layer '{}' given to keyword {} doesn't exist.\n", std::string(node.as_string()), KeywordBase::name()),
node.location());
}
Expand Down
6 changes: 3 additions & 3 deletions src/keywords/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ template <class M> class ModuleKeyword : public ModuleKeywordBase
{
auto *module = Module::find(std::string(node.as_string()));
if (!module)
throw toml::syntax_error(fmt::format("Module '{}' given to keyword {} doesn't exist.\n",
std::string(node.as_string()), KeywordBase::name()),
node.location());
throw toml::type_error(fmt::format("Module '{}' given to keyword {} doesn't exist.\n",
std::string(node.as_string()), KeywordBase::name()),
node.location());

setData(module);
}
Expand Down
4 changes: 2 additions & 2 deletions src/keywords/moduleVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ void ModuleVectorKeyword::deserialise(const SerialisedValue &node, const CoreDat
auto title = toml::get<std::string>(item);
auto *module = Module::find(title);
if (!module)
throw toml::syntax_error(fmt::format("No Module named '{}' exists.\n", title), item.location());
throw toml::type_error(fmt::format("No Module named '{}' exists.\n", title), item.location());

// Check the module's type if we can
if (!moduleTypes_.empty() &&
std::find_if(moduleTypes_.cbegin(), moduleTypes_.cend(),
[module](const auto &s) { return s == module->type(); }) == moduleTypes_.cend())
throw toml::syntax_error(
throw toml::type_error(
fmt::format("Module '{}' is of type '{}', and is not relevant to keyword '{}' (allowed types = {}).\n",
title, module->type(), name(), joinStrings(moduleTypes_)),
item.location());
Expand Down
4 changes: 2 additions & 2 deletions src/keywords/nodeAndInteger.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class NodeAndIntegerKeywordBase : public NodeKeywordUnderlay, public KeywordBase
auto nodeName = toml::find<std::string>(node, "node");
auto realNode = findNode(nodeName);
if (!realNode)
throw toml::syntax_error(
fmt::format("Node '{}' given to keyword {} doesn't exist.\n", nodeName, KeywordBase::name()), node.location());
throw toml::type_error(fmt::format("Node '{}' given to keyword {} doesn't exist.\n", nodeName, KeywordBase::name()),
node.location());

setInteger(toml::find<int>(node, "int"));
setNode(realNode);
Expand Down
8 changes: 4 additions & 4 deletions src/keywords/nodeVector.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,12 @@ template <class N> class NodeVectorKeyword : public NodeVectorKeywordBase

ConstNodeRef noderef = findNode(nodeName);
if (!noderef)
throw toml::syntax_error(fmt::format("Node '{}' given to keyword {} doesn't exist.\n",
std::string(item.as_string()), name()),
item.location());
throw toml::type_error(fmt::format("Node '{}' given to keyword {} doesn't exist.\n",
std::string(item.as_string()), name()),
item.location());

if (!validNode(noderef.get(), name()))
throw toml::syntax_error(fmt::format("Invalid node: {}", name()), item.location());
throw toml::type_error(fmt::format("Invalid node: {}", name()), item.location());

data_.push_back(std::dynamic_pointer_cast<const N>(noderef));
});
Expand Down
8 changes: 4 additions & 4 deletions src/keywords/speciesSite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,19 @@ void SpeciesSiteKeyword::deserialise(const SerialisedValue &node, const CoreData
Species *sp = coreData.findSpecies(species);
if (!sp)
{
throw toml::syntax_error(fmt::format("Error setting SpeciesSite - no Species named '{}' exists.\n", species),
node.location());
throw toml::type_error(fmt::format("Error setting SpeciesSite - no Species named '{}' exists.\n", species),
node.location());
}

// Find specified Site (second argument) in the Species
data_ = sp->findSite(site);
if (!data_)
throw toml::syntax_error(
throw toml::type_error(
fmt::format("Error setting SpeciesSite - no such site named '{}' exists in Species '{}'.\n", site, sp->name()),
node.location());

if (axesRequired_ && (!data_->hasAxes()))
throw toml::syntax_error(
throw toml::type_error(
fmt::format("Can't select site '{}' for keyword '{}', as the keyword requires axes specifications to be present.\n",
data_->name(), name()),
node.location());
Expand Down
8 changes: 4 additions & 4 deletions src/keywords/speciesSiteVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ void SpeciesSiteVectorKeyword::deserialise(const SerialisedValue &node, const Co
if (site)
data_.push_back(site);
else
throw toml::syntax_error(fmt::format("Cannot find Site {}", toml::find<std::string>(item, "site")),
item.location());
throw toml::type_error(fmt::format("Cannot find Site {}", toml::find<std::string>(item, "site")),
item.location());
}
else
toml::syntax_error(fmt::format("Cannot find Species {}", toml::find<std::string>(item, "species")),
item.location());
toml::type_error(fmt::format("Cannot find Species {}", toml::find<std::string>(item, "species")),
item.location());
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/keywords/speciesVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void SpeciesVectorKeyword::deserialise(const SerialisedValue &node, const CoreDa
auto title = toml::get<std::string>(item);
auto *species = coreData.findSpecies(title);
if (!species)
throw toml::syntax_error(fmt::format("No Species named '{}' exists.\n", title), item.location());
throw toml::type_error(fmt::format("No Species named '{}' exists.\n", title), item.location());

data_.push_back(species);
});
Expand Down
4 changes: 2 additions & 2 deletions src/keywords/weightedModuleVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ void WeightedModuleVectorKeyword::deserialise(const SerialisedValue &node, const
auto moduleName = toml::find<std::string>(item, "target");
auto *module = Module::find(moduleName);
if (!module)
throw toml::syntax_error(fmt::format("No Module named '{}' exists.\n", moduleName), item.location());
throw toml::type_error(fmt::format("No Module named '{}' exists.\n", moduleName), item.location());

// Check the module's type if we can
if (!moduleTypes_.empty() &&
std::find_if(moduleTypes_.cbegin(), moduleTypes_.cend(),
[module](const auto &s) { return s == module->type(); }) == moduleTypes_.cend())
throw toml::syntax_error(
throw toml::type_error(
fmt::format("Module '{}' is of type '{}', and is not relevant to keyword '{}' (allowed types = {}).\n",
moduleName, module->type(), name(), joinStrings(moduleTypes_)),
item.location());
Expand Down
67 changes: 59 additions & 8 deletions src/main/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
#include "main/keywords.h"
#include "main/version.h"
#include <cstring>
#include <fstream>
#include <functional>
#include <map>
#include <toml/parser.hpp>

// Load input file through supplied parser
bool Dissolve::loadInput(LineParser &parser)
Expand Down Expand Up @@ -221,19 +223,68 @@ void Dissolve::deserialise(const SerialisedValue &originalNode)
// Load input from supplied file
bool Dissolve::loadInput(std::string_view filename)
{
// Open file and check that we're OK to proceed reading from it
LineParser parser(&worldPool());
if (!parser.openInput(filename))
// If the file name ends in TOML, insist on a TOML parse
if (filename.find(".toml") == filename.size() - 5)
{
try
{
SerialisedValue contents = toml::parse(std::string(filename));
deserialise(contents);
return true;
}
catch (toml::syntax_error e)
{
Messenger::error("Syntax error in TOML file (are you sure you meant the .toml extension?).\n\n{}", e.what());
}
catch (toml::type_error e)
{
Messenger::error("Could not load TOML file\n\n{}", e.what());
}
return false;
}

auto result = loadInput(parser);
if (result)
// Fail if the file starts with restart header
{
std::ifstream infile{std::string(filename)};
std::string firstLine;
infile >> firstLine;
infile.close();
if (firstLine.find("# Restart file") == 0)
{
Messenger::error("File {} is a restart file and not an input file", filename);
return false;
}
}

try
{
Messenger::print("Finished reading input file.\n");
setInputFilename(filename);
SerialisedValue contents = toml::parse(std::string(filename));
deserialise(contents);
return true;
}
catch (toml::syntax_error e)
{
// The file didn't have TOML syntax, so try the original parser
// Open file and check that we're OK to proceed reading from it
LineParser parser(&worldPool());
if (!parser.openInput(filename))
return false;

return result;
auto result = loadInput(parser);
if (result)
{
Messenger::print("Finished reading input file.\n");
setInputFilename(filename);
}

return result;
}
catch (toml::type_error e)
{
// The file *was* a TOML file, but it had problems loading
Messenger::error("Could not load TOML file\n\n{}", e.what());
}
return false;
}

// Save input file
Expand Down
Loading