按提示词结论接入 INI 参数文件桥
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
struct CncSimHandle {
|
||||
CncSimDialect dialect = CNC_SIM_DIALECT_LINUXCNC;
|
||||
GcodeBackendKind backend = GcodeBackendKind::LinuxCncRs274;
|
||||
GcodeBackendOptions backend_options;
|
||||
std::string last_error;
|
||||
CanonEventSink sink;
|
||||
};
|
||||
@@ -96,6 +97,72 @@ bool contains_string_value(const std::string &compact, const char *key, const ch
|
||||
return false;
|
||||
}
|
||||
|
||||
bool find_json_string_value(const std::string &json, const char *key, std::string *value) {
|
||||
const std::string needle = std::string("\"") + key + "\"";
|
||||
size_t pos = 0;
|
||||
while ((pos = json.find(needle, pos)) != std::string::npos) {
|
||||
pos += needle.size();
|
||||
while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
|
||||
++pos;
|
||||
}
|
||||
if (pos >= json.size() || json[pos] != ':') {
|
||||
continue;
|
||||
}
|
||||
++pos;
|
||||
while (pos < json.size() && std::isspace(static_cast<unsigned char>(json[pos]))) {
|
||||
++pos;
|
||||
}
|
||||
if (pos >= json.size() || json[pos] != '"') {
|
||||
continue;
|
||||
}
|
||||
++pos;
|
||||
std::string parsed;
|
||||
bool escaped = false;
|
||||
for (; pos < json.size(); ++pos) {
|
||||
const char ch = json[pos];
|
||||
if (escaped) {
|
||||
switch (ch) {
|
||||
case '"':
|
||||
case '\\':
|
||||
case '/':
|
||||
parsed.push_back(ch);
|
||||
break;
|
||||
case 'n':
|
||||
parsed.push_back('\n');
|
||||
break;
|
||||
case 'r':
|
||||
parsed.push_back('\r');
|
||||
break;
|
||||
case 't':
|
||||
parsed.push_back('\t');
|
||||
break;
|
||||
default:
|
||||
parsed.push_back(ch);
|
||||
break;
|
||||
}
|
||||
escaped = false;
|
||||
} else if (ch == '\\') {
|
||||
escaped = true;
|
||||
} else if (ch == '"') {
|
||||
*value = parsed;
|
||||
return true;
|
||||
} else {
|
||||
parsed.push_back(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool find_json_string_any(const std::string &json, std::string *value, const char *first) {
|
||||
return find_json_string_value(json, first, value);
|
||||
}
|
||||
|
||||
template <typename... Keys>
|
||||
bool find_json_string_any(const std::string &json, std::string *value, const char *first, Keys... rest) {
|
||||
return find_json_string_value(json, first, value) || find_json_string_any(json, value, rest...);
|
||||
}
|
||||
|
||||
bool contains_switchkins_config_alias(const std::string &compact, const char *alias) {
|
||||
return contains_string_value(compact, "switchkins", alias) ||
|
||||
contains_string_value(compact, "remap", alias) ||
|
||||
@@ -300,6 +367,20 @@ int apply_config(CncSimHandle *handle, const std::string &json) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string ini_file_name;
|
||||
if (find_json_string_any(json,
|
||||
&ini_file_name,
|
||||
"ini",
|
||||
"iniFile",
|
||||
"inifile",
|
||||
"iniFileName",
|
||||
"inifilename",
|
||||
"ini_file",
|
||||
"ini_file_name",
|
||||
"INI_FILE_NAME")) {
|
||||
handle->backend_options.ini_file_name = ini_file_name;
|
||||
}
|
||||
|
||||
bool rtcp_enabled = false;
|
||||
double tool_length = 0.0;
|
||||
const bool has_rtcp_enabled = contains_bool_value(compact, "rtcp", &rtcp_enabled) ||
|
||||
@@ -383,7 +464,12 @@ int cnc_sim_parse_program(CncSimHandle *handle, const char *program, size_t prog
|
||||
}
|
||||
|
||||
handle->last_error.clear();
|
||||
const int rc = parse_gcode_with_backend(handle->backend, handle->sink, program, program_len, &handle->last_error);
|
||||
const int rc = parse_gcode_with_backend(handle->backend,
|
||||
handle->sink,
|
||||
program,
|
||||
program_len,
|
||||
handle->backend_options,
|
||||
&handle->last_error);
|
||||
if (rc != 0 && handle->last_error.empty()) {
|
||||
handle->last_error = "program parse failed";
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ int parse_gcode_with_backend(GcodeBackendKind backend,
|
||||
CanonEventSink &sink,
|
||||
const char *program,
|
||||
size_t program_len,
|
||||
const GcodeBackendOptions &options,
|
||||
std::string *error) {
|
||||
switch (backend) {
|
||||
case GcodeBackendKind::Smoke: {
|
||||
@@ -37,7 +38,7 @@ int parse_gcode_with_backend(GcodeBackendKind backend,
|
||||
}
|
||||
case GcodeBackendKind::LinuxCncRs274:
|
||||
#ifdef CNC_SIM_ENABLE_LINUXCNC_RS274_BACKEND
|
||||
return parse_linuxcnc_rs274_backend(sink, program, program_len, error);
|
||||
return parse_linuxcnc_rs274_backend(sink, program, program_len, options, error);
|
||||
#else
|
||||
if (error) {
|
||||
*error = "linuxcnc-rs274 backend is not compiled into this build";
|
||||
|
||||
@@ -10,11 +10,15 @@ enum class GcodeBackendKind {
|
||||
LinuxCncRs274,
|
||||
};
|
||||
|
||||
struct GcodeBackendOptions {
|
||||
std::string ini_file_name;
|
||||
};
|
||||
|
||||
const char *gcode_backend_name(GcodeBackendKind backend);
|
||||
|
||||
int parse_gcode_with_backend(GcodeBackendKind backend,
|
||||
CanonEventSink &sink,
|
||||
const char *program,
|
||||
size_t program_len,
|
||||
const GcodeBackendOptions &options,
|
||||
std::string *error);
|
||||
|
||||
|
||||
@@ -175,6 +175,7 @@ int execute_file_mode(InterpBase *interp,
|
||||
int parse_linuxcnc_rs274_backend(CanonEventSink &sink,
|
||||
const char *program,
|
||||
size_t program_len,
|
||||
const GcodeBackendOptions &options,
|
||||
std::string *error) {
|
||||
if (!program && program_len != 0) {
|
||||
if (error) {
|
||||
@@ -197,6 +198,22 @@ int parse_linuxcnc_rs274_backend(CanonEventSink &sink,
|
||||
cnc_sim_linuxcnc_set_canon_sink(&sink);
|
||||
|
||||
InterpBase *interp = makeInterp();
|
||||
if (!options.ini_file_name.empty()) {
|
||||
// LinuxCNC source basis: emctask.cc calls Interp::ini_load() before
|
||||
// Interp::init(), and rs274ngc_pre.cc ini_load() maps
|
||||
// [RS274NGC] PARAMETER_FILE through SET_PARAMETER_FILE_NAME().
|
||||
if (interp->ini_load(options.ini_file_name.c_str()) != INTERP_OK) {
|
||||
if (error) {
|
||||
*error = "ini_load failed: " + options.ini_file_name;
|
||||
}
|
||||
delete interp;
|
||||
cnc_sim_linuxcnc_set_canon_sink(nullptr);
|
||||
return -1;
|
||||
}
|
||||
if (const char *parameter_file = std::getenv("CNC_SIM_RS274_VAR")) {
|
||||
SET_PARAMETER_FILE_NAME(parameter_file);
|
||||
}
|
||||
}
|
||||
int status = interp->init();
|
||||
if (status != INTERP_OK) {
|
||||
if (error) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "canon_event_sink.h"
|
||||
#include "gcode_backend.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
@@ -8,5 +9,5 @@
|
||||
int parse_linuxcnc_rs274_backend(CanonEventSink &sink,
|
||||
const char *program,
|
||||
size_t program_len,
|
||||
const GcodeBackendOptions &options,
|
||||
std::string *error);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user