Fixed parsing of the config index.

This commit is contained in:
bubnikv 2018-04-11 15:17:41 +02:00
parent da2878958b
commit aaa8f133c0
5 changed files with 74 additions and 29 deletions

View File

@ -0,0 +1,13 @@
# This is an example configuration version index.
# The index contains version numbers
min_slic3r_version =1.39.0
0.2.0-alpha "some test comment"
max_slic3r_version= 1.39.4
0.1.0 another test comment
# some empty lines
# version without a comment
min_slic3r_version = 1.0.0
max_slic3r_version = 1.1.0
0.0.1

View File

@ -200,7 +200,7 @@ semver_parse_version (const char *str, semver_t *ver) {
slice = next + 1;
}
return 0;
return (index == 3) ? 0 : -1;
}
static int

View File

@ -57,6 +57,7 @@ void Snapshot::load_ini(const std::string &path)
// Parse snapshot.ini
std::string group_name_vendor = "Vendor:";
std::string key_filament = "filament";
std::string key_prefix_model = "model_";
for (auto &section : tree) {
if (section.first == "snapshot") {
// Parse the common section.
@ -107,10 +108,7 @@ void Snapshot::load_ini(const std::string &path)
VendorConfig vc;
vc.name = section.first.substr(group_name_vendor.size());
for (auto &kvp : section.second) {
if (boost::starts_with(kvp.first, "model_")) {
//model:MK2S = 0.4;xxx
//model:MK3 = 0.4;xxx
} else if (kvp.first == "version" || kvp.first == "min_slic3r_version" || kvp.first == "max_slic3r_version") {
if (kvp.first == "version" || kvp.first == "min_slic3r_version" || kvp.first == "max_slic3r_version") {
// Version of the vendor specific config bundle bundled with this snapshot.
auto semver = Semver::parse(kvp.second.data());
if (! semver)
@ -121,8 +119,16 @@ void Snapshot::load_ini(const std::string &path)
vc.min_slic3r_version = *semver;
else
vc.max_slic3r_version = *semver;
} else if (boost::starts_with(kvp.first, key_prefix_model) && kvp.first.size() > key_prefix_model.size()) {
// Parse the printer variants installed for the current model.
auto &set_variants = vc.models_variants_installed[kvp.first.substr(key_prefix_model.size())];
std::vector<std::string> variants;
if (unescape_strings_cstyle(kvp.second.data(), variants))
for (auto &variant : variants)
set_variants.insert(std::move(variant));
}
}
this->vendor_configs.emplace_back(std::move(vc));
}
}
}
@ -155,6 +161,14 @@ void Snapshot::save_ini(const std::string &path)
c << "version = " << vc.version.to_string() << std::endl;
c << "min_slic3r_version = " << vc.min_slic3r_version.to_string() << std::endl;
c << "max_slic3r_version = " << vc.max_slic3r_version.to_string() << std::endl;
// Export installed printer models and their variants.
for (const auto &model : vc.models_variants_installed) {
if (model.second.size() == 0)
continue;
const std::vector<std::string> variants(model.second.begin(), model.second.end());
const auto escaped = escape_strings_cstyle(variants);
c << "model_" << model.first << " = " << escaped << std::endl;
}
}
c.close();
}

View File

@ -40,12 +40,13 @@ inline std::string unquote_value(char *value, char *end, const std::string &path
if (value == end) {
// Empty string is a valid string.
} else if (*value == '"') {
if (++ value < -- end || *end != '"')
if (++ value > -- end || *end != '"')
throw file_parser_error("String not enquoted correctly", path, idx_line);
*end = 0;
if (! unescape_string_cstyle(value, svalue))
throw file_parser_error("Invalid escape sequence inside a quoted string", path, idx_line);
}
} else
svalue.assign(value, end);
return svalue;
}
@ -55,12 +56,13 @@ inline std::string unquote_version_comment(char *value, char *end, const std::st
if (value == end) {
// Empty string is a valid string.
} else if (*value == '"') {
if (++ value < -- end || *end != '"')
if (++ value > -- end || *end != '"')
throw file_parser_error("Version comment not enquoted correctly", path, idx_line);
*end = 0;
if (! unescape_string_cstyle(value, svalue))
throw file_parser_error("Invalid escape sequence inside a quoted version comment", path, idx_line);
}
} else
svalue.assign(value, end);
return svalue;
}
@ -77,41 +79,55 @@ size_t Index::load(const boost::filesystem::path &path)
++ idx_line;
// Skip the initial white spaces.
char *key = left_trim(const_cast<char*>(line.data()));
if (*key == '#')
// Skip a comment line.
continue;
// Right trim the line.
char *end = right_trim(key);
if (key == end)
// Skip an empty line.
continue;
// Keyword may only contain alphanumeric characters. Semantic version may in addition contain "+.-".
char *key_end = key;
bool maybe_semver = false;
for (;; ++ key) {
if (strchr("+.-", *key) != nullptr)
maybe_semver = true;
else if (! std::isalnum(*key))
bool maybe_semver = true;
for (; *key_end != 0; ++ key_end) {
if (std::isalnum(*key_end) || strchr("+.-", *key_end) != nullptr) {
// It may be a semver.
} else if (*key_end == '_') {
// Cannot be a semver, but it may be a key.
maybe_semver = false;
} else
// End of semver or keyword.
break;
}
if (*key != 0 && *key != ' ' && *key != '\t' && *key != '=')
if (*key_end != 0 && *key_end != ' ' && *key_end != '\t' && *key_end != '=')
throw file_parser_error("Invalid keyword or semantic version", path, idx_line);
char *value = left_trim(key_end);
bool key_value_pair = *value == '=';
if (key_value_pair)
value = left_trim(value + 1);
*key_end = 0;
boost::optional<Semver> semver;
if (maybe_semver)
semver = Semver::parse(key);
char *value = left_trim(key_end);
if (*value == '=') {
if (key_value_pair) {
if (semver)
throw file_parser_error("Key cannot be a semantic version", path, idx_line);
throw file_parser_error("Key cannot be a semantic version", path, idx_line);\
// Verify validity of the key / value pair.
std::string svalue = unquote_value(left_trim(++ value), end, path.string(), idx_line);
if (key == "min_sic3r_version" || key == "max_slic3r_version") {
std::string svalue = unquote_value(value, end, path.string(), idx_line);
if (strcmp(key, "min_slic3r_version") == 0 || strcmp(key, "max_slic3r_version") == 0) {
if (! svalue.empty())
semver = Semver::parse(key);
semver = Semver::parse(svalue);
if (! semver)
throw file_parser_error(std::string(key) + " must referece a valid semantic version", path, idx_line);
if (key == "min_sic3r_version")
if (strcmp(key, "min_slic3r_version") == 0)
ver.min_slic3r_version = *semver;
else
ver.max_slic3r_version = *semver;
} else {
// Ignore unknown keys, as there may come new keys in the future.
}
continue;
}
if (! semver)
throw file_parser_error("Invalid semantic version", path, idx_line);

View File

@ -55,9 +55,9 @@ public:
Semver(const Semver &other) : ver(other.ver)
{
if (other.ver.metadata != nullptr)
std::strcpy(ver.metadata, other.ver.metadata);
ver.metadata = strdup(other.ver.metadata);
if (other.ver.prerelease != nullptr)
std::strcpy(ver.prerelease, other.ver.prerelease);
ver.prerelease = strdup(other.ver.prerelease);
}
Semver &operator=(Semver &&other)
@ -73,8 +73,10 @@ public:
{
::semver_free(&ver);
ver = other.ver;
if (other.ver.metadata != nullptr) { std::strcpy(ver.metadata, other.ver.metadata); }
if (other.ver.prerelease != nullptr) { std::strcpy(ver.prerelease, other.ver.prerelease); }
if (other.ver.metadata != nullptr)
ver.metadata = strdup(other.ver.metadata);
if (other.ver.prerelease != nullptr)
ver.prerelease = strdup(other.ver.prerelease);
return *this;
}