继续把 interp_execute.cc、interp_queue.cc、interp_find.cc 等 LinuxCNC 源文件纳入直接编译/链接路径,逐步删除临时 convert_g() wrapper 行为

结论:已将核心 LinuxCNC interpreter 源接入 standalone native 编译链接路径,移除 minimal runtime 中的手写 convert_g 行为,并通过 native probe 验证。
This commit is contained in:
2026-06-06 23:49:01 +08:00
commit 5025b0c1a1
95 changed files with 35453 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
#pragma once
#include <string>
#include <vector>
namespace standalone {
void reset_canon_events();
void push_canon_event(const std::string &event);
const std::vector<std::string> &canon_events();
} // namespace standalone

View File

@@ -0,0 +1,4 @@
#include "nml_intf/emc.hh"
static EMC_STAT standalone_emc_status;
EMC_STAT *emcStatus = &standalone_emc_status;

View File

@@ -0,0 +1,32 @@
#include <iostream>
#include <string>
#include "emc/ini/inifile.hh"
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "usage: linuxcnc_ini_probe <ini-file>\n";
return 2;
}
const char *ini_path = argv[1];
linuxcnc::IniFile ini(ini_path);
if (!ini) {
std::cerr << "failed to open ini file: " << ini_path << "\n";
return 1;
}
const auto machine = ini.findString("MACHINE", "EMC");
const auto display = ini.findString("DISPLAY", "DISPLAY");
const auto kins = ini.findString("KINEMATICS", "KINS");
const auto coords = ini.findString("COORDINATES", "TRAJ");
const auto parameter_file = ini.findString("PARAMETER_FILE", "RS274NGC");
std::cout << "EMC.MACHINE=" << (machine ? *machine : "<missing>") << "\n";
std::cout << "DISPLAY.DISPLAY=" << (display ? *display : "<missing>") << "\n";
std::cout << "KINS.KINEMATICS=" << (kins ? *kins : "<missing>") << "\n";
std::cout << "TRAJ.COORDINATES=" << (coords ? *coords : "<missing>") << "\n";
std::cout << "RS274NGC.PARAMETER_FILE=" << (parameter_file ? *parameter_file : "<missing>") << "\n";
return 0;
}

View File

@@ -0,0 +1,21 @@
#include <emscripten/emscripten.h>
#include "emc/ini/inifile.h"
extern "C" {
EMSCRIPTEN_KEEPALIVE
int lcini_get_string(const char *inipath,
const char *section,
const char *tag,
char *buf,
int bufsize) {
return iniFindString(inipath, tag, section, buf, static_cast<size_t>(bufsize));
}
EMSCRIPTEN_KEEPALIVE
int lcini_tilde_expand(const char *path, char *buf, int bufsize) {
return TildeExpansion(path, buf, static_cast<size_t>(bufsize));
}
}

View File

@@ -0,0 +1,132 @@
#define private public
#include "emc/rs274ngc/rs274ngc_interp.hh"
#undef private
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "canon_event_sink.hh"
namespace {
void initialize_minimal_interp(Interp &interp)
{
interp._setup.length_units = CANON_UNITS_MM;
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
interp._setup.ijk_distance_mode = DISTANCE_MODE::ABSOLUTE;
interp._setup.feed_mode = FEED_MODE::UNITS_PER_MINUTE;
interp._setup.plane = CANON_PLANE::XY;
interp._setup.motion_mode = G_0;
interp._setup.percent_flag = false;
interp._setup.sequence_number = 0;
interp._setup.parameter_occurrence = 0;
std::memcpy(interp._readers, Interp::default_readers, sizeof(Interp::default_readers));
}
std::vector<std::string> load_program(int argc, char **argv)
{
if (argc <= 1) {
return {
"G0 X1.0 Y2.0 (Comment)\n",
"G1 X3.0 Y4.0 F120.0\n",
};
}
std::ifstream input(argv[1]);
if (!input) {
std::cerr << "failed to open fixture: " << argv[1] << "\n";
std::exit(2);
}
std::vector<std::string> lines;
std::string line;
while (std::getline(input, line)) {
if (!line.empty()) {
lines.push_back(line + "\n");
}
}
return lines;
}
} // namespace
int main(int argc, char **argv)
{
Interp interp;
standalone::reset_canon_events();
initialize_minimal_interp(interp);
const std::vector<std::string> program = load_program(argc, argv);
if (program.empty()) {
std::cerr << "empty fixture\n";
return 2;
}
char line[LINELEN] = {0};
std::strncpy(line, program.front().c_str(), sizeof(line) - 1);
char raw_line[LINELEN] = {0};
char cooked_line[LINELEN] = {0};
int length = -1;
const int read_text_rc = interp.read_text(line, nullptr, raw_line, cooked_line, &length);
const int downcase_rc = interp.close_and_downcase(line);
const int read_rc = interp.read(program.front().c_str());
initialize_minimal_interp(interp);
for (std::size_t idx = 0; idx < program.size(); ++idx) {
interp._setup.sequence_number = static_cast<int>(idx + 1);
const int execute_rc = interp.execute(program[idx].c_str());
std::cout << "execute_line_" << (idx + 1) << "=" << execute_rc << "\n";
}
block block{};
const int init_block_rc = interp.init_block(&block);
int parse_line_rc = INTERP_ERROR;
if (read_text_rc == INTERP_OK) {
parse_line_rc = interp.parse_line(cooked_line, &block, &interp._setup);
}
std::cout << "read_text=" << read_text_rc << "\n";
std::cout << "raw_line=" << raw_line << "\n";
std::cout << "cooked_line=" << cooked_line << "\n";
std::cout << "line_length=" << length << "\n";
std::cout << "read=" << read_rc << "\n";
std::cout << "setup.linetext=" << interp._setup.linetext << "\n";
std::cout << "setup.blocktext=" << interp._setup.blocktext << "\n";
std::cout << "setup.line_length=" << interp._setup.line_length << "\n";
std::cout << "setup.sequence_number=" << interp._setup.sequence_number << "\n";
std::cout << "setup.current_x=" << interp._setup.current_x << "\n";
std::cout << "setup.current_y=" << interp._setup.current_y << "\n";
std::cout << "setup.current_z=" << interp._setup.current_z << "\n";
std::cout << "setup.parameter_5420=" << interp._setup.parameters[5420] << "\n";
std::cout << "setup.parameter_5421=" << interp._setup.parameters[5421] << "\n";
std::cout << "setup.parameter_5422=" << interp._setup.parameters[5422] << "\n";
std::cout << "setup.feed_rate=" << interp._setup.feed_rate << "\n";
std::cout << "close_and_downcase=" << downcase_rc << "\n";
std::cout << "normalized_line=" << line << "\n";
std::cout << "init_block=" << init_block_rc << "\n";
std::cout << "parse_line=" << parse_line_rc << "\n";
std::cout << "block.motion_to_be=" << block.motion_to_be << "\n";
std::cout << "block.g_modes[GM_MOTION]=" << block.g_modes[GM_MOTION] << "\n";
std::cout << "block.x_flag=" << block.x_flag << " x=" << block.x_number << "\n";
std::cout << "block.y_flag=" << block.y_flag << " y=" << block.y_number << "\n";
std::cout << "executing_block.motion_to_be=" << EXECUTING_BLOCK(interp._setup).motion_to_be << "\n";
std::cout << "executing_block.g_modes[GM_MOTION]=" << EXECUTING_BLOCK(interp._setup).g_modes[GM_MOTION] << "\n";
std::cout << "executing_block.x_flag=" << EXECUTING_BLOCK(interp._setup).x_flag
<< " x=" << EXECUTING_BLOCK(interp._setup).x_number << "\n";
std::cout << "executing_block.y_flag=" << EXECUTING_BLOCK(interp._setup).y_flag
<< " y=" << EXECUTING_BLOCK(interp._setup).y_number << "\n";
std::cout << "executing_block.f_flag=" << EXECUTING_BLOCK(interp._setup).f_flag
<< " f=" << EXECUTING_BLOCK(interp._setup).f_number << "\n";
std::cout << "call_level=" << interp.call_level() << "\n";
std::cout << "loggingLevel=" << interp._setup.loggingLevel << "\n";
std::cout << "canon_event_count=" << standalone::canon_events().size() << "\n";
for (const auto &event : standalone::canon_events()) {
std::cout << "canon_event=" << event << "\n";
}
return 0;
}

View File

@@ -0,0 +1,564 @@
#include <cstdarg>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <string>
#include <vector>
#define private public
#include "emc/rs274ngc/rs274ngc_interp.hh"
#undef private
#include "emc/rs274ngc/rs274ngc_return.hh"
#include "canon_event_sink.hh"
PythonPlugin *python_plugin = nullptr;
namespace standalone {
static std::vector<std::string> g_canon_events;
void reset_canon_events()
{
g_canon_events.clear();
}
void push_canon_event(const std::string &event)
{
g_canon_events.push_back(event);
}
const std::vector<std::string> &canon_events()
{
return g_canon_events;
}
} // namespace standalone
bool GET_BLOCK_DELETE(void) { return false; }
void FINISH(void) {}
void ON_RESET(void) {}
USER_DEFINED_FUNCTION_TYPE USER_DEFINED_FUNCTION[USER_DEFINED_FUNCTION_NUM] = {};
int USER_DEFINED_FUNCTION_ADD(USER_DEFINED_FUNCTION_TYPE func, int num)
{
if ((num < 0) || (num >= USER_DEFINED_FUNCTION_NUM)) {
return -1;
}
USER_DEFINED_FUNCTION[num] = func;
return num;
}
void INIT_CANON() {}
void SET_G5X_OFFSET(int, double, double, double, double, double, double, double, double, double) {}
void SET_G92_OFFSET(double, double, double, double, double, double, double, double, double) {}
void SET_XY_ROTATION(double) {}
void CANON_UPDATE_END_POINT(double, double, double, double, double, double, double, double, double) {}
void USE_LENGTH_UNITS(CANON_UNITS) {}
void SELECT_PLANE(CANON_PLANE) {}
void SET_TRAVERSE_RATE(double) {}
void SET_FEED_REFERENCE(CANON_FEED_REFERENCE) {}
void SET_FEED_MODE(int, int) {}
void SET_MOTION_CONTROL_MODE(CANON_MOTION_MODE, double) {}
void SET_NAIVECAM_TOLERANCE(double) {}
void SET_CUTTER_RADIUS_COMPENSATION(double) {}
void START_CUTTER_RADIUS_COMPENSATION(int) {}
void STOP_CUTTER_RADIUS_COMPENSATION() {}
void START_SPEED_FEED_SYNCH(int, double, bool) {}
void STOP_SPEED_FEED_SYNCH() {}
void RIGID_TAP(int, double, double, double, double) {}
void STRAIGHT_PROBE(int, double, double, double, double, double, double, double, double, double, unsigned char) {}
void STOP() {}
void DWELL(double) {}
void SET_SPINDLE_MODE(int, double) {}
void SPINDLE_RETRACT_TRAVERSE() {}
void START_SPINDLE_CLOCKWISE(int, int) {}
void START_SPINDLE_COUNTERCLOCKWISE(int, int) {}
void SET_SPINDLE_SPEED(int, double) {}
void STOP_SPINDLE_TURNING(int) {}
void SPINDLE_RETRACT() {}
void ORIENT_SPINDLE(int, double, int) {}
void WAIT_SPINDLE_ORIENT_COMPLETE(int, double) {}
void LOCK_SPINDLE_Z() {}
void USE_SPINDLE_FORCE() {}
void USE_NO_SPINDLE_FORCE() {}
void SET_TOOL_TABLE_ENTRY(int, int, const EmcPose &, double, double, double, int) {}
void USE_TOOL_LENGTH_OFFSET(const EmcPose &) {}
void CHANGE_TOOL() {}
void SELECT_TOOL(int) {}
void CHANGE_TOOL_NUMBER(int) {}
void RELOAD_TOOLDATA(void) {}
void CLAMP_AXIS(CANON_AXIS) {}
void DISABLE_ADAPTIVE_FEED() {}
void ENABLE_ADAPTIVE_FEED() {}
void DISABLE_FEED_OVERRIDE() {}
void ENABLE_FEED_OVERRIDE() {}
void DISABLE_SPEED_OVERRIDE(int) {}
void ENABLE_SPEED_OVERRIDE(int) {}
void DISABLE_FEED_HOLD() {}
void ENABLE_FEED_HOLD() {}
void FLOOD_OFF() {}
void FLOOD_ON() {}
void MIST_OFF() {}
void MIST_ON() {}
void PALLET_SHUTTLE() {}
void TURN_PROBE_OFF() {}
void TURN_PROBE_ON() {}
void UNCLAMP_AXIS(CANON_AXIS) {}
void NURB_KNOT_VECTOR() {}
void NURB_CONTROL_POINT(int, double, double, double, double) {}
void NURB_FEED(double, double) {}
void SET_BLOCK_DELETE(bool) {}
void OPTIONAL_PROGRAM_STOP() {}
void SET_OPTIONAL_PROGRAM_STOP(bool) {}
bool GET_OPTIONAL_PROGRAM_STOP() { return false; }
void PROGRAM_END() {}
void PROGRAM_STOP() {}
void SET_MOTION_OUTPUT_BIT(int) {}
void CLEAR_MOTION_OUTPUT_BIT(int) {}
void SET_AUX_OUTPUT_BIT(int) {}
void CLEAR_AUX_OUTPUT_BIT(int) {}
void SET_MOTION_OUTPUT_VALUE(int, double) {}
void SET_AUX_OUTPUT_VALUE(int, double) {}
int WAIT(int, int, int, double) { return 0; }
int UNLOCK_ROTARY(int, int) { return 0; }
int LOCK_ROTARY(int, int) { return 0; }
void UPDATE_TAG(const StateTag &) {}
void MESSAGE(char *s) { standalone::push_canon_event(std::string("MESSAGE: ") + (s ? s : "")); }
void LOG(char *) {}
void LOGOPEN(char *) {}
void LOGAPPEND(char *) {}
void LOGCLOSE() {}
void CANON_ERROR(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
fputc('\n', stderr);
va_end(ap);
}
double GET_EXTERNAL_FEED_RATE() { return 0.0; }
int GET_EXTERNAL_FLOOD() { return 0; }
double GET_EXTERNAL_LENGTH_UNITS() { return CANON_UNITS_MM; }
double GET_EXTERNAL_ANGLE_UNITS() { return 1.0; }
int GET_EXTERNAL_MIST() { return 0; }
CANON_MOTION_MODE GET_EXTERNAL_MOTION_CONTROL_MODE() { return CANON_EXACT_STOP; }
double GET_EXTERNAL_MOTION_CONTROL_TOLERANCE() { return 0.0; }
double GET_EXTERNAL_MOTION_CONTROL_NAIVECAM_TOLERANCE() { return 0.0; }
double GET_EXTERNAL_ORIGIN_A() { return 0.0; }
double GET_EXTERNAL_ORIGIN_B() { return 0.0; }
double GET_EXTERNAL_ORIGIN_C() { return 0.0; }
double GET_EXTERNAL_ORIGIN_X() { return 0.0; }
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';
}
}
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; }
double GET_EXTERNAL_POSITION_C() { return 0.0; }
double GET_EXTERNAL_POSITION_X() { return 0.0; }
double GET_EXTERNAL_POSITION_Y() { return 0.0; }
double GET_EXTERNAL_POSITION_Z() { return 0.0; }
double GET_EXTERNAL_POSITION_U() { return 0.0; }
double GET_EXTERNAL_POSITION_V() { return 0.0; }
double GET_EXTERNAL_POSITION_W() { return 0.0; }
double GET_EXTERNAL_PROBE_POSITION_A() { return 0.0; }
double GET_EXTERNAL_PROBE_POSITION_B() { return 0.0; }
double GET_EXTERNAL_PROBE_POSITION_C() { return 0.0; }
double GET_EXTERNAL_PROBE_POSITION_X() { return 0.0; }
double GET_EXTERNAL_PROBE_POSITION_Y() { return 0.0; }
double GET_EXTERNAL_PROBE_POSITION_Z() { return 0.0; }
double GET_EXTERNAL_PROBE_POSITION_U() { return 0.0; }
double GET_EXTERNAL_PROBE_POSITION_V() { return 0.0; }
double GET_EXTERNAL_PROBE_POSITION_W() { return 0.0; }
double GET_EXTERNAL_PROBE_VALUE() { return 0.0; }
int GET_EXTERNAL_PROBE_TRIPPED_VALUE() { return 0; }
int GET_EXTERNAL_QUEUE_EMPTY() { return 1; }
double GET_EXTERNAL_SPEED(int) { return 0.0; }
CANON_DIRECTION GET_EXTERNAL_SPINDLE(int) { return CANON_STOPPED; }
double GET_EXTERNAL_TOOL_LENGTH_XOFFSET() { return 0.0; }
double GET_EXTERNAL_TOOL_LENGTH_YOFFSET() { return 0.0; }
double GET_EXTERNAL_TOOL_LENGTH_ZOFFSET() { return 0.0; }
double GET_EXTERNAL_TOOL_LENGTH_AOFFSET() { return 0.0; }
double GET_EXTERNAL_TOOL_LENGTH_BOFFSET() { return 0.0; }
double GET_EXTERNAL_TOOL_LENGTH_COFFSET() { return 0.0; }
double GET_EXTERNAL_TOOL_LENGTH_UOFFSET() { return 0.0; }
double GET_EXTERNAL_TOOL_LENGTH_VOFFSET() { return 0.0; }
double GET_EXTERNAL_TOOL_LENGTH_WOFFSET() { return 0.0; }
int GET_EXTERNAL_TOOL_SLOT() { return 0; }
int GET_EXTERNAL_SELECTED_TOOL_SLOT() { return -1; }
CANON_TOOL_TABLE GET_EXTERNAL_TOOL_TABLE(int) { return tooldata_entry_init(); }
int GET_EXTERNAL_TC_FAULT() { return 0; }
int GET_EXTERNAL_TC_REASON() { return 0; }
double GET_EXTERNAL_TRAVERSE_RATE() { return 0.0; }
int GET_EXTERNAL_FEED_OVERRIDE_ENABLE() { return 1; }
int GET_EXTERNAL_SPINDLE_OVERRIDE_ENABLE(int) { return 1; }
int GET_EXTERNAL_ADAPTIVE_FEED_ENABLE() { return 1; }
int GET_EXTERNAL_FEED_HOLD_ENABLE() { return 1; }
int GET_EXTERNAL_DIGITAL_INPUT(int, int def) { return def; }
double GET_EXTERNAL_ANALOG_INPUT(int, double def) { return def; }
int GET_EXTERNAL_AXIS_MASK() { return 7; }
int GET_EXTERNAL_OFFSET_APPLIED() { return 0; }
EmcPose GET_EXTERNAL_OFFSETS() { return {{0, 0, 0}, 0, 0, 0, 0, 0, 0}; }
void NURBS_G5_FEED(int, const std::vector<NURBS_CONTROL_POINT> &, unsigned int, CANON_PLANE) {}
void NURBS_G6_FEED(int, const std::vector<NURBS_G6_CONTROL_POINT> &, unsigned int, double, int, CANON_PLANE) {}
void COMMENT(const char *s)
{
standalone::push_canon_event(std::string("COMMENT: ") + (s ? s : ""));
}
void STRAIGHT_TRAVERSE(int lineno,
double x, double y, double z,
double a, double b, double c,
double u, double v, double w)
{
std::ostringstream oss;
oss << "STRAIGHT_TRAVERSE line=" << lineno
<< " x=" << x
<< " y=" << y
<< " z=" << z
<< " a=" << a
<< " b=" << b
<< " c=" << c
<< " u=" << u
<< " v=" << v
<< " w=" << w;
standalone::push_canon_event(oss.str());
}
void STRAIGHT_FEED(int lineno,
double x, double y, double z,
double a, double b, double c,
double u, double v, double w)
{
std::ostringstream oss;
oss << "STRAIGHT_FEED line=" << lineno
<< " x=" << x
<< " y=" << y
<< " z=" << z
<< " a=" << a
<< " b=" << b
<< " c=" << c
<< " u=" << u
<< " v=" << v
<< " w=" << w;
standalone::push_canon_event(oss.str());
}
void ARC_FEED(int lineno,
double first_end, double second_end,
double first_axis, double second_axis, int rotation,
double axis_end_point,
double a, double b, double c,
double u, double v, double w)
{
std::ostringstream oss;
oss << "ARC_FEED line=" << lineno
<< " first_end=" << first_end
<< " second_end=" << second_end
<< " first_axis=" << first_axis
<< " second_axis=" << second_axis
<< " rotation=" << rotation
<< " axis_end_point=" << axis_end_point
<< " a=" << a
<< " b=" << b
<< " c=" << c
<< " u=" << u
<< " v=" << v
<< " w=" << w;
standalone::push_canon_event(oss.str());
}
void SET_FEED_RATE(double rate)
{
std::ostringstream oss;
oss << "SET_FEED_RATE rate=" << rate;
standalone::push_canon_event(oss.str());
}
InterpBase::~InterpBase() {}
Interp::Interp()
: log_file(stderr),
_setup{}
{
_setup.init_once = 1;
memset(_readers, 0, sizeof(_readers));
}
Interp::~Interp() {
if (log_file && log_file != stderr) {
fclose(log_file);
}
log_file = nullptr;
}
void Interp::doLog(unsigned int, const char *, int, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
const char *Interp::interp_status(int status)
{
static char statustext[64];
snprintf(statustext, sizeof(statustext), "%d", status);
return statustext;
}
const char *Interp::getSavedError()
{
return "";
}
int Interp::setSavedError(const char *)
{
return INTERP_OK;
}
void Interp::setError(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
fputc('\n', stderr);
va_end(ap);
}
int Interp::unwind_call(int status, const char *, int, const char *)
{
return status;
}
int Interp::close() { return INTERP_OK; }
int Interp::execute(const char *command)
{
int status = read(command);
if (status != INTERP_OK) {
if (status > INTERP_MIN_ERROR) {
unwind_call(status, __FILE__, __LINE__, __FUNCTION__);
}
return status;
}
if (_setup.line_length != 0) {
status = execute_block(&EXECUTING_BLOCK(_setup), &_setup);
if (status > INTERP_MIN_ERROR) {
unwind_call(status, __FILE__, __LINE__, __FUNCTION__);
}
return status;
}
return INTERP_OK;
}
int Interp::execute() { return execute(nullptr); }
int Interp::execute(const char *command, int line_number)
{
if (command && line_number) {
_setup.sequence_number = line_number;
}
int status = execute(command);
if ((_setup.call_level == 0) &&
(status == INTERP_EXECUTE_FINISH) &&
(_setup.mdi_interrupt)) {
_setup.mdi_interrupt = false;
}
return status;
}
int Interp::exit() { return INTERP_OK; }
int Interp::init() { return INTERP_OK; }
void Interp::set_loop_on_main_m99(bool state) { _setup.loop_on_main_m99 = state; }
int Interp::open(const char *) { return INTERP_ERROR; }
int Interp::read_inputs(setup_pointer)
{
return INTERP_OK;
}
int Interp::_read(const char *command)
{
int read_status = INTERP_OK;
block_pointer eblock = &EXECUTING_BLOCK(_setup);
if ((_setup.call_state > CS_NORMAL) &&
(eblock->call_type != CT_NGC_OWORD_SUB) &&
(eblock->call_type != CT_NGC_M98_SUB) &&
(eblock->call_type != CT_NONE) &&
((eblock->o_type == O_call) ||
(eblock->o_type == M_98) ||
(eblock->o_type == O_return) ||
(eblock->o_type == O_endsub) ||
(eblock->o_type == M_99))) {
_setup.line_length = 0;
_setup.linetext[0] = 0;
return INTERP_OK;
}
_setup.call_state = CS_NORMAL;
if (read_inputs(&_setup) != INTERP_OK) {
return INTERP_ERROR;
}
if ((command == nullptr) && (_setup.file_pointer == nullptr)) {
return INTERP_FILE_NOT_OPEN;
}
_setup.parameters[5420] = _setup.current_x;
_setup.parameters[5421] = _setup.current_y;
_setup.parameters[5422] = _setup.current_z;
_setup.parameters[5423] = _setup.AA_current;
_setup.parameters[5424] = _setup.BB_current;
_setup.parameters[5425] = _setup.CC_current;
_setup.parameters[5426] = _setup.u_current;
_setup.parameters[5427] = _setup.v_current;
_setup.parameters[5428] = _setup.w_current;
if (_setup.file_pointer) {
EXECUTING_BLOCK(_setup).offset = ftell(_setup.file_pointer);
}
read_status = read_text(command, _setup.file_pointer, _setup.linetext,
_setup.blocktext, &_setup.line_length);
if ((read_status == INTERP_EXECUTE_FINISH) || (read_status == INTERP_OK)) {
if (_setup.line_length != 0) {
if (parse_line(_setup.blocktext, &(EXECUTING_BLOCK(_setup)), &_setup) != INTERP_OK) {
return INTERP_ERROR;
}
} else {
if (EXECUTING_BLOCK(_setup).o_type != O_none) {
EXECUTING_BLOCK(_setup).o_type = 0;
}
}
} else if (read_status == INTERP_ENDFILE) {
if (_setup.skipping_o != nullptr) {
return INTERP_ERROR;
}
} else {
return read_status;
}
return read_status;
}
int Interp::read(const char *command)
{
int status = _read(command);
if (status > INTERP_MIN_ERROR) {
unwind_call(status, __FILE__, __LINE__, __FUNCTION__);
}
return status;
}
int Interp::read()
{
return read(nullptr);
}
int Interp::reset() { return INTERP_OK; }
int Interp::synch() { return INTERP_OK; }
void Interp::active_g_codes(int *codes) { std::memcpy(codes, _setup.active_g_codes, sizeof(_setup.active_g_codes)); }
void Interp::active_m_codes(int *codes) { std::memcpy(codes, _setup.active_m_codes, sizeof(_setup.active_m_codes)); }
void Interp::active_settings(double *settings) { std::memcpy(settings, _setup.active_settings, sizeof(_setup.active_settings)); }
int Interp::active_modes(int *, int *, double *, StateTag const &) { return INTERP_ERROR; }
void Interp::print_state_tag(StateTag const &) {}
char *Interp::error_text(int, char *buf, size_t max_size)
{
if (max_size) buf[0] = '\0';
return buf;
}
char *Interp::file_name(char *buf, size_t max_size)
{
if (max_size) {
std::strncpy(buf, _setup.filename, max_size - 1);
buf[max_size - 1] = '\0';
}
return buf;
}
size_t Interp::line_length() { return static_cast<size_t>(_setup.line_length); }
char *Interp::line_text(char *buf, size_t max_size)
{
if (max_size) {
std::strncpy(buf, _setup.linetext, max_size - 1);
buf[max_size - 1] = '\0';
}
return buf;
}
int Interp::sequence_number() { return _setup.sequence_number; }
char *Interp::stack_name(int idx, char *buf, size_t max_size)
{
if (!max_size) return buf;
if (idx < 0 || idx >= STACK_LEN) {
buf[0] = '\0';
return buf;
}
std::strncpy(buf, _setup.stack[idx], max_size - 1);
buf[max_size - 1] = '\0';
return buf;
}
int Interp::ini_load(const char *) { return INTERP_OK; }
int Interp::on_abort(int, const char *) { return INTERP_OK; }
void Interp::set_loglevel(int level) { _setup.loggingLevel = level; }
int Interp::find_remappings(block_pointer, setup_pointer) { return 0; }
int Interp::load_tool_table() { return INTERP_OK; }
int Interp::init_tool_parameters() { return INTERP_OK; }
int Interp::default_tool_parameters() { return INTERP_OK; }
int Interp::set_tool_parameters() { return INTERP_OK; }
bool Interp::is_pycallable(setup_pointer, const char *, const char *) { return false; }
bool Interp::is_user_defined_g_code(int) { return false; }
bool Interp::is_any_m_code_remapped(block_pointer, setup_pointer) { return false; }
bool Interp::is_user_defined_m_code(block_pointer, setup_pointer, int) { return false; }
void Interp::loop_to_beginning(setup_pointer) {}
int Interp::convert_control_functions(block_pointer, setup_pointer) { return INTERP_OK; }
int Interp::convert_remapped_code(block_pointer, setup_pointer, int, char, int) { return INTERP_ERROR; }
int Interp::py_execute(const char *, bool) { return INTERP_OK; }
int Interp::py_reload() { return INTERP_OK; }
const char *o_ops[] = {
"O_none", "O_sub", "O_endsub", "O_call", "O_do", "O_while", "O_if",
"O_elseif", "O_else", "O_endif", "O_break", "O_continue",
"O_endwhile", "O_return", "O_repeat", "O_endrepeat", "M_98", "M_99", "O_"
};
int Interp::read_named_parameter(char *, int *, double *double_ptr, double *, bool check_exists)
{
if (check_exists) {
*double_ptr = 0.0;
}
return INTERP_ERROR;
}
int Interp::find_named_param(const char *, int *status, double *value)
{
*status = 0;
*value = 0.0;
return INTERP_OK;
}
int Interp::store_named_param(setup_pointer, const char *, double, int)
{
return INTERP_ERROR;
}
int Interp::add_named_param(const char *, int)
{
return INTERP_OK;
}

View File

@@ -0,0 +1,18 @@
#include <iostream>
#include "emc/rs274ngc/interp_internal.hh"
int main() {
std::cout << "RS274NGC_MAX_PARAMETERS="
<< interp_param_global::RS274NGC_MAX_PARAMETERS << "\n";
std::cout << "ACTIVE_G_CODES=" << ACTIVE_G_CODES << "\n";
std::cout << "ACTIVE_M_CODES=" << ACTIVE_M_CODES << "\n";
std::cout << "ACTIVE_SETTINGS=" << ACTIVE_SETTINGS << "\n";
std::cout << "INTERP_SUB_ROUTINE_LEVELS=" << INTERP_SUB_ROUTINE_LEVELS << "\n";
std::cout << "MAX_NAMED_PARAMETERS=" << MAX_NAMED_PARAMETERS << "\n";
std::cout << "sizeof_setup=" << sizeof(setup) << "\n";
std::cout << "sizeof_context=" << sizeof(context) << "\n";
std::cout << "sizeof_parameter_value=" << sizeof(parameter_value) << "\n";
return 0;
}

View File

@@ -0,0 +1,341 @@
#define private public
#include "emc/rs274ngc/rs274ngc_interp.hh"
#undef private
#include <cstdlib>
#include <iostream>
#include <string>
#include "config.h"
#include "emc/ini/inifile.hh"
namespace {
enum predefined_named_parameters {
NP_LINE,
NP_MOTION_MODE,
NP_PLANE,
NP_CCOMP,
NP_METRIC,
NP_IMPERIAL,
NP_ABSOLUTE,
NP_INCREMENTAL,
NP_INVERSE_TIME,
NP_UNITS_PER_MINUTE,
NP_UNITS_PER_REV,
NP_COORD_SYSTEM,
NP_TOOL_OFFSET,
NP_RETRACT_R_PLANE,
NP_RETRACT_OLD_Z,
NP_SPINDLE_RPM_MODE,
NP_SPINDLE_CSS_MODE,
NP_IJK_ABSOLUTE_MODE,
NP_LATHE_DIAMETER_MODE,
NP_LATHE_RADIUS_MODE,
NP_SPINDLE_ON,
NP_SPINDLE_CW,
NP_MIST,
NP_FLOOD,
NP_SPEED_OVERRIDE,
NP_FEED_OVERRIDE,
NP_ADAPTIVE_FEED,
NP_FEED_HOLD,
NP_FEED,
NP_RPM,
NP_CURRENT_TOOL,
NP_SELECTED_POCKET,
NP_CURRENT_POCKET,
NP_X,
NP_Y,
NP_Z,
NP_A,
NP_B,
NP_C,
NP_U,
NP_V,
NP_W,
NP_ABS_X,
NP_ABS_Y,
NP_ABS_Z,
NP_ABS_A,
NP_ABS_B,
NP_ABS_C,
NP_VALUE,
NP_CALL_LEVEL,
NP_REMAP_LEVEL,
NP_SELECTED_TOOL,
NP_VALUE_RETURNED,
NP_TASK,
};
struct NamedParamRuntime {
setup state;
int fetch_ini_param(const char *nameBuf, int *status, double *value) {
*status = 0;
const int n = static_cast<int>(strlen(nameBuf));
if (n < 8) {
return INTERP_OK;
}
std::string sect = nameBuf + 5;
for (auto &c : sect) {
c = static_cast<char>(toupper(c));
}
const size_t i = sect.find(']');
if (i == std::string::npos) {
return INTERP_ERROR;
}
std::string var = sect.substr(i + 1);
sect.erase(i);
const char *iniFileName = getenv("INI_FILE_NAME");
if (!iniFileName) {
return INTERP_OK;
}
linuxcnc::IniFile inifile(iniFileName);
if (!inifile) {
return INTERP_OK;
}
if (auto inival = inifile.findReal(var, sect)) {
*value = *inival;
*status = 1;
}
return INTERP_OK;
}
int lookup_named_param(const char *nameBuf, double index, double *value) {
const int cmd = round_to_int(index);
switch (cmd) {
case NP_LINE:
*value = state.sequence_number;
break;
case NP_MOTION_MODE:
*value = state.motion_mode;
break;
case NP_METRIC:
*value = (state.length_units == CANON_UNITS_MM);
break;
case NP_IMPERIAL:
*value = (state.length_units == CANON_UNITS_INCHES);
break;
case NP_ABSOLUTE:
*value = (state.distance_mode == DISTANCE_MODE::ABSOLUTE);
break;
case NP_INCREMENTAL:
*value = (state.distance_mode == DISTANCE_MODE::INCREMENTAL);
break;
case NP_FEED:
*value = state.feed_rate;
break;
case NP_RPM:
*value = state.speed[0];
break;
case NP_X:
*value = state.current_x;
break;
case NP_Y:
*value = state.current_y;
break;
case NP_Z:
*value = state.current_z;
break;
case NP_CURRENT_TOOL:
*value = state.parameters[interp_param_global::TOOL_NUMBER];
break;
case NP_CALL_LEVEL:
*value = state.call_level;
break;
default:
return INTERP_ERROR;
}
return INTERP_OK;
}
int find_named_param(const char *nameBuf, int *status, double *value) {
const int level = (nameBuf[0] == '_') ? 0 : state.call_level;
context_pointer frame = &state.sub_context[level];
*status = 0;
auto pi = frame->named_params.find(nameBuf);
if (pi == frame->named_params.end()) {
int exists = 0;
double inivalue = 0.0;
if ((state.feature_set & FEATURE_INI_VARS) && (strncasecmp(nameBuf, "_ini[", 5) == 0)) {
fetch_ini_param(nameBuf, &exists, &inivalue);
if (exists) {
*value = inivalue;
*status = 1;
parameter_value param;
param.value = inivalue;
param.attr = PA_GLOBAL | PA_READONLY | PA_FROM_INI;
state.sub_context[0].named_params[strstore(nameBuf)] = param;
return INTERP_OK;
}
}
*value = 0.0;
*status = 0;
} else {
parameter_pointer pv = &pi->second;
if (pv->attr & PA_USE_LOOKUP) {
if (lookup_named_param(nameBuf, pv->value, value) != INTERP_OK) {
return INTERP_ERROR;
}
*status = 1;
} else {
*value = pv->value;
*status = 1;
}
}
return INTERP_OK;
}
int store_named_param(const char *nameBuf, double value, bool override_readonly) {
const int level = (nameBuf[0] == '_') ? 0 : state.call_level;
context_pointer frame = &state.sub_context[level];
auto pi = frame->named_params.find(nameBuf);
if (pi == frame->named_params.end()) {
return INTERP_ERROR;
}
parameter_pointer pv = &pi->second;
if ((pv->attr & PA_READONLY) && !override_readonly) {
return INTERP_ERROR;
}
pv->value = value;
pv->attr &= ~PA_UNSET;
return INTERP_OK;
}
int add_named_param(const char *nameBuf, int attr) {
int findStatus = 0;
double value = 0.0;
find_named_param(nameBuf, &findStatus, &value);
if (findStatus) {
return INTERP_OK;
}
int level = 0;
if (nameBuf[0] != '_') {
level = state.call_level;
} else {
level = 0;
attr |= PA_GLOBAL;
}
attr |= PA_UNSET;
parameter_value param;
param.value = 0.0;
param.attr = attr;
state.sub_context[level].named_params[strstore(nameBuf)] = param;
return INTERP_OK;
}
int init_readonly_param(const char *nameBuf, double value, int attr) {
if (add_named_param(nameBuf, PA_READONLY | attr) != INTERP_OK) {
return INTERP_ERROR;
}
if (store_named_param(nameBuf, value, true) != INTERP_OK) {
return INTERP_ERROR;
}
return INTERP_OK;
}
double inicheck() {
const char *filename = getenv("INI_FILE_NAME");
if (!filename) {
return -1.0;
}
linuxcnc::IniFile inifile(filename);
if (!inifile) {
return -1.0;
}
if (auto inistring = inifile.findString("LINEAR_UNITS", "TRAJ")) {
if ((strcasecmp("mm", inistring->c_str()) == 0) ||
(strcasecmp("metric", inistring->c_str()) == 0)) {
return 1.0;
}
return 0.0;
}
return -1.0;
}
int init_named_parameters() {
const char *pkgversion = PACKAGE_VERSION;
const char *version_major = "_vmajor";
const char *version_minor = "_vminor";
const char *metric_machine = "_metric_machine";
double vmajor = 0.0;
double vminor = 0.0;
double munits = 1.0;
sscanf(pkgversion, "%lf%lf", &vmajor, &vminor);
if (init_readonly_param(version_major, vmajor, 0) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param(version_minor, vminor, 0) != INTERP_OK) return INTERP_ERROR;
munits = inicheck();
if (init_readonly_param(metric_machine, munits, 0) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_line", NP_LINE, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_motion_mode", NP_MOTION_MODE, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_metric", NP_METRIC, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_imperial", NP_IMPERIAL, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_absolute", NP_ABSOLUTE, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_incremental", NP_INCREMENTAL, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_feed", NP_FEED, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_rpm", NP_RPM, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_x", NP_X, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_y", NP_Y, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_z", NP_Z, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_current_tool", NP_CURRENT_TOOL, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
if (init_readonly_param("_call_level", NP_CALL_LEVEL, PA_USE_LOOKUP) != INTERP_OK) return INTERP_ERROR;
return INTERP_OK;
}
};
void print_named_value(NamedParamRuntime &runtime, const char *name) {
int status = 0;
double value = 0.0;
const int rc = runtime.find_named_param(name, &status, &value);
std::cout << name << ": rc=" << rc << " found=" << status << " value=" << value << "\n";
}
} // namespace
int main(int argc, char **argv) {
if (argc == 2) {
setenv("INI_FILE_NAME", argv[1], 1);
}
NamedParamRuntime runtime;
runtime.state.feature_set = FEATURE_INI_VARS;
runtime.state.length_units = CANON_UNITS_MM;
runtime.state.distance_mode = DISTANCE_MODE::ABSOLUTE;
runtime.state.motion_mode = G_1;
runtime.state.feed_rate = 123.45;
runtime.state.speed[0] = 678.9;
runtime.state.current_x = 1.25;
runtime.state.current_y = 2.5;
runtime.state.current_z = 3.75;
runtime.state.parameters[interp_param_global::TOOL_NUMBER] = 12.0;
const int rc = runtime.init_named_parameters();
std::cout << "init_named_parameters=" << rc << "\n";
std::cout << "global_named_count=" << runtime.state.sub_context[0].named_params.size() << "\n";
std::cout << "required_parameter_first=" << interp_param_global::G28_X << "\n";
std::cout << "readonly_tool_number_index=" << interp_param_global::TOOL_NUMBER << "\n";
print_named_value(runtime, "_vmajor");
print_named_value(runtime, "_vminor");
print_named_value(runtime, "_metric_machine");
print_named_value(runtime, "_motion_mode");
print_named_value(runtime, "_metric");
print_named_value(runtime, "_feed");
print_named_value(runtime, "_rpm");
print_named_value(runtime, "_x");
print_named_value(runtime, "_current_tool");
print_named_value(runtime, "_ini[traj]max_linear_velocity");
return rc == INTERP_OK ? 0 : 1;
}

View File

@@ -0,0 +1,5 @@
#include "emc/rs274ngc/rs274ngc_interp.hh"
int main() {
return 0;
}

View File

@@ -0,0 +1,209 @@
#include <algorithm>
#include <cstring>
#include <stdexcept>
#include <string>
#include <unordered_set>
#include "emc/rs274ngc/interp_internal.hh"
struct pycontext_impl {};
pycontext::pycontext() : impl(new pycontext_impl) {}
pycontext::~pycontext() { delete impl; }
pycontext::pycontext(const pycontext &other) : impl(new pycontext_impl(*other.impl)) {}
pycontext &pycontext::operator=(const pycontext &other) {
if (this == &other) {
return *this;
}
delete impl;
impl = new pycontext_impl(*other.impl);
return *this;
}
const char *strstore(const char *s)
{
static std::unordered_set<std::string> stringtable;
if (s == nullptr) {
throw std::invalid_argument("strstore(): NULL argument");
}
auto pair = stringtable.insert(s);
return pair.first->c_str();
}
context_struct::context_struct()
: position(0), sequence_number(0), filename(""), subName(""),
m98_loop_counter(-1), context_status(0), call_type(0)
{
memset(saved_params, 0, sizeof(saved_params));
memset(saved_g_codes, 0, sizeof(saved_g_codes));
memset(saved_m_codes, 0, sizeof(saved_m_codes));
memset(saved_settings, 0, sizeof(saved_settings));
}
void context_struct::clear()
{
new (this) context_struct();
}
setup::setup()
: AA_axis_offset(0.0),
AA_current(0.0),
AA_origin_offset(0.0),
BB_axis_offset(0.0),
BB_current(0.0),
BB_origin_offset(0.0),
CC_axis_offset(0.0),
CC_current(0.0),
CC_origin_offset(0.0),
u_axis_offset(0.0),
u_current(0.0),
u_origin_offset(0.0),
v_axis_offset(0.0),
v_current(0.0),
v_origin_offset(0.0),
w_axis_offset(0.0),
w_current(0.0),
w_origin_offset(0.0),
active_g_codes{},
active_m_codes{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
active_settings{},
arc_not_allowed(0),
axis_offset_x(0.0),
axis_offset_y(0.0),
axis_offset_z(0.0),
blocks{},
remap_level(0),
blocktext{},
control_mode(CANON_EXACT_STOP),
tolerance(0.0),
naivecam_tolerance(0.0),
tolerance_default(0.0),
naivecam_tolerance_default(0.0),
current_pocket(0),
current_x(0.0),
current_y(0.0),
current_z(0.0),
cutter_comp_radius(0.0),
cutter_comp_orientation(0),
cutter_comp_side(CUTTER_COMP::OFF),
cycle_cc(0.0),
cycle_i(0.0),
cycle_j(0.0),
cycle_k(0.0),
cycle_l(0),
cycle_p(0.0),
cycle_q(0.0),
cycle_r(0.0),
cycle_il(0.0),
cycle_il_flag(0),
distance_mode(DISTANCE_MODE::ABSOLUTE),
ijk_distance_mode(DISTANCE_MODE::ABSOLUTE),
feed_mode(FEED_MODE::UNITS_PER_MINUTE),
feed_override(0),
feed_rate(0.0),
filename{},
file_pointer(nullptr),
flood(0),
length_units(CANON_UNITS_INCHES),
center_arc_radius_tolerance_inch(CENTER_ARC_RADIUS_TOLERANCE_INCH),
center_arc_radius_tolerance_mm(CENTER_ARC_RADIUS_TOLERANCE_MM),
line_length(0),
linetext{},
mist(0),
motion_mode(0),
origin_index(0),
origin_offset_x(0.0),
origin_offset_y(0.0),
origin_offset_z(0.0),
rotation_xy(0.0),
parameters{0},
parameter_occurrence(0),
parameter_numbers{0},
parameter_values{0},
named_parameter_occurrence(0),
named_parameters{nullptr},
named_parameter_values{0},
percent_flag(0),
plane(CANON_PLANE::XY),
probe_flag(0),
input_flag(0),
toolchange_flag(0),
input_index(0),
input_digital(0),
cutter_comp_firstmove(0),
program_x(0.0),
program_y(0.0),
program_z(0.0),
retract_mode(RETRACT_MODE::R_PLANE),
random_toolchanger(0),
selected_pocket(0),
selected_tool(0),
sequence_number(0),
num_spindles(0),
active_spindle(0),
speed{0.0},
spindle_mode{SPINDLE_MODE::CONSTANT_RPM},
speed_feed_mode{CANON_INDEPENDENT},
speed_override{false},
spindle_turning{CANON_STOPPED},
stack{},
stack_index(0),
tool_offset{{0,0,0},0,0,0,0,0,0},
tool_table{},
traverse_rate(0.0),
orient_offset(0.0),
g43_with_zero_offset(false),
defining_sub(0),
sub_name(nullptr),
doing_continue(0),
doing_break(0),
executed_if(0),
skipping_o(nullptr),
skipping_to_sub(nullptr),
skipping_start(0),
test_value(0.0),
return_value(0.0),
value_returned(0),
call_level(0),
sub_context{},
call_state(0),
adaptive_feed(0),
feed_hold(0),
loggingLevel(0),
debugmask(0),
log_file{},
program_prefix{},
subroutines{},
use_lazy_close(0),
lazy_closing(0),
wizard_root{},
tool_change_at_g30(0),
tool_change_quill_up(0),
tool_change_with_spindle_on(0),
parameter_g73_peck_clearance(0.0),
parameter_g83_peck_clearance(0.0),
a_axis_wrapped(0),
b_axis_wrapped(0),
c_axis_wrapped(0),
a_indexer_jnum(0),
b_indexer_jnum(0),
c_indexer_jnum(0),
lathe_diameter_mode(0),
mdi_interrupt(0),
feature_set(0),
disable_fanuc_style_sub(false),
loop_on_main_m99(false),
disable_g92_persistence(0),
pythis(nullptr),
on_abort_command(nullptr),
init_once(CANON_STOPPED)
{
std::fill(parameters, parameters + interp_param_global::RS274NGC_MAX_PARAMETERS, 0);
}
setup::~setup() {
if (pythis) {
delete pythis;
}
}

View File

@@ -0,0 +1 @@
#pragma once

View File

@@ -0,0 +1 @@
#pragma once

View File

@@ -0,0 +1,4 @@
#pragma once
struct _object;
typedef _object PyObject;

View File

@@ -0,0 +1,9 @@
#pragma once
namespace boost {
namespace python {
class object {};
} // namespace python
} // namespace boost

View File

@@ -0,0 +1,3 @@
#pragma once
#define PACKAGE_VERSION "2.10.0~pre1"

View File

@@ -0,0 +1,7 @@
#pragma once
#include <format>
namespace fmt {
using std::format;
}

View File

@@ -0,0 +1,18 @@
#pragma once
// Minimal shim for standalone interpreter source probes.
enum EmcJointType : int {
EMC_LINEAR = 1,
EMC_ANGULAR = 2,
};
class EMC_STAT {
public:
struct Motion {
struct Traj {
double linearUnits = 1.0;
} traj;
} motion;
};
extern EMC_STAT *emcStatus;

View File

@@ -0,0 +1,13 @@
#pragma once
#include <string>
class PythonPlugin {
public:
bool usable() const { return false; }
int plugin_status() const { return 0; }
const std::string &last_exception() const {
static std::string empty;
return empty;
}
};

View File

@@ -0,0 +1,67 @@
#pragma once
#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <cstddef>
#ifndef RTAPI_BEGIN_DECLS
#ifdef __cplusplus
#define RTAPI_BEGIN_DECLS extern "C" {
#define RTAPI_END_DECLS }
#else
#define RTAPI_BEGIN_DECLS
#define RTAPI_END_DECLS
#endif
#endif
#ifndef RTAPI_NAME_LEN
#define RTAPI_NAME_LEN 31
#endif
typedef enum {
RTAPI_MSG_NONE = 0,
RTAPI_MSG_ERR,
RTAPI_MSG_WARN,
RTAPI_MSG_INFO,
RTAPI_MSG_DBG,
RTAPI_MSG_ALL
} msg_level_t;
RTAPI_BEGIN_DECLS
static inline int rtapi_snprintf(char *buf, unsigned long size, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
int rc = vsnprintf(buf, static_cast<size_t>(size), fmt, ap);
va_end(ap);
return rc;
}
static inline int rtapi_vsnprintf(char *buf, unsigned long size, const char *fmt, va_list ap) {
return vsnprintf(buf, static_cast<size_t>(size), fmt, ap);
}
static inline void rtapi_print(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
static inline void rtapi_print_msg(msg_level_t, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
static inline int rtapi_set_msg_level(int) {
return 0;
}
static inline int rtapi_get_msg_level(void) {
return RTAPI_MSG_ALL;
}
RTAPI_END_DECLS

View File

@@ -0,0 +1,29 @@
#pragma once
#include "emc/nml_intf/emctool.h"
enum {
IDX_OK = 0,
};
inline CANON_TOOL_TABLE tooldata_entry_init()
{
CANON_TOOL_TABLE tool{};
tool.toolno = 0;
tool.pocketno = 0;
return tool;
}
inline int tooldata_find_index_for_tool(int toolno)
{
return toolno == 0 ? 0 : -1;
}
inline int tooldata_get(CANON_TOOL_TABLE *tool, int index)
{
if ((tool == nullptr) || (index != 0)) {
return -1;
}
*tool = tooldata_entry_init();
return IDX_OK;
}