From 31ea03feb0af7376a35aa3b3428684b1e59d4a15 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Wed, 11 Apr 2018 13:12:08 +0200 Subject: [PATCH 1/3] ConfigWizard: Make bundle installation more intelligent, fixes --- xs/src/slic3r/Config/Snapshot.cpp | 4 +- xs/src/slic3r/GUI/AppConfig.cpp | 19 +++++++ xs/src/slic3r/GUI/AppConfig.hpp | 3 ++ xs/src/slic3r/GUI/ConfigWizard.cpp | 9 ++-- xs/src/slic3r/GUI/Preset.cpp | 75 ++++++++++++++++++++++++++- xs/src/slic3r/GUI/Preset.hpp | 11 +++- xs/src/slic3r/GUI/PresetBundle.cpp | 43 +-------------- xs/src/slic3r/Utils/PresetUpdater.cpp | 32 +++++++----- xs/src/slic3r/Utils/PresetUpdater.hpp | 4 +- xs/src/slic3r/Utils/Semver.hpp | 19 ++++++- xs/xsp/GUI.xsp | 8 ++- 11 files changed, 159 insertions(+), 68 deletions(-) diff --git a/xs/src/slic3r/Config/Snapshot.cpp b/xs/src/slic3r/Config/Snapshot.cpp index eeb5b6ac5..b6c356576 100644 --- a/xs/src/slic3r/Config/Snapshot.cpp +++ b/xs/src/slic3r/Config/Snapshot.cpp @@ -275,7 +275,7 @@ const Snapshot& SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot: // Snapshot header. snapshot.time_captured = Slic3r::Utils::get_current_time_utc(); snapshot.id = Slic3r::Utils::format_time_ISO8601Z(snapshot.time_captured); - snapshot.slic3r_version_captured = *Semver::parse(SLIC3R_VERSION); + snapshot.slic3r_version_captured = *Semver::parse(SLIC3R_VERSION); // XXX: have Semver Slic3r version snapshot.comment = comment; snapshot.reason = reason; // Active presets at the time of the snapshot. @@ -299,7 +299,7 @@ const Snapshot& SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot: bundle.load_configbundle((data_dir / "vendor" / (cfg.name + ".ini")).string(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY); for (const VendorProfile &vp : bundle.vendors) if (vp.id == cfg.name) - cfg.version = *Semver::parse(vp.config_version); + cfg.version = vp.config_version; // Fill-in the min/max slic3r version from the config index, if possible. try { // Load the config index for the vendor. diff --git a/xs/src/slic3r/GUI/AppConfig.cpp b/xs/src/slic3r/GUI/AppConfig.cpp index 9e5ce5f1b..ee77f877a 100644 --- a/xs/src/slic3r/GUI/AppConfig.cpp +++ b/xs/src/slic3r/GUI/AppConfig.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -228,9 +229,27 @@ bool AppConfig::version_check_enabled() const bool AppConfig::slic3r_update_avail() const { + // FIXME: Update with Semver + // TODO: probably need to move semver to libslic3r return version_check_enabled() && get("version_online") != SLIC3R_VERSION; } +Semver AppConfig::get_slic3r_version() const +{ + // TODO: move to Semver c-tor (???) + auto res = Semver::parse(get("version")); + if (! res) { + throw std::runtime_error(std::string("Could not parse Slic3r version string in application config.")); + } else { + return *res; + } +} + +void AppConfig::set_slic3r_version(const Semver &version) +{ + set("version", version.to_string()); +} + std::string AppConfig::config_path() { return (boost::filesystem::path(Slic3r::data_dir()) / "slic3r.ini").make_preferred().string(); diff --git a/xs/src/slic3r/GUI/AppConfig.hpp b/xs/src/slic3r/GUI/AppConfig.hpp index 40b3a12fd..cac2759f1 100644 --- a/xs/src/slic3r/GUI/AppConfig.hpp +++ b/xs/src/slic3r/GUI/AppConfig.hpp @@ -6,6 +6,7 @@ #include #include "libslic3r/Config.hpp" +#include "slic3r/Utils/Semver.hpp" namespace Slic3r { @@ -91,6 +92,8 @@ public: // Whether the Slic3r version available online differs from this one bool version_check_enabled() const; bool slic3r_update_avail() const; + Semver get_slic3r_version() const; + void set_slic3r_version(const Semver &version); // Get the default config path from Slic3r::data_dir(). static std::string config_path(); diff --git a/xs/src/slic3r/GUI/ConfigWizard.cpp b/xs/src/slic3r/GUI/ConfigWizard.cpp index f13448c37..0c2a9dd59 100644 --- a/xs/src/slic3r/GUI/ConfigWizard.cpp +++ b/xs/src/slic3r/GUI/ConfigWizard.cpp @@ -15,6 +15,7 @@ #include "libslic3r/Utils.hpp" #include "PresetBundle.hpp" #include "GUI.hpp" +#include "slic3r/Utils/PresetUpdater.hpp" namespace fs = boost::filesystem; @@ -699,12 +700,8 @@ ConfigWizard::~ConfigWizard() {} bool ConfigWizard::run(wxWindow *parent, PresetBundle *preset_bundle) { - const auto profiles_dir = fs::path(resources_dir()) / "profiles"; - for (fs::directory_iterator it(profiles_dir); it != fs::directory_iterator(); ++it) { - if (it->path().extension() == ".ini") { - PresetBundle::install_vendor_configbundle(it->path()); - } - } + // FIXME: this should be done always at app startup + PresetUpdater::init_vendors(); ConfigWizard wizard(parent); if (wizard.ShowModal() == wxID_OK) { diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index 66836074e..39bfbd398 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -24,14 +25,16 @@ #include "../../libslic3r/Utils.hpp" #include "../../libslic3r/PlaceholderParser.hpp" +using boost::property_tree::ptree; + namespace Slic3r { -ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree) +ConfigFileType guess_config_file_type(const ptree &tree) { size_t app_config = 0; size_t bundle = 0; size_t config = 0; - for (const boost::property_tree::ptree::value_type &v : tree) { + for (const ptree::value_type &v : tree) { if (v.second.empty()) { if (v.first == "background_processing" || v.first == "last_output_path" || @@ -59,6 +62,74 @@ ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree) (bundle > config) ? CONFIG_FILE_TYPE_CONFIG_BUNDLE : CONFIG_FILE_TYPE_CONFIG; } + +VendorProfile VendorProfile::from_ini(const boost::filesystem::path &path, bool load_all) +{ + ptree tree; + boost::filesystem::ifstream ifs(path); + boost::property_tree::read_ini(ifs, tree); + return VendorProfile::from_ini(tree, path, load_all); +} + +VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem::path &path, bool load_all) +{ + static const std::string printer_model_key = "printer_model:"; + const std::string id = path.stem().string(); + VendorProfile res(id); + + auto get_or_throw = [&](const ptree &tree, const std::string &key) -> ptree::const_assoc_iterator + { + auto res = tree.find(key); + if (res == tree.not_found()) { + throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Missing secion or key: `%2%`.") % id % key).str()); + } + return res; + }; + + const auto &vendor_section = get_or_throw(tree, "vendor")->second; + res.name = get_or_throw(vendor_section, "name")->second.data(); + + auto config_version_str = get_or_throw(vendor_section, "config_version")->second.data(); + auto config_version = Semver::parse(config_version_str); + if (! config_version) { + throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Cannot parse config_version: `%2%`.") % id % config_version_str).str()); + } else { + res.config_version = std::move(*config_version); + } + + auto config_update_url = vendor_section.find("config_update_url"); + if (config_update_url != vendor_section.not_found()) { + res.config_update_url = config_update_url->second.data(); + } + + if (! load_all) { + return res; + } + + for (auto §ion : tree) { + if (boost::starts_with(section.first, printer_model_key)) { + VendorProfile::PrinterModel model; + model.id = section.first.substr(printer_model_key.size()); + model.name = section.second.get("name", model.id); + section.second.get("variants", ""); + std::vector variants; + if (Slic3r::unescape_strings_cstyle(section.second.get("variants", ""), variants)) { + for (const std::string &variant_name : variants) { + if (model.variant(variant_name) == nullptr) + model.variants.emplace_back(VendorProfile::PrinterVariant(variant_name)); + } + } else { + // Log error? // XXX + } + if (! model.id.empty() && ! model.variants.empty()) + res.models.push_back(std::move(model)); + } + } + + return res; +} + + // Suffix to be added to a modified preset name in the combo box. static std::string g_suffix_modified = " (modified)"; const std::string& Preset::suffix_modified() diff --git a/xs/src/slic3r/GUI/Preset.hpp b/xs/src/slic3r/GUI/Preset.hpp index 4f734b85e..d6ccfd450 100644 --- a/xs/src/slic3r/GUI/Preset.hpp +++ b/xs/src/slic3r/GUI/Preset.hpp @@ -3,8 +3,12 @@ #include +#include +#include + #include "../../libslic3r/libslic3r.h" #include "../../libslic3r/PrintConfig.hpp" +#include "slic3r/Utils/Semver.hpp" class wxBitmap; class wxChoice; @@ -30,7 +34,7 @@ class VendorProfile public: std::string name; std::string id; - std::string config_version; + Semver config_version; std::string config_update_url; struct PrinterVariant { @@ -54,7 +58,10 @@ public: }; std::vector models; - VendorProfile(std::string id) : id(std::move(id)) {} + VendorProfile(std::string id) : id(std::move(id)), config_version(0, 0, 0) {} + + static VendorProfile from_ini(const boost::filesystem::path &path, bool load_all=true); + static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true); size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; } diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp index bd9e35ca8..ad27bf8c6 100644 --- a/xs/src/slic3r/GUI/PresetBundle.cpp +++ b/xs/src/slic3r/GUI/PresetBundle.cpp @@ -105,7 +105,7 @@ void PresetBundle::setup_directories() std::initializer_list paths = { data_dir, data_dir / "vendor", - data_dir / "cache", // TODO: rename as vendor-cache? (Check usage elsewhere!) + data_dir / "cache", #ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR // Store the print/filament/printer presets into a "presets" directory. data_dir / "presets", @@ -672,42 +672,6 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree) flatten_configbundle_hierarchy(tree, "printer"); } -static void load_vendor_profile(const boost::property_tree::ptree &tree, VendorProfile &vendor_profile) -{ - const std::string printer_model_key = "printer_model:"; - for (auto §ion : tree) { - if (section.first == "vendor") { - // Load the names of the active presets. - for (auto &kvp : section.second) { - if (kvp.first == "name") - vendor_profile.name = kvp.second.data(); - else if (kvp.first == "id") - vendor_profile.id = kvp.second.data(); - else if (kvp.first == "config_version") - vendor_profile.config_version = kvp.second.data(); - else if (kvp.first == "config_update_url") - vendor_profile.config_update_url = kvp.second.data(); - } - } else if (boost::starts_with(section.first, printer_model_key)) { - VendorProfile::PrinterModel model; - model.id = section.first.substr(printer_model_key.size()); - model.name = section.second.get("name", model.id); - section.second.get("variants", ""); - std::vector variants; - if (Slic3r::unescape_strings_cstyle(section.second.get("variants", ""), variants)) { - for (const std::string &variant_name : variants) { - if (model.variant(variant_name) == nullptr) - model.variants.emplace_back(VendorProfile::PrinterVariant(variant_name)); - } - } else { - // Log error? - } - if (! model.id.empty() && ! model.variants.empty()) - vendor_profile.models.push_back(std::move(model)); - } - } -} - // Load a config bundle file, into presets and store the loaded presets into separate files // of the local configuration directory. void PresetBundle::install_vendor_configbundle(const std::string &src_path0) @@ -738,10 +702,7 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla const VendorProfile *vendor_profile = nullptr; if (flags & (LOAD_CFGBNDLE_SYSTEM | LOAD_CFGBUNDLE_VENDOR_ONLY)) { boost::filesystem::path fspath(path); - VendorProfile vp(fspath.stem().string()); - load_vendor_profile(tree, vp); - if (vp.name.empty()) - throw std::runtime_error(std::string("Vendor Config Bundle is not valid: Missing vendor name key.")); + auto vp = VendorProfile::from_ini(tree, fspath.stem().string()); if (vp.num_variants() == 0) return 0; vendor_profile = &(*this->vendors.insert(vp).first); diff --git a/xs/src/slic3r/Utils/PresetUpdater.cpp b/xs/src/slic3r/Utils/PresetUpdater.cpp index 040d326b5..a16a6d889 100644 --- a/xs/src/slic3r/Utils/PresetUpdater.cpp +++ b/xs/src/slic3r/Utils/PresetUpdater.cpp @@ -1,9 +1,8 @@ #include "PresetUpdater.hpp" -#include // XXX #include #include -#include +#include #include #include @@ -22,6 +21,7 @@ namespace Slic3r { // TODO: proper URL +// TODO: Actually, use index static const std::string SLIC3R_VERSION_URL = "https://gist.githubusercontent.com/vojtechkral/4d8fd4a3b8699a01ec892c264178461c/raw/e9187c3e15ceaf1a90f29b7c43cf3ccc746140f0/slic3rPE.version"; enum { SLIC3R_VERSION_BODY_MAX = 256, @@ -52,8 +52,6 @@ PresetUpdater::priv::priv(int event) : void PresetUpdater::priv::download(const std::set vendors) const { - std::cerr << "PresetUpdater::priv::download()" << std::endl; - if (!version_check) { return; } // Download current Slic3r version @@ -64,7 +62,6 @@ void PresetUpdater::priv::download(const std::set vendors) const }) .on_complete([&](std::string body, unsigned http_status) { boost::trim(body); - std::cerr << "Got version: " << http_status << ", body: \"" << body << '"' << std::endl; wxCommandEvent* evt = new wxCommandEvent(version_online_event); evt->SetString(body); GUI::get_app()->QueueEvent(evt); @@ -74,25 +71,19 @@ void PresetUpdater::priv::download(const std::set vendors) const if (!preset_update) { return; } // Donwload vendor preset bundles - std::cerr << "Bundle vendors: " << vendors.size() << std::endl; for (const auto &vendor : vendors) { - std::cerr << "vendor: " << vendor.name << std::endl; - std::cerr << " URL: " << vendor.config_update_url << std::endl; - if (cancel) { return; } // TODO: Proper caching auto target_path = cache_path / vendor.id; target_path += ".ini"; - std::cerr << "target_path: " << target_path << std::endl; Http::get(vendor.config_update_url) .on_progress([this](Http::Progress, bool &cancel) { cancel = this->cancel; }) .on_complete([&](std::string body, unsigned http_status) { - std::cerr << "Got ini: " << http_status << ", body: " << body.size() << std::endl; fs::fstream file(target_path, std::ios::out | std::ios::binary | std::ios::trunc); file.write(body.c_str(), body.size()); }) @@ -121,7 +112,6 @@ PresetUpdater::~PresetUpdater() void PresetUpdater::download(PresetBundle *preset_bundle) { - std::cerr << "PresetUpdater::download()" << std::endl; // Copy the whole vendors data for use in the background thread // Unfortunatelly as of C++11, it needs to be copied again @@ -133,5 +123,23 @@ void PresetUpdater::download(PresetBundle *preset_bundle) })); } +void PresetUpdater::init_vendors() +{ + const auto vendors_rources = fs::path(resources_dir()) / "profiles"; + const auto vendors_data = fs::path(Slic3r::data_dir()) / "vendor"; + + for (fs::directory_iterator it(vendors_rources); it != fs::directory_iterator(); ++it) { + if (it->path().extension() == ".ini") { + auto vp = VendorProfile::from_ini(it->path(), false); + const auto path_in_data = vendors_data / it->path().filename(); + + if (! fs::exists(path_in_data) || VendorProfile::from_ini(path_in_data, false).config_version < vp.config_version) { + // FIXME: update vendor bundle properly when snapshotting is ready + PresetBundle::install_vendor_configbundle(it->path()); + } + } + } +} + } diff --git a/xs/src/slic3r/Utils/PresetUpdater.hpp b/xs/src/slic3r/Utils/PresetUpdater.hpp index aafe9569b..b10c61784 100644 --- a/xs/src/slic3r/Utils/PresetUpdater.hpp +++ b/xs/src/slic3r/Utils/PresetUpdater.hpp @@ -19,7 +19,9 @@ public: PresetUpdater &operator=(const PresetUpdater &) = delete; ~PresetUpdater(); - void download(PresetBundle *preset_bundle); + void download(PresetBundle *preset_bundle); // XXX + + static void init_vendors(); private: struct priv; std::unique_ptr p; diff --git a/xs/src/slic3r/Utils/Semver.hpp b/xs/src/slic3r/Utils/Semver.hpp index bd8e9b758..2ac2ba700 100644 --- a/xs/src/slic3r/Utils/Semver.hpp +++ b/xs/src/slic3r/Utils/Semver.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -10,6 +11,7 @@ namespace Slic3r { +// FIXME:: operators=: leak, return class Semver { @@ -18,9 +20,22 @@ public: struct Minor { const int i; Minor(int i) : i(i) {} }; struct Patch { const int i; Patch(int i) : i(i) {} }; + Semver(int major, int minor, int patch, + boost::optional metadata = boost::none, + boost::optional prerelease = boost::none) + { + ver.major = major; + ver.minor = minor; + ver.patch = patch; + ver.metadata = metadata ? std::strcpy(ver.metadata, metadata->c_str()) : nullptr; + ver.prerelease = prerelease ? std::strcpy(ver.prerelease, prerelease->c_str()) : nullptr; + } + + // TODO: throwing ctor ??? + static boost::optional parse(const std::string &str) { - semver_t ver; + semver_t ver = semver_zero(); if (::semver_parse(str.c_str(), &ver) == 0) { return Semver(ver); } else { @@ -121,6 +136,8 @@ private: semver_t ver; Semver(semver_t ver) : ver(ver) {} + + static semver_t semver_zero() { return { 0, 0, 0, nullptr, nullptr }; } }; diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 964f350b9..46e4ace83 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -61,7 +61,13 @@ bool check_unsaved_changes() %code%{ RETVAL=Slic3r::GUI::check_unsaved_changes(); %}; bool config_wizard(int fresh_start) - %code%{ RETVAL=Slic3r::GUI::config_wizard(fresh_start != 0); %}; + %code%{ + try { + RETVAL = Slic3r::GUI::config_wizard(fresh_start != 0); + } catch (std::exception& e) { + croak("%s\n", e.what()); + } + %}; void open_preferences_dialog(int preferences_event) %code%{ Slic3r::GUI::open_preferences_dialog(preferences_event); %}; From 12b3132b1a55459b550f144b70b7ae548014c751 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Wed, 11 Apr 2018 15:20:38 +0200 Subject: [PATCH 2/3] Perform init_vendors at startup --- lib/Slic3r/GUI.pm | 2 ++ xs/src/slic3r/GUI/ConfigWizard.cpp | 3 --- xs/xsp/Utils_PresetUpdater.xsp | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index b28b84df3..2082728cc 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -101,6 +101,8 @@ sub OnInit { $self->{app_config}->set('version', $Slic3r::VERSION); $self->{app_config}->save; + Slic3r::PresetUpdater::init_vendors(); + # my $version_check = $self->{app_config}->get('version_check'); $self->{preset_updater} = Slic3r::PresetUpdater->new($VERSION_ONLINE_EVENT, $self->{app_config}); my $slic3r_update = $self->{app_config}->slic3r_update_avail; diff --git a/xs/src/slic3r/GUI/ConfigWizard.cpp b/xs/src/slic3r/GUI/ConfigWizard.cpp index 0c2a9dd59..52a896704 100644 --- a/xs/src/slic3r/GUI/ConfigWizard.cpp +++ b/xs/src/slic3r/GUI/ConfigWizard.cpp @@ -700,9 +700,6 @@ ConfigWizard::~ConfigWizard() {} bool ConfigWizard::run(wxWindow *parent, PresetBundle *preset_bundle) { - // FIXME: this should be done always at app startup - PresetUpdater::init_vendors(); - ConfigWizard wizard(parent); if (wizard.ShowModal() == wxID_OK) { wizard.p->apply_config(GUI::get_app_config(), preset_bundle); diff --git a/xs/xsp/Utils_PresetUpdater.xsp b/xs/xsp/Utils_PresetUpdater.xsp index 666379f02..1cb9f1c39 100644 --- a/xs/xsp/Utils_PresetUpdater.xsp +++ b/xs/xsp/Utils_PresetUpdater.xsp @@ -8,4 +8,5 @@ %name{Slic3r::PresetUpdater} class PresetUpdater { PresetUpdater(int version_online_event, AppConfig *app_config); void download(PresetBundle* preset_bundle); + static void init_vendors(); }; From b030791384a312d8368941fb7bc01c65e1fd6dea Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Wed, 11 Apr 2018 17:07:27 +0200 Subject: [PATCH 3/3] Semver fixes, misc fixes --- resources/profiles/BarBaz.ini | 2 +- resources/profiles/Foobar.ini | 2 +- xs/src/semver/semver.c | 18 ++++++++++++++++++ xs/src/semver/semver.h | 3 +++ xs/src/slic3r/GUI/AboutDialog.cpp | 2 +- xs/src/slic3r/GUI/GUI.cpp | 8 ++++---- xs/src/slic3r/Utils/Semver.hpp | 30 +++++------------------------- xs/src/slic3r/Utils/Time.cpp | 3 ++- 8 files changed, 35 insertions(+), 33 deletions(-) diff --git a/resources/profiles/BarBaz.ini b/resources/profiles/BarBaz.ini index 83bb15684..7c8cd3a6b 100644 --- a/resources/profiles/BarBaz.ini +++ b/resources/profiles/BarBaz.ini @@ -5,7 +5,7 @@ name = Bar Baz # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the Slic3r configuration to be downgraded. -config_version = 0.1 +config_version = 0.1.0 # Where to get the updates from? config_update_url = https://example.com diff --git a/resources/profiles/Foobar.ini b/resources/profiles/Foobar.ini index 21681398a..571aa8bb8 100644 --- a/resources/profiles/Foobar.ini +++ b/resources/profiles/Foobar.ini @@ -5,7 +5,7 @@ name = Foo Bar # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the Slic3r configuration to be downgraded. -config_version = 0.1 +config_version = 0.1.0 # Where to get the updates from? config_update_url = https://example.com diff --git a/xs/src/semver/semver.c b/xs/src/semver/semver.c index 599217f89..3e4a30e3a 100644 --- a/xs/src/semver/semver.c +++ b/xs/src/semver/semver.c @@ -615,3 +615,21 @@ semver_numeric (semver_t *x) { return num; } + +static char *semver_strdup(const char *src) { + if (src == NULL) return NULL; + size_t len = strlen(src) + 1; + char *res = malloc(len); + return res != NULL ? (char *) memcpy(res, src, len) : NULL; +} + +semver_t +semver_copy(const semver_t *ver) { + semver_t res = *ver; + if (ver->metadata != NULL) { + res.metadata = strdup(ver->metadata); + } + if (ver->prerelease != NULL) { + res.prerelease = strdup(ver->prerelease); + } +} \ No newline at end of file diff --git a/xs/src/semver/semver.h b/xs/src/semver/semver.h index 1b48670ca..7251f51e3 100644 --- a/xs/src/semver/semver.h +++ b/xs/src/semver/semver.h @@ -98,6 +98,9 @@ semver_is_valid (const char *s); int semver_clean (char *s); +semver_t +semver_copy(const semver_t *ver); + #ifdef __cplusplus } #endif diff --git a/xs/src/slic3r/GUI/AboutDialog.cpp b/xs/src/slic3r/GUI/AboutDialog.cpp index 49cfff2bd..664bbd1bb 100644 --- a/xs/src/slic3r/GUI/AboutDialog.cpp +++ b/xs/src/slic3r/GUI/AboutDialog.cpp @@ -56,7 +56,7 @@ AboutDialog::AboutDialog() // version { - std::string version_string = _(L("Version ")) + std::string(SLIC3R_VERSION); + auto version_string = _(L("Version ")) + std::string(SLIC3R_VERSION); wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize); wxFont version_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); #ifdef __WXMSW__ diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index cef56b892..d70b47840 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -352,11 +352,11 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l // A different naming convention is used for the Wizard on Windows vs. OSX & GTK. #if WIN32 - std::string config_wizard_menu = _(L("Configuration Wizard")); - std::string config_wizard_tooltip = _(L("Run configuration wizard")); + auto config_wizard_menu = _(L("Configuration Wizard")); + auto config_wizard_tooltip = _(L("Run configuration wizard")); #else - std::string config_wizard_menu = _(L("Configuration Assistant")); - std::string config_wizard_tooltip = _(L("Run configuration Assistant")); + auto config_wizard_menu = _(L("Configuration Assistant")); + auto config_wizard_tooltip = _(L("Run configuration Assistant")); #endif // Cmd+, is standard on OS X - what about other operating systems? local_menu->Append(config_id_base + ConfigMenuWizard, config_wizard_menu + "\u2026", config_wizard_tooltip); diff --git a/xs/src/slic3r/Utils/Semver.hpp b/xs/src/slic3r/Utils/Semver.hpp index 2ac2ba700..a1f4a92e8 100644 --- a/xs/src/slic3r/Utils/Semver.hpp +++ b/xs/src/slic3r/Utils/Semver.hpp @@ -43,11 +43,7 @@ public: } } - static const Semver zero() - { - static semver_t ver = { 0, 0, 0, nullptr, nullptr }; - return Semver(ver); - } + static const Semver zero() { return Semver(semver_zero()); } static const Semver inf() { @@ -61,37 +57,21 @@ public: return Semver(ver); } - Semver(Semver &&other) : ver(other.ver) - { - other.ver.major = other.ver.minor = other.ver.patch = 0; - other.ver.metadata = other.ver.prerelease = nullptr; - } - - Semver(const Semver &other) : ver(other.ver) - { - if (other.ver.metadata != nullptr) - ver.metadata = strdup(other.ver.metadata); - if (other.ver.prerelease != nullptr) - ver.prerelease = strdup(other.ver.prerelease); - } + Semver(Semver &&other) : ver(other.ver) { other.ver = semver_zero(); } + Semver(const Semver &other) : ver(::semver_copy(&other.ver)) {} Semver &operator=(Semver &&other) { ::semver_free(&ver); ver = other.ver; - other.ver.major = other.ver.minor = other.ver.patch = 0; - other.ver.metadata = other.ver.prerelease = nullptr; + other.ver = semver_zero(); return *this; } Semver &operator=(const Semver &other) { ::semver_free(&ver); - ver = other.ver; - if (other.ver.metadata != nullptr) - ver.metadata = strdup(other.ver.metadata); - if (other.ver.prerelease != nullptr) - ver.prerelease = strdup(other.ver.prerelease); + ver = ::semver_copy(&other.ver); return *this; } diff --git a/xs/src/slic3r/Utils/Time.cpp b/xs/src/slic3r/Utils/Time.cpp index a2b2328af..f38c4b407 100644 --- a/xs/src/slic3r/Utils/Time.cpp +++ b/xs/src/slic3r/Utils/Time.cpp @@ -71,7 +71,8 @@ time_t get_current_time_utc() tm.tm_isdst = -1; return mktime(&tm); #else - return gmtime(); + const time_t current_local = time(nullptr); + return mktime(gmtime(¤t_local)); #endif }