2014-05-06 08:07:18 +00:00
|
|
|
#include "PlaceholderParser.hpp"
|
2014-11-09 19:41:27 +00:00
|
|
|
#include <ctime>
|
|
|
|
#include <iomanip>
|
|
|
|
#include <sstream>
|
2015-07-01 15:56:38 +00:00
|
|
|
#include <unistd.h> // provides **environ
|
|
|
|
|
|
|
|
extern char **environ;
|
2014-05-06 08:07:18 +00:00
|
|
|
|
|
|
|
namespace Slic3r {
|
|
|
|
|
|
|
|
PlaceholderParser::PlaceholderParser()
|
|
|
|
{
|
2015-07-01 17:35:22 +00:00
|
|
|
this->set("version", SLIC3R_VERSION);
|
2015-07-01 15:56:38 +00:00
|
|
|
this->apply_env_variables();
|
2014-11-09 19:41:27 +00:00
|
|
|
this->update_timestamp();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PlaceholderParser::update_timestamp()
|
|
|
|
{
|
|
|
|
time_t rawtime;
|
|
|
|
time(&rawtime);
|
|
|
|
struct tm* timeinfo = localtime(&rawtime);
|
|
|
|
|
|
|
|
{
|
|
|
|
std::ostringstream ss;
|
|
|
|
ss << (1900 + timeinfo->tm_year);
|
|
|
|
ss << std::setw(2) << std::setfill('0') << (1 + timeinfo->tm_mon);
|
|
|
|
ss << std::setw(2) << std::setfill('0') << timeinfo->tm_mday;
|
|
|
|
ss << "-";
|
|
|
|
ss << std::setw(2) << std::setfill('0') << timeinfo->tm_hour;
|
|
|
|
ss << std::setw(2) << std::setfill('0') << timeinfo->tm_min;
|
|
|
|
ss << std::setw(2) << std::setfill('0') << timeinfo->tm_sec;
|
2015-05-02 19:43:22 +00:00
|
|
|
this->set("timestamp", ss.str());
|
2014-11-09 19:41:27 +00:00
|
|
|
}
|
2015-05-02 19:43:22 +00:00
|
|
|
this->set("year", 1900 + timeinfo->tm_year);
|
|
|
|
this->set("month", 1 + timeinfo->tm_mon);
|
|
|
|
this->set("day", timeinfo->tm_mday);
|
|
|
|
this->set("hour", timeinfo->tm_hour);
|
|
|
|
this->set("minute", timeinfo->tm_min);
|
|
|
|
this->set("second", timeinfo->tm_sec);
|
2014-05-06 08:07:18 +00:00
|
|
|
}
|
|
|
|
|
2014-06-13 13:32:11 +00:00
|
|
|
void PlaceholderParser::apply_config(DynamicPrintConfig &config)
|
|
|
|
{
|
|
|
|
// options that are set and aren't text-boxes
|
|
|
|
t_config_option_keys opt_keys;
|
|
|
|
for (t_optiondef_map::iterator i = config.def->begin();
|
|
|
|
i != config.def->end(); ++i)
|
|
|
|
{
|
|
|
|
const t_config_option_key &key = i->first;
|
|
|
|
const ConfigOptionDef &def = i->second;
|
|
|
|
|
|
|
|
if (config.has(key) && !def.multiline) {
|
|
|
|
opt_keys.push_back(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (t_config_option_keys::iterator i = opt_keys.begin();
|
|
|
|
i != opt_keys.end(); ++i)
|
|
|
|
{
|
|
|
|
const t_config_option_key &key = *i;
|
2015-05-02 19:43:22 +00:00
|
|
|
const ConfigOption* opt = config.option(key);
|
|
|
|
|
|
|
|
if (const ConfigOptionVectorBase* optv = dynamic_cast<const ConfigOptionVectorBase*>(opt)) {
|
|
|
|
// set placeholders for options with multiple values
|
2015-07-01 17:35:22 +00:00
|
|
|
// TODO: treat [bed_shape] as single, not multiple
|
2015-05-02 19:43:22 +00:00
|
|
|
this->set(key, optv->vserialize());
|
|
|
|
} else if (const ConfigOptionPoint* optp = dynamic_cast<const ConfigOptionPoint*>(opt)) {
|
2015-07-01 17:35:22 +00:00
|
|
|
this->set(key, optp->serialize());
|
2015-05-02 19:43:22 +00:00
|
|
|
|
|
|
|
Pointf val = *optp;
|
2015-07-01 17:35:22 +00:00
|
|
|
this->set(key + "_X", val.x);
|
|
|
|
this->set(key + "_Y", val.y);
|
2015-05-02 19:43:22 +00:00
|
|
|
} else {
|
2014-06-13 13:32:11 +00:00
|
|
|
// set single-value placeholders
|
2015-07-01 17:35:22 +00:00
|
|
|
this->set(key, opt->serialize());
|
2014-06-13 13:32:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-01 15:56:38 +00:00
|
|
|
void
|
|
|
|
PlaceholderParser::apply_env_variables()
|
|
|
|
{
|
|
|
|
for (char** env = environ; *env; env++) {
|
|
|
|
if (strncmp(*env, "SLIC3R_", 7) == 0) {
|
|
|
|
std::stringstream ss(*env);
|
|
|
|
std::string key, value;
|
|
|
|
std::getline(ss, key, '=');
|
|
|
|
ss >> value;
|
|
|
|
|
|
|
|
this->set(key, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-09 19:41:27 +00:00
|
|
|
void
|
|
|
|
PlaceholderParser::set(const std::string &key, const std::string &value)
|
|
|
|
{
|
|
|
|
this->_single[key] = value;
|
2015-05-02 19:43:22 +00:00
|
|
|
this->_multiple.erase(key);
|
2014-11-09 19:41:27 +00:00
|
|
|
}
|
|
|
|
|
2015-05-02 19:43:22 +00:00
|
|
|
void
|
|
|
|
PlaceholderParser::set(const std::string &key, int value)
|
2014-06-13 13:32:11 +00:00
|
|
|
{
|
2015-05-02 19:43:22 +00:00
|
|
|
std::ostringstream ss;
|
|
|
|
ss << value;
|
|
|
|
this->set(key, ss.str());
|
2014-06-13 13:32:11 +00:00
|
|
|
}
|
|
|
|
|
2015-05-02 19:43:22 +00:00
|
|
|
void
|
2015-07-01 17:35:22 +00:00
|
|
|
PlaceholderParser::set(const std::string &key, std::vector<std::string> values)
|
2014-06-13 13:32:11 +00:00
|
|
|
{
|
2015-07-01 17:35:22 +00:00
|
|
|
if (values.empty()) {
|
|
|
|
this->_multiple.erase(key);
|
|
|
|
this->_single.erase(key);
|
|
|
|
} else {
|
|
|
|
this->_multiple[key] = values;
|
|
|
|
this->_single[key] = values.front();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string
|
|
|
|
PlaceholderParser::process(std::string str) const
|
|
|
|
{
|
|
|
|
// replace single options, like [foo]
|
|
|
|
for (t_strstr_map::const_iterator it = this->_single.begin(); it != this->_single.end(); ++it) {
|
2015-05-02 19:43:22 +00:00
|
|
|
std::stringstream ss;
|
2015-07-01 17:35:22 +00:00
|
|
|
ss << '[' << it->first << ']';
|
|
|
|
this->find_and_replace(str, ss.str(), it->second);
|
|
|
|
}
|
|
|
|
|
|
|
|
// replace multiple options like [foo_0] by looping until we have enough values
|
|
|
|
// or until a previous match was found (this handles non-existing indices reasonably
|
|
|
|
// without a regex)
|
|
|
|
for (t_strstrs_map::const_iterator it = this->_multiple.begin(); it != this->_multiple.end(); ++it) {
|
|
|
|
const std::vector<std::string> &values = it->second;
|
|
|
|
bool found = false;
|
|
|
|
for (size_t i = 0; (i < values.size()) || found; ++i) {
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << '[' << it->first << '_' << i << ']';
|
|
|
|
if (i < values.size()) {
|
|
|
|
found = this->find_and_replace(str, ss.str(), values[i]);
|
|
|
|
} else {
|
|
|
|
found = this->find_and_replace(str, ss.str(), values.front());
|
|
|
|
}
|
2015-05-02 19:43:22 +00:00
|
|
|
}
|
2014-06-13 13:32:11 +00:00
|
|
|
}
|
2015-07-01 17:35:22 +00:00
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
PlaceholderParser::find_and_replace(std::string &source, std::string const &find, std::string const &replace) const
|
|
|
|
{
|
|
|
|
bool found = false;
|
|
|
|
for (std::string::size_type i = 0; (i = source.find(find, i)) != std::string::npos; ) {
|
|
|
|
source.replace(i, find.length(), replace);
|
|
|
|
i += replace.length();
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
return found;
|
2014-06-13 13:32:11 +00:00
|
|
|
}
|
|
|
|
|
2014-05-06 08:07:18 +00:00
|
|
|
#ifdef SLIC3RXS
|
|
|
|
REGISTER_CLASS(PlaceholderParser, "GCode::PlaceholderParser");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|