按规划继续工作

结论:参数文件 restore/save 已通过解释器 WASM C ABI 直连 vendored LinuxCNC,native 与 host/WASM/browser 验证全部通过。
This commit is contained in:
2026-06-08 07:37:15 +08:00
parent e5697970df
commit 16585690ca
9 changed files with 223 additions and 9 deletions

View File

@@ -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)
{

View File

@@ -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"

View File

@@ -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)`

View File

@@ -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);
},
};
}