Expand LinuxCNC interpreter regression coverage

This commit is contained in:
2026-06-09 14:54:54 +08:00
parent 50757e45ba
commit 5bd8f12872
143 changed files with 10895 additions and 219 deletions

View File

@@ -10,6 +10,7 @@
#include <sstream>
#include <string>
#include <vector>
#include <unistd.h>
#include "canon_event_sink.hh"
#include "emc/ini/inifile.hh"
@@ -79,7 +80,7 @@ void initialize_minimal_interp(Interp &interp)
standalone::reset_external_axis_mask();
interp._setup.length_units = CANON_UNITS_MM;
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
interp._setup.ijk_distance_mode = DISTANCE_MODE::ABSOLUTE;
interp._setup.ijk_distance_mode = DISTANCE_MODE::INCREMENTAL;
interp._setup.feed_mode = FEED_MODE::UNITS_PER_MINUTE;
interp._setup.plane = CANON_PLANE::XY;
interp._setup.motion_mode = G_0;
@@ -133,6 +134,46 @@ void apply_ini_search_paths(Interp &interp, const char *ini_path)
}
}
std::filesystem::path resolve_machine_relative_path(const std::filesystem::path &machine_dir,
const std::string &entry)
{
std::filesystem::path path(entry);
if (path.is_relative()) {
path = machine_dir / path;
}
return path.lexically_normal();
}
int initialize_parameter_file_from_ini(Interp &interp, const char *ini_path)
{
standalone::reset_parameter_file_name();
if (!ini_path || ini_path[0] == '\0') {
return INTERP_OK;
}
linuxcnc::IniFile ini(ini_path);
if (!ini || !ini.findString("PARAMETER_FILE", "RS274NGC")) {
return INTERP_OK;
}
const int ini_rc = interp.ini_load(ini_path);
if (ini_rc != INTERP_OK) {
return ini_rc;
}
char parameter_file_name[LINELEN] = {0};
standalone::get_parameter_file_name(parameter_file_name, sizeof(parameter_file_name));
const auto resolved = resolve_machine_relative_path(
std::filesystem::path(ini_path).parent_path(), parameter_file_name);
if (access(resolved.c_str(), F_OK) != 0) {
standalone::reset_parameter_file_name();
return INTERP_OK;
}
standalone::set_parameter_file_name(resolved.c_str());
return interp.init();
}
std::vector<std::string> load_program(int argc, char **argv)
{
if (argc <= 1) {
@@ -273,7 +314,17 @@ int main(int argc, char **argv)
standalone::reset_canon_events();
initialize_minimal_interp(file_interp);
apply_ini_search_paths(file_interp, ini_path);
file_open_rc = file_interp.open(argv[arg_offset]);
const int init_rc = initialize_parameter_file_from_ini(file_interp, ini_path);
if (init_rc != INTERP_OK) {
std::cout << "file_init=" << init_rc << "\n";
if (init_rc > INTERP_MIN_ERROR) {
char error_buf[LINELEN] = {0};
file_interp.error_text(init_rc, error_buf, sizeof(error_buf));
std::cout << "file_error_text=" << error_buf << "\n";
}
}
apply_ini_search_paths(file_interp, ini_path);
file_open_rc = init_rc == INTERP_OK ? file_interp.open(argv[arg_offset]) : init_rc;
if (file_open_rc == INTERP_OK) {
while (true) {
const int file_read_rc = file_interp.read();

View File

@@ -22,6 +22,7 @@ namespace standalone {
static std::vector<std::string> g_canon_events;
static double g_external_feed_rate = 0.0;
static int g_external_axis_mask = Interp::AXIS_MASK_X | Interp::AXIS_MASK_Y | Interp::AXIS_MASK_Z;
static std::string g_parameter_file_name;
void reset_canon_events()
{
@@ -55,6 +56,25 @@ int external_axis_mask()
return g_external_axis_mask;
}
void reset_parameter_file_name()
{
g_parameter_file_name.clear();
}
void set_parameter_file_name(const char *filename)
{
g_parameter_file_name = filename ? filename : "";
}
void get_parameter_file_name(char *filename, int max_size)
{
if (!filename || max_size <= 0) {
return;
}
std::snprintf(filename, static_cast<std::size_t>(max_size), "%s",
g_parameter_file_name.c_str());
}
} // namespace standalone
bool GET_BLOCK_DELETE(void) { return false; }
@@ -489,11 +509,12 @@ double GET_EXTERNAL_ORIGIN_Y() { return 0.0; }
double GET_EXTERNAL_ORIGIN_Z() { return 0.0; }
void GET_EXTERNAL_PARAMETER_FILE_NAME(char *filename, int max_size)
{
if (max_size > 0) {
filename[0] = '\0';
}
standalone::get_parameter_file_name(filename, max_size);
}
void SET_PARAMETER_FILE_NAME(const char *filename)
{
standalone::set_parameter_file_name(filename);
}
void SET_PARAMETER_FILE_NAME(const char *) {}
CANON_PLANE GET_EXTERNAL_PLANE() { return CANON_PLANE::XY; }
double GET_EXTERNAL_POSITION_A() { return 0.0; }
double GET_EXTERNAL_POSITION_B() { return 0.0; }

View File

@@ -10,6 +10,7 @@
#include <vector>
#include <emscripten/emscripten.h>
#include <unistd.h>
#include "canon_event_sink.hh"
#include "emc/ini/inifile.hh"
@@ -111,7 +112,7 @@ void initialize_minimal_interp(Interp &interp)
standalone::reset_external_axis_mask();
interp._setup.length_units = CANON_UNITS_MM;
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
interp._setup.ijk_distance_mode = DISTANCE_MODE::ABSOLUTE;
interp._setup.ijk_distance_mode = DISTANCE_MODE::INCREMENTAL;
interp._setup.feed_mode = FEED_MODE::UNITS_PER_MINUTE;
interp._setup.plane = CANON_PLANE::XY;
interp._setup.motion_mode = G_0;
@@ -411,6 +412,17 @@ std::string remap_subroutine_path(const std::string &machine_dir, const std::str
return machine_dir + "/" + entry;
}
std::string resolve_machine_relative_path(const std::string &machine_dir, const std::string &entry)
{
if (entry.empty() || entry[0] == '/') {
return entry;
}
if (machine_dir == "/") {
return machine_dir + entry;
}
return machine_dir + "/" + entry;
}
int apply_ini_search_paths(Interp &interp, const linuxcnc::IniFile &ini, const std::string &machine_dir)
{
standalone::apply_machine_axis_config(interp, ini);
@@ -452,6 +464,36 @@ bool apply_ini_search_paths(Interp &interp, const char *ini_path)
return true;
}
int initialize_parameter_file_from_ini(Interp &interp, const char *ini_path)
{
standalone::reset_parameter_file_name();
if (!ini_path || ini_path[0] == '\0') {
return INTERP_OK;
}
linuxcnc::IniFile ini(ini_path);
if (!ini || !ini.findString("PARAMETER_FILE", "RS274NGC")) {
return INTERP_OK;
}
const int ini_rc = interp.ini_load(ini_path);
if (ini_rc != INTERP_OK) {
return ini_rc;
}
char parameter_file_name[LINELEN] = {0};
standalone::get_parameter_file_name(parameter_file_name, sizeof(parameter_file_name));
const std::string resolved =
resolve_machine_relative_path(parent_path(ini_path), parameter_file_name);
if (access(resolved.c_str(), F_OK) != 0) {
standalone::reset_parameter_file_name();
return INTERP_OK;
}
standalone::set_parameter_file_name(resolved.c_str());
return interp.init();
}
bool parse_remaps_from_ini(Interp &interp, std::ostringstream &output, const char *ini_path)
{
const std::string machine_dir = parent_path(ini_path);
@@ -569,6 +611,14 @@ char *run_file_with_ini_internal(const char *path, const char *ini_path, bool co
std::ostringstream output;
apply_ini_search_paths(interp, ini_path);
const int init_rc = initialize_parameter_file_from_ini(interp, ini_path);
if (init_rc != INTERP_OK) {
output << "file_init=" << init_rc << "\n";
append_error_text(output, interp, "file_error_text=", init_rc);
append_events_and_state(output, interp);
return copy_result(output.str());
}
apply_ini_search_paths(interp, ini_path);
const int open_rc = interp.open(path);
output << "file_open=" << open_rc << "\n";

View File

@@ -5,5 +5,8 @@ namespace standalone {
void reset_external_axis_mask();
void set_external_axis_mask(int axis_mask);
int external_axis_mask();
void reset_parameter_file_name();
void set_parameter_file_name(const char *filename);
void get_parameter_file_name(char *filename, int max_size);
} // namespace standalone