This commit is contained in:
Enrico Turri 2020-01-21 14:07:22 +01:00
commit 2b93900ac0
21 changed files with 850 additions and 418 deletions

View file

@ -12,6 +12,7 @@
#include <algorithm>
#include <cstdlib>
#include <math.h>
#include <string_view>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/find.hpp>
@ -34,6 +35,8 @@
#include "miniz_extension.hpp"
using namespace std::literals::string_view_literals;
#if 0
// Enable debugging and asserts, even in the release build.
#define DEBUG
@ -2268,8 +2271,20 @@ void GCode::apply_print_config(const PrintConfig &print_config)
void GCode::append_full_config(const Print &print, std::string &str)
{
const DynamicPrintConfig &cfg = print.full_print_config();
// Sorted list of config keys, which shall not be stored into the G-code. Initializer list.
static constexpr auto banned_keys = {
"compatible_printers"sv,
"compatible_prints"sv,
"print_host"sv,
"printhost_apikey"sv,
"printhost_cafile"sv
};
assert(std::is_sorted(banned_keys.begin(), banned_keys.end()));
auto is_banned = [](const std::string &key) {
return std::binary_search(banned_keys.begin(), banned_keys.end(), key);
};
for (const std::string &key : cfg.keys())
if (key != "compatible_prints" && key != "compatible_printers" && ! cfg.option(key)->is_nil())
if (! is_banned(key) && ! cfg.option(key)->is_nil())
str += "; " + key + " = " + cfg.opt_serialize(key) + "\n";
}

View file

@ -332,6 +332,21 @@ namespace client
return expr();
}
expr unary_integer(const Iterator start_pos) const
{
switch (this->type) {
case TYPE_INT :
return expr<Iterator>(this->i(), start_pos, this->it_range.end());
case TYPE_DOUBLE:
return expr<Iterator>((int)(this->d()), start_pos, this->it_range.end());
default:
this->throw_exception("Cannot convert to integer.");
}
assert(false);
// Suppress compiler warnings.
return expr();
}
expr unary_not(const Iterator start_pos) const
{
switch (this->type) {
@ -415,6 +430,22 @@ namespace client
return *this;
}
expr &operator%=(const expr &rhs)
{
this->throw_if_not_numeric("Cannot divide a non-numeric type.");
rhs.throw_if_not_numeric("Cannot divide with a non-numeric type.");
if ((this->type == TYPE_INT) ? (rhs.i() == 0) : (rhs.d() == 0.))
rhs.throw_exception("Division by zero");
if (this->type == TYPE_DOUBLE || rhs.type == TYPE_DOUBLE) {
double d = std::fmod(this->as_d(), rhs.as_d());
this->data.d = d;
this->type = TYPE_DOUBLE;
} else
this->data.i %= rhs.i();
this->it_range = boost::iterator_range<Iterator>(this->it_range.begin(), rhs.it_range.end());
return *this;
}
static void to_string2(expr &self, std::string &out)
{
out = self.to_string();
@ -1087,6 +1118,7 @@ namespace client
unary_expression(_r1) [_val = _1]
>> *( (lit('*') > unary_expression(_r1) ) [_val *= _1]
| (lit('/') > unary_expression(_r1) ) [_val /= _1]
| (lit('%') > unary_expression(_r1) ) [_val %= _1]
);
multiplicative_expression.name("multiplicative_expression");
@ -1107,6 +1139,8 @@ namespace client
{ out = value.unary_minus(out.it_range.begin()); }
static void not_(expr<Iterator> &value, expr<Iterator> &out)
{ out = value.unary_not(out.it_range.begin()); }
static void to_int(expr<Iterator> &value, expr<Iterator> &out)
{ out = value.unary_integer(out.it_range.begin()); }
};
unary_expression = iter_pos[px::bind(&FactorActions::set_start_pos, _1, _val)] >> (
scalar_variable_reference(_r1) [ _val = _1 ]
@ -1118,6 +1152,8 @@ namespace client
[ px::bind(&expr<Iterator>::min, _val, _2) ]
| (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
[ px::bind(&expr<Iterator>::max, _val, _2) ]
//FIXME this is likley not correct
| (kw["int"] > '(' > unary_expression(_r1) /* > ')' */ ) [ px::bind(&FactorActions::to_int, _1, _val) ]
| (strict_double > iter_pos) [ px::bind(&FactorActions::double_, _1, _2, _val) ]
| (int_ > iter_pos) [ px::bind(&FactorActions::int_, _1, _2, _val) ]
| (kw[bool_] > iter_pos) [ px::bind(&FactorActions::bool_, _1, _2, _val) ]

View file

@ -41,7 +41,7 @@ public:
// Fill in the template using a macro processing language.
// Throws std::runtime_error on syntax or runtime error.
std::string process(const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override = nullptr) const;
std::string process(const std::string &templ, unsigned int current_extruder_id = 0, const DynamicConfig *config_override = nullptr) const;
// Evaluate a boolean expression using the full expressive power of the PlaceholderParser boolean expression syntax.
// Throws std::runtime_error on syntax or runtime error.

View file

@ -449,7 +449,7 @@ int copy_file(const std::string &from, const std::string &to, const bool with_ch
ret_val = check_copy(from, to_temp);
if (ret_val == 0 && rename_file(to_temp, to))
ret_val = -1;
ret_val = -3;
}
return ret_val;
}
@ -460,11 +460,11 @@ int check_copy(const std::string &origin, const std::string &copy)
std::ifstream f2(copy, std::ifstream::in | std::ifstream::binary | std::ifstream::ate);
if (f1.fail() || f2.fail())
return -1;
return -2;
std::streampos fsize = f1.tellg();
if (fsize != f2.tellg())
return -1;
return -2;
f1.seekg(0, std::ifstream::beg);
f2.seekg(0, std::ifstream::beg);
@ -481,12 +481,12 @@ int check_copy(const std::string &origin, const std::string &copy)
if (origin_cnt != copy_cnt ||
(origin_cnt > 0 && std::memcmp(buffer_origin.data(), buffer_copy.data(), origin_cnt) != 0))
// Files are different.
return -1;
return -2;
fsize -= origin_cnt;
} while (f1.good() && f2.good());
// All data has been read and compared equal.
return (f1.eof() && f2.eof() && fsize == 0) ? 0 : -1;
return (f1.eof() && f2.eof() && fsize == 0) ? 0 : -2;
}
// Ignore system and hidden files, which may be created by the DropBox synchronisation process.