按规划继续工作
结论:参数文件 restore/save 已通过解释器 WASM C ABI 直连 vendored LinuxCNC,native 与 host/WASM/browser 验证全部通过。
This commit is contained in:
@@ -136,6 +136,36 @@ void append_events_and_state(std::ostringstream &output, const Interp &interp)
|
||||
output << "post_execute.flood=" << interp._setup.flood << "\n";
|
||||
}
|
||||
|
||||
void append_parameter_state(std::ostringstream &output, const Interp &interp)
|
||||
{
|
||||
output << "parameter_5161=" << interp._setup.parameters[5161] << "\n";
|
||||
output << "parameter_5162=" << interp._setup.parameters[5162] << "\n";
|
||||
output << "parameter_5220=" << interp._setup.parameters[5220] << "\n";
|
||||
output << "parameter_5221=" << interp._setup.parameters[5221] << "\n";
|
||||
output << "parameter_5399=" << interp._setup.parameters[5399] << "\n";
|
||||
}
|
||||
|
||||
void append_error_text(std::ostringstream &output, Interp &interp, const char *prefix, int rc)
|
||||
{
|
||||
if (rc > INTERP_MIN_ERROR) {
|
||||
char error_buf[LINELEN] = {0};
|
||||
interp.error_text(rc, error_buf, sizeof(error_buf));
|
||||
output << prefix << error_buf << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void apply_parameter_assignments(Interp &interp, const char *assignments)
|
||||
{
|
||||
std::istringstream input(assignments ? assignments : "");
|
||||
int parameter = 0;
|
||||
double value = 0.0;
|
||||
while (input >> parameter >> value) {
|
||||
if ((parameter > 0) && (parameter < interp_param_global::RS274NGC_MAX_PARAMETERS)) {
|
||||
interp._setup.parameters[parameter] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
@@ -258,6 +288,35 @@ char *lcinterp_run_file(const char *path)
|
||||
return lcinterp_run_file_with_ini(path, nullptr);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
char *lcinterp_restore_parameters(const char *path)
|
||||
{
|
||||
Interp interp;
|
||||
initialize_minimal_interp(interp);
|
||||
|
||||
std::ostringstream output;
|
||||
const int rc = interp.restore_parameters(path);
|
||||
output << "restore_parameters=" << rc << "\n";
|
||||
append_error_text(output, interp, "restore_error_text=", rc);
|
||||
append_parameter_state(output, interp);
|
||||
return copy_result(output.str());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
char *lcinterp_save_parameters(const char *path, const char *assignments)
|
||||
{
|
||||
Interp interp;
|
||||
initialize_minimal_interp(interp);
|
||||
apply_parameter_assignments(interp, assignments);
|
||||
|
||||
std::ostringstream output;
|
||||
const int rc = interp.save_parameters(path, interp._setup.parameters);
|
||||
output << "save_parameters=" << rc << "\n";
|
||||
append_error_text(output, interp, "save_error_text=", rc);
|
||||
append_parameter_state(output, interp);
|
||||
return copy_result(output.str());
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
void lcinterp_free_string(char *value)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
|
||||
#include <wordexp.h>
|
||||
|
||||
@@ -44,4 +46,59 @@ void wordfree(wordexp_t *pwordexp)
|
||||
pwordexp->we_offs = 0;
|
||||
}
|
||||
|
||||
int link(const char *oldpath, const char *newpath)
|
||||
{
|
||||
FILE *source = std::fopen(oldpath, "rb");
|
||||
if (!source) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE *target = std::fopen(newpath, "rb");
|
||||
if (target) {
|
||||
std::fclose(target);
|
||||
std::fclose(source);
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
target = std::fopen(newpath, "wb");
|
||||
if (!target) {
|
||||
const int saved_errno = errno;
|
||||
std::fclose(source);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buffer[4096];
|
||||
while (true) {
|
||||
const std::size_t read = std::fread(buffer, 1, sizeof(buffer), source);
|
||||
if (read > 0 && std::fwrite(buffer, 1, read, target) != read) {
|
||||
const int saved_errno = errno;
|
||||
std::fclose(target);
|
||||
std::fclose(source);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
if (read < sizeof(buffer)) {
|
||||
if (std::ferror(source)) {
|
||||
const int saved_errno = errno;
|
||||
std::fclose(target);
|
||||
std::fclose(source);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (std::fclose(target) != 0) {
|
||||
const int saved_errno = errno;
|
||||
std::fclose(source);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
std::fclose(source);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -38,4 +38,7 @@ vendored LinuxCNC RS274NGC sources and exposes:
|
||||
- `runProgramWithIni(programText, iniPath)`
|
||||
- `runFile(path)`
|
||||
- `runFileWithIni(path, iniPath)`
|
||||
- `restoreParameters(path)`
|
||||
- `saveParameters(path, values)`
|
||||
- `writeTextFile(path, text)`
|
||||
- `readTextFile(path)`
|
||||
|
||||
@@ -54,6 +54,10 @@ export async function createLinuxCncInterpSdk(moduleOptions = {}) {
|
||||
mod.FS.writeFile(path, text, { encoding: "utf8" });
|
||||
},
|
||||
|
||||
readTextFile(path) {
|
||||
return mod.FS.readFile(path, { encoding: "utf8" });
|
||||
},
|
||||
|
||||
runProgram(programText) {
|
||||
return callStringResult(mod, "lcinterp_run_program", programText);
|
||||
},
|
||||
@@ -69,5 +73,16 @@ export async function createLinuxCncInterpSdk(moduleOptions = {}) {
|
||||
runFileWithIni(path, iniPath) {
|
||||
return callStringResult(mod, "lcinterp_run_file_with_ini", path, iniPath);
|
||||
},
|
||||
|
||||
restoreParameters(path) {
|
||||
return callStringResult(mod, "lcinterp_restore_parameters", path);
|
||||
},
|
||||
|
||||
saveParameters(path, values) {
|
||||
const assignments = Object.entries(values)
|
||||
.map(([parameter, value]) => `${parameter} ${value}`)
|
||||
.join("\n");
|
||||
return callStringResult(mod, "lcinterp_save_parameters", path, assignments);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user