From 7041ebdd229581d60c1f771c1380f6aa9dbd8c36 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 19 Apr 2014 19:14:41 +0200 Subject: [PATCH] Workaround for upstream module bug causing command line option parsing for multi-boolean options like retract-layer-change and wipe --- lib/Slic3r/Config.pm | 8 ++++++-- xs/src/Config.cpp | 11 +++++++++++ xs/src/Config.hpp | 1 + xs/t/15_config.t | 4 +++- xs/xsp/Config.xsp | 10 +++++----- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index 3a51ebc5..92a63a61 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -58,9 +58,13 @@ sub new_from_cli { my $self = $class->new; foreach my $opt_key (keys %args) { - if ($opt_key =~ /^(?:print_center|bed_size|duplicate_grid|extruder_offset|retract_layer_change|wipe)$/) { + my $opt_def = $Options->{$opt_key}; + + # we use set_deserialize() for bool options since GetOpt::Long doesn't handle + # arrays of boolean values + if ($opt_key =~ /^(?:print_center|bed_size|duplicate_grid|extruder_offset)$/ || $opt_def->{type} eq 'bool') { $self->set_deserialize($opt_key, $args{$opt_key}); - } elsif (my $shortcut = $Options->{$opt_key}{shortcut}) { + } elsif (my $shortcut = $opt_def->{shortcut}) { $self->set($_, $args{$opt_key}) for @$shortcut; } else { $self->set($opt_key, $args{$opt_key}); diff --git a/xs/src/Config.cpp b/xs/src/Config.cpp index a0c0137e..1043beb4 100644 --- a/xs/src/Config.cpp +++ b/xs/src/Config.cpp @@ -237,6 +237,17 @@ ConfigBase::set(t_config_option_key opt_key, SV* value) { } return true; } + +/* This method is implemented as a workaround for this typemap bug: + https://rt.cpan.org/Public/Bug/Display.html?id=94110 */ +bool +ConfigBase::set_deserialize(const t_config_option_key opt_key, SV* str) { + size_t len; + const char * c = SvPV(str, len); + std::string value(c, len); + + return this->set_deserialize(opt_key, value); +} #endif DynamicConfig::~DynamicConfig () { diff --git a/xs/src/Config.hpp b/xs/src/Config.hpp index 419b1348..4d6446dc 100644 --- a/xs/src/Config.hpp +++ b/xs/src/Config.hpp @@ -479,6 +479,7 @@ class ConfigBase SV* get(t_config_option_key opt_key); SV* get_at(t_config_option_key opt_key, size_t i); bool set(t_config_option_key opt_key, SV* value); + bool set_deserialize(const t_config_option_key opt_key, SV* str); #endif }; diff --git a/xs/t/15_config.t b/xs/t/15_config.t index 9ccb8d13..57603ed1 100644 --- a/xs/t/15_config.t +++ b/xs/t/15_config.t @@ -4,7 +4,7 @@ use strict; use warnings; use Slic3r::XS; -use Test::More tests => 110; +use Test::More tests => 112; foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) { $config->set('layer_height', 0.3); @@ -101,6 +101,8 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) { is $config->serialize('wipe'), '1,0', 'serialize bools'; $config->set_deserialize('wipe', '0,1,1'); is_deeply $config->get('wipe'), [0,1,1], 'deserialize bools'; + $config->set_deserialize('retract_layer_change', 0); + is_deeply $config->get('retract_layer_change'), [0], 'deserialize bools from non-string value'; { my @values = (1); $values[2] = 1; # implicitely extend array; this is not the same as explicitely assigning undef to second item diff --git a/xs/xsp/Config.xsp b/xs/xsp/Config.xsp index 5a9a0b13..7c89a9bf 100644 --- a/xs/xsp/Config.xsp +++ b/xs/xsp/Config.xsp @@ -13,7 +13,7 @@ SV* get(t_config_option_key opt_key); SV* get_at(t_config_option_key opt_key, int i); bool set(t_config_option_key opt_key, SV* value); - bool set_deserialize(t_config_option_key opt_key, std::string str); + bool set_deserialize(t_config_option_key opt_key, SV* str); std::string serialize(t_config_option_key opt_key); double get_abs_value(t_config_option_key opt_key); %name{get_abs_value_over} @@ -36,7 +36,7 @@ SV* get(t_config_option_key opt_key); SV* get_at(t_config_option_key opt_key, int i); bool set(t_config_option_key opt_key, SV* value); - bool set_deserialize(t_config_option_key opt_key, std::string str); + bool set_deserialize(t_config_option_key opt_key, SV* str); std::string serialize(t_config_option_key opt_key); double get_abs_value(t_config_option_key opt_key); %name{get_abs_value_over} @@ -56,7 +56,7 @@ SV* get(t_config_option_key opt_key); SV* get_at(t_config_option_key opt_key, int i); bool set(t_config_option_key opt_key, SV* value); - bool set_deserialize(t_config_option_key opt_key, std::string str); + bool set_deserialize(t_config_option_key opt_key, SV* str); std::string serialize(t_config_option_key opt_key); double get_abs_value(t_config_option_key opt_key); %name{get_abs_value_over} @@ -77,7 +77,7 @@ SV* get(t_config_option_key opt_key); SV* get_at(t_config_option_key opt_key, int i); bool set(t_config_option_key opt_key, SV* value); - bool set_deserialize(t_config_option_key opt_key, std::string str); + bool set_deserialize(t_config_option_key opt_key, SV* str); std::string serialize(t_config_option_key opt_key); double get_abs_value(t_config_option_key opt_key); %name{get_abs_value_over} @@ -98,7 +98,7 @@ SV* get(t_config_option_key opt_key); SV* get_at(t_config_option_key opt_key, int i); bool set(t_config_option_key opt_key, SV* value); - bool set_deserialize(t_config_option_key opt_key, std::string str); + bool set_deserialize(t_config_option_key opt_key, SV* str); std::string serialize(t_config_option_key opt_key); double get_abs_value(t_config_option_key opt_key); %name{get_abs_value_over}