#define BOOST_PYTHON_MAX_ARITY 4
#include "python_plugin.hh"
#include <boost/python/dict.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/import.hpp>
#include <boost/python/list.hpp>
#include <boost/python/scope.hpp>
#include <boost/python/tuple.hpp>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <libintl.h>
#include <set>
#include <stdexcept>
#include <new>
#include "rtapi.h"
#include "inifile.hh"
#include "rs274ngc.hh"
#include "rs274ngc_return.hh"
#include "interp_internal.hh"
#include "interp_queue.hh"
#include "rs274ngc_interp.hh"
#include "units.h"
#include <unordered_set>
#include <interp_parameter_def.hh>
using namespace interp_param_global;
namespace bp = boost::python;
extern char * _rs274ngc_errors[];
const char *Interp::interp_status(int status) {
static char statustext[50];
static const char *msgs[] = { "INTERP_OK", "INTERP_EXIT",
"INTERP_EXECUTE_FINISH", "INTERP_ENDFILE", "INTERP_FILE_NOT_OPEN",
"INTERP_ERROR" };
sprintf(statustext, "%s%s%d", ((status >= INTERP_OK) && (status
<= INTERP_ERROR)) ? msgs[status] : "unknown interpreter error",
(status > INTERP_MIN_ERROR) ? " - error: " : " - ", status);
return statustext;
}
extern struct _inittab builtin_modules[];
int trace;
static char savedError[LINELEN+1];
Interp::Interp()
: log_file(stderr),
_setup{}
{
_setup.init_once = 1;
init_named_parameters();
if (!PythonPlugin::instantiate(builtin_modules)) { Error("Interp ctor: cant instantiate Python plugin");
return;
}
#ifndef UNIT_TEST
try {
bp::object interp_module = bp::import("interpreter");
_setup.pythis = new boost::python::object(boost::cref(*this));
bp::scope(interp_module).attr("this") = *_setup.pythis;
bp::object retval;
python_plugin->run_string("from interpreter import this", retval, false);
}
catch (bp::error_already_set) {
std::string exception_msg;
if (PyErr_Occurred()) {
exception_msg = handle_pyerror();
} else
exception_msg = "unknown exception";
bp::handle_exception();
PyErr_Clear();
Error("PYTHON: exception during 'this' export:\n%s\n",exception_msg.c_str());
}
#endif
}
InterpBase *makeInterp()
{
return new Interp;
}
Interp::~Interp() {
if(log_file) {
if(log_file != stderr)
fclose(log_file);
log_file = nullptr;
}
}
void Interp::doLog(unsigned int flags, const char *file, int line,
const char *fmt, ...)
{
struct timeval tv;
struct tm *tm;
va_list ap;
if (flags & LOG_TIME) {
gettimeofday(&tv, NULL);
tm = localtime(&tv.tv_sec);
fprintf(log_file, "%04d%02d%02d-%02d:%02d:%02d.%03ld ",
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
tv.tv_usec/1000);
}
if (flags & LOG_PID) {
fprintf(log_file, "%4d ",getpid());
}
if (flags & LOG_FILENAME) {
fprintf(log_file, "%s:%d: ",file,line);
}
va_start(ap, fmt);
vfprintf(log_file, fmt, ap);
fflush(log_file);
va_end(ap);
}
int Interp::close()
{
logOword("Interp::close()");
if(_setup.use_lazy_close) {
_setup.lazy_closing = 1;
return INTERP_OK;
}
if (_setup.file_pointer != NULL) {
fclose(_setup.file_pointer);
_setup.file_pointer = NULL;
_setup.percent_flag = false;
}
reset();
return INTERP_OK;
}
int Interp::_execute(const char *command)
{
int status;
int n;
int MDImode = 0;
block_pointer eblock = &EXECUTING_BLOCK(_setup);
extern const char *call_statenames[];
extern const char *call_typenames[];
extern const char *o_ops[];
if (NULL != command) {
MDImode = 1;
status = read(command);
if (status != INTERP_OK) {
return status;
}
}
logDebug("execute:%s %s='%s' mdi_int=%d o_type=%s o_name=%s cl=%d rl=%d type=%s state=%s",
MDImode ? "MDI" : "auto",
command ? "command" : "line",
command ? command : _setup.linetext,
_setup.mdi_interrupt, o_ops[eblock->o_type], eblock->o_name,
_setup.call_level,_setup.remap_level,
eblock->call_type < 0 ? "*unset*" : call_typenames[eblock->call_type],
call_statenames[_setup.call_state]);
if ((eblock->o_name != 0) || _setup.mdi_interrupt) {
status = convert_control_functions(eblock, &_setup);
CHP(status);
if (_setup.mdi_interrupt) {
_setup.mdi_interrupt = false;
MDImode = 1;
}
logDebug("!!!KL Open file is:%s:", _setup.filename);
logDebug("MDImode = %d", MDImode);
while(MDImode && _setup.call_level) {
status = read(0); if (status > INTERP_MIN_ERROR)
CHP(status);
status = execute(); if (status != INTERP_OK) {
if (status == INTERP_EXECUTE_FINISH) {
_setup.mdi_interrupt = true;
}
CHP(status);
}
}
_setup.mdi_interrupt = false;
if (MDImode) {
FINISH();
_setup.offset_map.clear();
}
return INTERP_OK;
}
if(_setup.skipping_o)
{
logDebug("skipping to: %s", _setup.skipping_o);
return INTERP_OK;
}
for (n = 0; n < _setup.parameter_occurrence; n++)
{ _setup.parameters[_setup.parameter_numbers[n]]
= _setup.parameter_values[n];
}
for (n = 0; n < _setup.named_parameter_occurrence; n++)
{
logDebug("storing param:|%s|", _setup.named_parameters[n]);
CHP(store_named_param(&_setup, _setup.named_parameters[n],
_setup.named_parameter_values[n]));
}
_setup.named_parameter_occurrence = 0;
if (_setup.line_length != 0) {
if (eblock->remappings.size() > 0) {
std::set<int>::iterator it;
int next_remap = *eblock->remappings.begin();
logRemap("found remap %d in '%s', level=%d filename=%s line=%d",
next_remap,_setup.blocktext,_setup.call_level,_setup.filename,_setup.sequence_number);
CHP(enter_remap());
block_pointer cblock = &CONTROLLING_BLOCK(_setup);
cblock->phase = next_remap;
status = execute_block(cblock, &_setup);
#if 0#endif
if (status < 0) {
if (cblock->remappings.find(- status) == cblock->remappings.end()) {
ERS("BUG: execute_block: got %d - not in remappings() !! (next_remap=%d)",- status,next_remap);
}
logRemap("initial phase %d",-status);
if (MDImode) {
if ((eblock->o_name != 0) ||
(_setup.mdi_interrupt)) {
status = convert_control_functions(eblock, &_setup);
CHP(status);
if (_setup.mdi_interrupt) {
_setup.mdi_interrupt = false;
MDImode = 1;
}
status = INTERP_OK;
while(MDImode && _setup.call_level) { CHP(read(0)); status = execute(); if (status == INTERP_EXECUTE_FINISH)
_setup.mdi_interrupt = true;
CHP(status);
}
_setup.mdi_interrupt = false;
logRemap("MDI remap execution complete status=%s\n",interp_status(status));
write_g_codes(eblock, &_setup);
write_m_codes(eblock, &_setup);
write_settings(&_setup);
return INTERP_OK;
}
} else {
status = execute(0);
CHP(status);
}
if ((status != INTERP_OK) &&
(status != INTERP_EXECUTE_FINISH) && (status != INTERP_EXIT))
ERP(status);
} else {
CHP(status);
}
} else {
status = execute_block(eblock, &_setup);
write_g_codes(eblock, &_setup);
write_m_codes(eblock, &_setup);
write_settings(&_setup);
if ((status == INTERP_EXIT) &&
(_setup.remap_level > 0) &&
(_setup.call_level > 0)) {
logRemap("standard case status=%s remap_level=%d call_level=%d blocktext='%s' MDImode=%d",
interp_status(status),_setup.remap_level,_setup.call_level, _setup.blocktext,MDImode);
logRemap("_setup.filename = %s, fn[0]=%s, fn[1]=%s",
_setup.filename,
_setup.sub_context[0].filename,
_setup.sub_context[1].filename);
}
}
if ((status != INTERP_OK) &&
(status != INTERP_EXECUTE_FINISH) && (status != INTERP_EXIT))
ERP(status);
} else
status = INTERP_OK;
return status;
}
int Interp::execute(const char *command)
{
int status;
if ((status = _execute(command)) > INTERP_MIN_ERROR) {
unwind_call(status, __FILE__,__LINE__,__FUNCTION__);
}
return status;
}
int Interp::execute()
{
return Interp::execute(0);
}
int Interp::execute(const char *command, int line_number)
{
int status;
if(command && line_number)
_setup.sequence_number = line_number;
status = Interp::execute(command);
if (status > INTERP_MIN_ERROR) {
unwind_call(status, __FILE__,__LINE__,__FUNCTION__);
logDebug("<-- execute(): error returned, clearing remap and call stack");
}
if ((_setup.call_level == 0) &&
(status == INTERP_EXECUTE_FINISH) &&
(_setup.mdi_interrupt)) {
logDebug(" execute() clearing mdi_interrupt");
_setup.mdi_interrupt = false; }
return status;
}
int Interp::remap_finished(int phase)
{
int next_remap,status;
block_pointer cblock = &CONTROLLING_BLOCK(_setup);
logRemap("remap_finished phase=%d remap_level=%d call_level=%d filename=%s",
phase, _setup.remap_level,_setup.call_level,_setup.filename);
if (phase < 0) {
if (cblock->remappings.find(-phase) == cblock->remappings.end()) {
ERS("remap_finished: got %d - not in cblock.remappings!",phase);
}
cblock->remappings.erase(-phase);
std::set<int>::iterator it = cblock->remappings.begin();
if (it != cblock->remappings.end()) {
next_remap = *it;
cblock->phase = next_remap;
logRemap("starting phase %d (remap_level=%d call_level=%d)",next_remap,_setup.remap_level,_setup.call_level);
status = execute_block(cblock, &_setup);
logRemap("phase %d started, execute_block() returns %d", next_remap, status);
if (status < 0) {
return execute(0);
} else
return status;
} else {
if (cblock->remappings.size()) {
ERS("BUG - remappings not empty");
}
logRemap("no more remaps in controlling_block found (remap_level=%d call_level=%d), remappings size=%zd, dropping",
_setup.remap_level,_setup.call_level,cblock->remappings.size());
status = execute_block(cblock, &_setup);
if ((status < 0) || (status > INTERP_MIN_ERROR)) {
logRemap("executing block leftover items: %s status=%s remap_level=%d call_level=%d (failing)",
status < 0 ? "BUG":"ERROR", interp_status(status),_setup.remap_level,_setup.call_level);
if (status < 0)
ERS("BUG - check find_remappings()!! status=%d nesting=%d",status,_setup.remap_level);
} else {
if (status != INTERP_EXIT) CHP(leave_remap());
logRemap("executing block leftover items complete, status=%s remap_level=%d call_level=%d tc=%d probe=%d input=%d mdi_interrupt=%d line=%d backtoline=%d",
interp_status(status),_setup.remap_level,_setup.call_level,_setup.toolchange_flag,
_setup.probe_flag,_setup.input_flag,_setup.mdi_interrupt,_setup.sequence_number,
cblock->line_number);
}
}
return status;
} else {
ERS("BUG: remap_finished(): phase=%d nesting=%d",
phase, _setup.remap_level);
}
return INTERP_OK;
}
int Interp::find_remappings(block_pointer block, setup_pointer settings)
{
if (block->f_flag && remapping("F")) {
if (remap_in_progress("F"))
CONTROLLING_BLOCK(*settings).builtin_used = true;
else
block->remappings.insert(STEP_SET_FEED_RATE);
}
if (block->s_flag && remapping("S")) {
if (remap_in_progress("S"))
CONTROLLING_BLOCK(*settings).builtin_used = true;
else
block->remappings.insert(STEP_SET_SPINDLE_SPEED);
}
if (block->t_flag && remapping("T")) {
if (remap_in_progress("T"))
CONTROLLING_BLOCK(*settings).builtin_used = true;
else
block->remappings.insert(STEP_PREPARE);
}
if (IS_USER_MCODE(block,settings,5) &&
!(((block->m_modes[5] == 62) && remap_in_progress("M62")) ||
((block->m_modes[5] == 63) && remap_in_progress("M63")) ||
((block->m_modes[5] == 64) && remap_in_progress("M64")) ||
((block->m_modes[5] == 65) && remap_in_progress("M65")) ||
((block->m_modes[5] == 66) && remap_in_progress("M66")) ||
((block->m_modes[5] == 67) && remap_in_progress("M67")) ||
((block->m_modes[5] == 68) && remap_in_progress("M68"))))
block->remappings.insert(STEP_M_5);
if (IS_USER_MCODE(block,settings,6) &&
!(((block->m_modes[6] == 6) && remap_in_progress("M6")) ||
((block->m_modes[6] == 61) && remap_in_progress("M61")))) {
block->remappings.insert(STEP_M_6); }
if (IS_USER_MCODE(block,settings,7))
block->remappings.insert(STEP_M_7);
if (IS_USER_MCODE(block,settings,8))
block->remappings.insert(STEP_M_8);
if (IS_USER_MCODE(block,settings,9))
block->remappings.insert(STEP_M_9);
if (IS_USER_MCODE(block,settings,10))
block->remappings.insert(STEP_M_10);
int mode = block->g_modes[GM_MOTION];
if ((mode != -1) && IS_USER_GCODE(mode))
block->remappings.insert(STEP_MOTION);
mode = block->motion_to_be;
if ((mode != -1) && IS_USER_GCODE(mode)) {
block->remappings.insert(STEP_MOTION);
}
if (IS_USER_MCODE(block,settings,4)) {
if (remap_in_progress("M0") ||
remap_in_progress("M1") ||
remap_in_progress("M60")) {
CONTROLLING_BLOCK(*settings).builtin_used = true;
} else {
block->remappings.insert(STEP_MGROUP4);
}
}
return block->remappings.size();
}
int Interp::exit()
{
char file_name[LINELEN];
GET_EXTERNAL_PARAMETER_FILE_NAME(file_name, (LINELEN - 1));
save_parameters(((file_name[0] ==
0) ?
RS274NGC_PARAMETER_FILE_NAME_DEFAULT :
file_name), _setup.parameters);
reset();
if (python_plugin->is_callable(NULL, DELETE_FUNC)) {
bp::object retval, tupleargs, kwargs;
bp::list plist;
plist.append(*_setup.pythis); tupleargs = bp::tuple(plist);
kwargs = bp::dict();
python_plugin->call(NULL, DELETE_FUNC, tupleargs, kwargs, retval);
if (python_plugin->plugin_status() == PLUGIN_EXCEPTION) {
ERM("pycall(%s):\n%s", INIT_FUNC,
python_plugin->last_exception().c_str());
fprintf(stderr, "%s\n",savedError);
}
}
return INTERP_OK;
}
void Interp::set_loglevel(int level) { _setup.loggingLevel = level; }
int Interp::init()
{
int k; char filename[LINELEN];
double *pars; char *iniFileName;
IniFile::ErrorCode r;
INIT_CANON();
iniFileName = getenv("INI_FILE_NAME");
_setup.loggingLevel = 0;
_setup.tool_change_at_g30 = 0;
_setup.tool_change_quill_up = 0;
_setup.tool_change_with_spindle_on = 0;
_setup.a_axis_wrapped = 0;
_setup.b_axis_wrapped = 0;
_setup.c_axis_wrapped = 0;
_setup.random_toolchanger = 0;
_setup.a_indexer_jnum = -1; _setup.b_indexer_jnum = -1; _setup.c_indexer_jnum = -1; _setup.return_value = 0;
_setup.value_returned = 0;
_setup.remap_level = 0; _setup.call_state = CS_NORMAL;
_setup.num_spindles = 1;
_setup.center_arc_radius_tolerance_inch = CENTER_ARC_RADIUS_TOLERANCE_INCH;
_setup.center_arc_radius_tolerance_mm = CENTER_ARC_RADIUS_TOLERANCE_MM;
if(iniFileName != NULL) {
IniFile inifile;
if (inifile.Open(iniFileName) == false) {
fprintf(stderr,"Unable to open inifile:%s:\n", iniFileName);
} else {
const char *inistring;
inifile.Find(&_setup.tool_change_at_g30, "TOOL_CHANGE_AT_G30", "EMCIO");
inifile.Find(&_setup.tool_change_quill_up, "TOOL_CHANGE_QUILL_UP", "EMCIO");
inifile.Find(&_setup.tool_change_with_spindle_on, "TOOL_CHANGE_WITH_SPINDLE_ON", "EMCIO");
inifile.Find(&_setup.a_axis_wrapped, "WRAPPED_ROTARY", "AXIS_A");
inifile.Find(&_setup.b_axis_wrapped, "WRAPPED_ROTARY", "AXIS_B");
inifile.Find(&_setup.c_axis_wrapped, "WRAPPED_ROTARY", "AXIS_C");
inifile.Find(&_setup.random_toolchanger, "RANDOM_TOOLCHANGER", "EMCIO");
inifile.Find(&_setup.feature_set, "FEATURES", "RS274NGC");
inifile.Find(&_setup.num_spindles, "SPINDLES", "TRAJ");
if (NULL != (inistring =inifile.Find("LOCKING_INDEXER_JOINT", "AXIS_A"))) {
_setup.a_indexer_jnum = atol(inistring);
}
if (NULL != (inistring =inifile.Find("LOCKING_INDEXER_JOINT", "AXIS_B"))) {
_setup.b_indexer_jnum = atol(inistring);
}
if (NULL != (inistring =inifile.Find("LOCKING_INDEXER_JOINT", "AXIS_C"))) {
_setup.c_indexer_jnum = atol(inistring);
}
inifile.Find(&_setup.orient_offset, "ORIENT_OFFSET", "RS274NGC");
inifile.Find(&_setup.debugmask, "DEBUG", "EMC");
_setup.debugmask |= EMC_DEBUG_UNCONDITIONAL;
if(NULL != (inistring = inifile.Find("LOG_LEVEL", "RS274NGC")))
{
_setup.loggingLevel = atol(inistring);
}
if(NULL != (inistring = inifile.Find("LOG_FILE", "RS274NGC")))
{
if ((log_file = fopen(inistring, "a")) == NULL) {
log_file = stderr;
logDebug( "(%d): Unable to open log file:%s, using stderr",
getpid(), inistring);
}
} else {
log_file = stderr;
}
_setup.use_lazy_close = 1;
_setup.wizard_root[0] = 0;
if(NULL != (inistring = inifile.Find("WIZARD_ROOT", "WIZARD")))
{
logDebug("[WIZARD]WIZARD_ROOT:%s", inistring);
if (realpath(inistring, _setup.wizard_root) == NULL) {
logDebug("realpath failed to find wizard_root:%s:", inistring);
}
}
logDebug("_setup.wizard_root:%s:", _setup.wizard_root);
_setup.program_prefix[0] = 0;
if(NULL != (inistring = inifile.Find("PROGRAM_PREFIX", "DISPLAY")))
{
char expandinistring[LINELEN];
if (inifile.TildeExpansion(inistring,expandinistring,sizeof(expandinistring))) {
logDebug("TildeExpansion failed for: %s",inistring);
}
if (realpath(expandinistring, _setup.program_prefix) == NULL){
logDebug("realpath failed to find program_prefix:%s:", inistring);
}
logDebug("program prefix:%s: prefix:%s:",
inistring, _setup.program_prefix);
}
else
{
logDebug("PROGRAM_PREFIX not found");
}
logDebug("_setup.program_prefix:%s:", _setup.program_prefix);
if(NULL != (inistring = inifile.Find("SUBROUTINE_PATH", "RS274NGC")))
{
int dct;
char* nextdir;
char tmpdirs[PATH_MAX+1];
for (dct=0; dct < MAX_SUB_DIRS; dct++) {
_setup.subroutines[dct] = NULL;
}
strcpy(tmpdirs,inistring);
nextdir = strtok(tmpdirs,":"); dct = 0;
while (1) {
char tmp_path[PATH_MAX];
char expandnextdir[LINELEN];
if (inifile.TildeExpansion(nextdir,expandnextdir,sizeof(expandnextdir))) {
logDebug("TildeExpansion failed for: %s",nextdir);
}
if (realpath(expandnextdir, tmp_path) == NULL){
logDebug("realpath failed to find subroutines[%d]:%s:",dct,nextdir);
_setup.subroutines[dct] = NULL;
} else {
_setup.subroutines[dct] = strstore(tmp_path);
logDebug("program prefix[%d]:%s",dct,_setup.subroutines[dct]);
dct++;
}
if (dct >= MAX_SUB_DIRS) {
logDebug("too many entries in SUBROUTINE_PATH, max=%d", MAX_SUB_DIRS);
break;
}
nextdir = strtok(NULL,":");
if (nextdir == NULL) break; }
}
else
{
logDebug("SUBROUTINE_PATH not found");
}
if (NULL != (inistring = inifile.Find("ON_ABORT_COMMAND", "RS274NGC"))) {
_setup.on_abort_command = strstore(inistring);
logDebug("_setup.on_abort_command=%s", _setup.on_abort_command);
} else {
_setup.on_abort_command = NULL;
}
if (NULL != (inistring = inifile.Find("TOPLEVEL", "PYTHON"))) {
int status = python_plugin->configure(iniFileName,"PYTHON");
if (status != PLUGIN_OK) {
Error("Python plugin configure() failed, status = %d", status);
}
}
int n = 1;
int lineno = -1;
_setup.g_remapped.clear();
_setup.m_remapped.clear();
_setup.remaps.clear();
while (NULL != (inistring = inifile.Find("REMAP", "RS274NGC",
n, &lineno))) {
CHP(parse_remap( inistring, lineno));
n++;
}
r = inifile.Find(
&_setup.center_arc_radius_tolerance_inch,
MIN_CENTER_ARC_RADIUS_TOLERANCE_INCH,
CENTER_ARC_RADIUS_TOLERANCE_INCH,
"CENTER_ARC_RADIUS_TOLERANCE_INCH",
"RS274NGC"
);
if ((r != IniFile::ERR_NONE) && (r != IniFile::ERR_TAG_NOT_FOUND)) {
Error("invalid [RS274NGC]CENTER_ARC_RADIUS_TOLERANCE_INCH in ini file\n");
}
r = inifile.Find(
&_setup.center_arc_radius_tolerance_mm,
MIN_CENTER_ARC_RADIUS_TOLERANCE_MM,
CENTER_ARC_RADIUS_TOLERANCE_MM,
"CENTER_ARC_RADIUS_TOLERANCE_MM",
"RS274NGC"
);
if ((r != IniFile::ERR_NONE) && (r != IniFile::ERR_TAG_NOT_FOUND)) {
Error("invalid [RS274NGC]CENTER_ARC_RADIUS_TOLERANCE_MM in ini file\n");
}
inifile.Find(&_setup.disable_g92_persistence,
"DISABLE_G92_PERSISTENCE",
"RS274NGC");
inifile.Find(&_setup.disable_fanuc_style_sub,
"DISABLE_FANUC_STYLE_SUB",
"RS274NGC");
logDebug("init: DISABLE_FANUC_STYLE_SUB = %d",
_setup.disable_fanuc_style_sub);
inifile.Close();
}
}
_setup.length_units = GET_EXTERNAL_LENGTH_UNIT_TYPE();
USE_LENGTH_UNITS(_setup.length_units);
GET_EXTERNAL_PARAMETER_FILE_NAME(filename, LINELEN);
if (filename[0] == 0)
strcpy(filename, RS274NGC_PARAMETER_FILE_NAME_DEFAULT);
CHP(restore_parameters(filename));
pars = _setup.parameters;
_setup.origin_index = (int) (pars[5220] + 0.0001);
if(_setup.origin_index < 1 || _setup.origin_index > 9) {
_setup.origin_index = 1;
pars[5220] = 1.0;
}
k = (5200 + (_setup.origin_index * 20));
_setup.origin_offset_x = USER_TO_PROGRAM_LEN(pars[k + 1]);
_setup.origin_offset_y = USER_TO_PROGRAM_LEN(pars[k + 2]);
_setup.origin_offset_z = USER_TO_PROGRAM_LEN(pars[k + 3]);
_setup.AA_origin_offset = USER_TO_PROGRAM_ANG(pars[k + 4]);
_setup.BB_origin_offset = USER_TO_PROGRAM_ANG(pars[k + 5]);
_setup.CC_origin_offset = USER_TO_PROGRAM_ANG(pars[k + 6]);
_setup.u_origin_offset = USER_TO_PROGRAM_LEN(pars[k + 7]);
_setup.v_origin_offset = USER_TO_PROGRAM_LEN(pars[k + 8]);
_setup.w_origin_offset = USER_TO_PROGRAM_LEN(pars[k + 9]);
SET_G5X_OFFSET(_setup.origin_index,
_setup.origin_offset_x ,
_setup.origin_offset_y ,
_setup.origin_offset_z ,
_setup.AA_origin_offset,
_setup.BB_origin_offset,
_setup.CC_origin_offset,
_setup.u_origin_offset ,
_setup.v_origin_offset ,
_setup.w_origin_offset);
if (_setup.disable_g92_persistence)
for (k = 5210; k < 5220; k++)
pars[k] = 0;
if (pars[5210]) {
_setup.axis_offset_x = USER_TO_PROGRAM_LEN(pars[5211]);
_setup.axis_offset_y = USER_TO_PROGRAM_LEN(pars[5212]);
_setup.axis_offset_z = USER_TO_PROGRAM_LEN(pars[5213]);
_setup.AA_axis_offset = USER_TO_PROGRAM_ANG(pars[5214]);
_setup.BB_axis_offset = USER_TO_PROGRAM_ANG(pars[5215]);
_setup.CC_axis_offset = USER_TO_PROGRAM_ANG(pars[5216]);
_setup.u_axis_offset = USER_TO_PROGRAM_LEN(pars[5217]);
_setup.v_axis_offset = USER_TO_PROGRAM_LEN(pars[5218]);
_setup.w_axis_offset = USER_TO_PROGRAM_LEN(pars[5219]);
} else {
_setup.axis_offset_x = 0.0;
_setup.axis_offset_y = 0.0;
_setup.axis_offset_z = 0.0;
_setup.AA_axis_offset = 0.0;
_setup.BB_axis_offset = 0.0;
_setup.CC_axis_offset = 0.0;
_setup.u_axis_offset = 0.0;
_setup.v_axis_offset = 0.0;
_setup.w_axis_offset = 0.0;
}
SET_G92_OFFSET(_setup.axis_offset_x ,
_setup.axis_offset_y ,
_setup.axis_offset_z ,
_setup.AA_axis_offset,
_setup.BB_axis_offset,
_setup.CC_axis_offset,
_setup.u_axis_offset ,
_setup.v_axis_offset ,
_setup.w_axis_offset);
_setup.rotation_xy = pars[k+10];
SET_XY_ROTATION(pars[k+10]);
SET_FEED_REFERENCE(CANON_XYZ);
_setup.blocktext[0] = 0;
_setup.cutter_comp_side = false;
_setup.arc_not_allowed = false;
_setup.cycle_il_flag = false;
_setup.distance_mode = MODE_ABSOLUTE;
_setup.ijk_distance_mode = MODE_INCREMENTAL; _setup.feed_mode = UNITS_PER_MINUTE;
_setup.filename[0] = 0;
_setup.file_pointer = NULL;
_setup.line_length = 0;
_setup.linetext[0] = 0;
_setup.motion_mode = G_80;
_setup.probe_flag = false;
_setup.toolchange_flag = false;
_setup.input_flag = false;
_setup.input_index = -1;
_setup.input_digital = false;
_setup.program_x = 0.;
_setup.program_y = 0.;
_setup.program_z = 0.;
_setup.cutter_comp_firstmove = true;
_setup.sequence_number = 0;
_setup.speed_feed_mode = CANON_INDEPENDENT;
ZERO_EMC_POSE(_setup.tool_offset);
_setup.call_level = 0;
_setup.defining_sub = 0;
_setup.skipping_o = 0;
_setup.offset_map.clear();
_setup.lathe_diameter_mode = false;
_setup.parameters[5599] = 1.0;
memcpy(_readers, default_readers, sizeof(default_readers));
long axis_mask = GET_EXTERNAL_AXIS_MASK();
if(!(axis_mask & AXIS_MASK_X)) _readers[(int)'x'] = 0;
if(!(axis_mask & AXIS_MASK_Y)) _readers[(int)'y'] = 0;
if(!(axis_mask & AXIS_MASK_Z)) _readers[(int)'z'] = 0;
if(!(axis_mask & AXIS_MASK_A)) _readers[(int)'a'] = 0;
if(!(axis_mask & AXIS_MASK_B)) _readers[(int)'b'] = 0;
if(!(axis_mask & AXIS_MASK_C)) _readers[(int)'c'] = 0;
if(!(axis_mask & AXIS_MASK_U)) _readers[(int)'u'] = 0;
if(!(axis_mask & AXIS_MASK_V)) _readers[(int)'v'] = 0;
if(!(axis_mask & AXIS_MASK_W)) _readers[(int)'w'] = 0;
synch();
write_g_codes((block_pointer) NULL, &_setup);
write_m_codes((block_pointer) NULL, &_setup);
write_settings(&_setup);
init_tool_parameters();
if ((iniFileName != NULL) && _setup.init_once && PYUSABLE ) {
try {
bp::object npmod = python_plugin->main_namespace[NAMEDPARAMS_MODULE];
bp::dict predef_dict = bp::extract<bp::dict>(npmod.attr("__dict__"));
bp::list iterkeys = (bp::list) predef_dict.iterkeys();
for (int i = 0; i < bp::len(iterkeys); i++) {
std::string key = bp::extract<std::string>(iterkeys[i]);
bp::object value = predef_dict[key];
if (PyCallable_Check(value.ptr())) {
CHP(init_python_predef_parameter(key.c_str()));
}
}
}
catch (bp::error_already_set) {
std::string exception_msg;
bool unexpected = false;
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
exception_msg = handle_pyerror();
unexpected = true;
}
bp::handle_exception();
PyErr_Clear();
CHKS(unexpected, "exception adding Python predefined named parameter: %s", exception_msg.c_str());
}
if (python_plugin->is_callable(NULL, INIT_FUNC)) {
bp::object retval, tupleargs, kwargs;
bp::list plist;
plist.append(*_setup.pythis); tupleargs = bp::tuple(plist);
kwargs = bp::dict();
python_plugin->call(NULL, INIT_FUNC, tupleargs, kwargs, retval);
CHKS(python_plugin->plugin_status() == PLUGIN_EXCEPTION,
"pycall(%s):\n%s", INIT_FUNC,
python_plugin->last_exception().c_str());
}
}
_setup.init_once = 0;
return INTERP_OK;
}
void Interp::set_loop_on_main_m99(bool state) {
_setup.loop_on_main_m99 = state;
}
int Interp::load_tool_table()
{
int n;
CHKS((_setup.pockets_max > CANON_POCKETS_MAX), NCE_POCKET_MAX_TOO_LARGE);
for (n = 0; n < _setup.pockets_max; n++) {
_setup.tool_table[n] = GET_EXTERNAL_TOOL_TABLE(n);
}
for (; n < CANON_POCKETS_MAX; n++) {
_setup.tool_table[n].toolno = -1;
ZERO_EMC_POSE(_setup.tool_table[n].offset);
_setup.tool_table[n].diameter = 0;
_setup.tool_table[n].orientation = 0;
_setup.tool_table[n].frontangle = 0;
_setup.tool_table[n].backangle = 0;
}
set_tool_parameters();
return INTERP_OK;
}
int Interp::open(const char *filename) {
char *line;
int index;
int length;
logOword("open()");
if(_setup.use_lazy_close && _setup.lazy_closing)
{
_setup.use_lazy_close = 0; close();
_setup.use_lazy_close = 1;
_setup.lazy_closing = 0;
}
CHKS((_setup.file_pointer != NULL), NCE_A_FILE_IS_ALREADY_OPEN);
CHKS((strlen(filename) > (LINELEN - 1)), NCE_FILE_NAME_TOO_LONG);
_setup.file_pointer = fopen(filename, "r");
CHKS((_setup.file_pointer == NULL), NCE_UNABLE_TO_OPEN_FILE, filename);
line = _setup.linetext;
for (index = -1; index == -1;) {
CHKS((fgets(line, LINELEN, _setup.file_pointer) ==
NULL), NCE_FILE_ENDED_WITH_NO_PERCENT_SIGN);
length = strlen(line);
if (length == (LINELEN - 1)) { for (; fgetc(_setup.file_pointer) != '\n' && !feof(_setup.file_pointer););
ERS(NCE_COMMAND_TOO_LONG);
}
for (index = (length - 1); (index >= 0) && (isspace(line[index])); index--);
}
if (line[index] == '%') {
for (index--; (index >= 0) && (isspace(line[index])); index--);
if (index == -1) {
_setup.percent_flag = true;
_setup.sequence_number = 1; } else {
fseek(_setup.file_pointer, 0, SEEK_SET);
_setup.percent_flag = false;
_setup.sequence_number = 0; }
} else {
fseek(_setup.file_pointer, 0, SEEK_SET);
_setup.percent_flag = false;
_setup.sequence_number = 0; }
strcpy(_setup.filename, filename);
reset();
return INTERP_OK;
}
int Interp::read_inputs(setup_pointer settings)
{
if (settings->probe_flag) {
CHKS((GET_EXTERNAL_QUEUE_EMPTY() == 0),
NCE_QUEUE_IS_NOT_EMPTY_AFTER_PROBING);
set_probe_data(&_setup);
settings->probe_flag = false;
}
if (settings->toolchange_flag) {
CHKS((GET_EXTERNAL_QUEUE_EMPTY() == 0),
_("Queue is not empty after tool change"));
refresh_actual_position(&_setup);
load_tool_table();
settings->toolchange_flag = false;
}
settings->parameters[5600] = GET_EXTERNAL_TC_FAULT();
settings->parameters[5601] = GET_EXTERNAL_TC_REASON();
if (settings->input_flag) {
CHKS((GET_EXTERNAL_QUEUE_EMPTY() == 0),
NCE_QUEUE_IS_NOT_EMPTY_AFTER_INPUT);
if (settings->input_digital) { settings->parameters[5399] =
GET_EXTERNAL_DIGITAL_INPUT(settings->input_index,
(settings->parameters[5399] != 0.0));
} else { settings->parameters[5399] =
GET_EXTERNAL_ANALOG_INPUT(settings->input_index, settings->parameters[5399]);
}
settings->input_flag = false;
}
return INTERP_OK;
}
int Interp::_read(const char *command) {
static char name[] = "Interp::read";
int read_status;
#if 0#endif
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))) {
logDebug("read(): skipping read");
_setup.line_length = 0;
_setup.linetext[0] = 0;
return INTERP_OK;
}
_setup.call_state = CS_NORMAL;
CHP(read_inputs(&_setup));
CHKN(((command == NULL) && (_setup.file_pointer == NULL)),
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_ERROR && _setup.skipping_to_sub) {
_setup.skipping_to_sub = NULL;
}
if(command)logDebug("%s:[cmd]:|%s|", name, command);
else logDebug("%s:|%s|", name, _setup.linetext);
if ((read_status == INTERP_EXECUTE_FINISH)
|| (read_status == INTERP_OK)) {
if (_setup.line_length != 0) {
CHP(parse_line(_setup.blocktext, &(EXECUTING_BLOCK(_setup)), &_setup));
}
else {
if (EXECUTING_BLOCK(_setup).o_type != O_none) {
EXECUTING_BLOCK(_setup).o_type = 0;
}
}
} else if (read_status == INTERP_ENDFILE) {
CHKS((_setup.skipping_o != NULL),
"Failed to find sub 'O%s' before EOF", _setup.skipping_o);
} else
ERP(read_status);
return read_status;
}
int Interp::read(const char *command)
{
int status;
if ((status = _read(command)) > INTERP_MIN_ERROR) {
unwind_call(status, __FILE__,__LINE__,__FUNCTION__);
}
return status;
}
int Interp::unwind_call(int status, const char *file, int line, const char *function)
{
logDebug("unwind_call: call_level=%d status=%s from %s %s:%d",
_setup.call_level, interp_status(status), function, file, line);
for(; _setup.call_level > 0; _setup.call_level--) {
int i;
context * sub = _setup.sub_context + _setup.call_level - 1;
free_named_parameters(&_setup.sub_context[_setup.call_level]);
if(sub->subName) {
logDebug("unwind_call leaving sub '%s'", sub->subName);
sub->subName = 0;
}
if (sub->call_type != CT_NGC_M98_SUB) for(i=0; i<INTERP_SUB_PARAMS; i++) {
_setup.parameters[i+INTERP_FIRST_SUBROUTINE_PARAM] =
sub->saved_params[i];
}
if (!_setup.file_pointer) continue;
if (sub->filename && sub->filename[0]) {
if(0 != strcmp(_setup.filename, sub->filename)) {
fclose(_setup.file_pointer);
_setup.file_pointer = fopen(sub->filename, "r");
logDebug("unwind_call: reopening '%s' at %ld",
sub->filename, sub->position);
strcpy(_setup.filename, sub->filename);
}
fseek(_setup.file_pointer, sub->position, SEEK_SET);
}
_setup.sequence_number = sub->sequence_number;
logDebug("unwind_call: setting sequence number=%d from frame %d",
_setup.sequence_number,_setup.call_level);
}
if(_setup.sub_name) {
logDebug("unwind_call: exiting current sub '%s'\n", _setup.sub_name);
_setup.sub_name = 0;
}
_setup.remap_level = 0; _setup.defining_sub = 0;
_setup.skipping_o = 0;
_setup.skipping_to_sub = 0;
_setup.offset_map.clear();
_setup.mdi_interrupt = false;
qc_reset();
return INTERP_OK;
}
int Interp::read() {
return read(0);
}
int Interp::reset()
{
_setup.call_state = CS_NORMAL;
_setup.linetext[0] = 0;
_setup.blocktext[0] = 0;
_setup.line_length = 0;
ON_RESET();
unwind_call(INTERP_OK, __FILE__,__LINE__,__FUNCTION__);
return INTERP_OK;
}
int Interp::restore_parameters(const char *filename) {
FILE *infile;
char line[256];
int variable;
double value;
int required; int index; double *pars; int k;
if(access(filename, F_OK) == -1)
return INTERP_OK;
infile = fopen(filename, "r");
CHKS((infile == NULL), _("Unable to open parameter file: '%s'"), filename);
pars = _setup.parameters;
k = 0;
index = 0;
required = _required_parameters[index++];
while (feof(infile) == 0) {
if (fgets(line, 256, infile) == NULL) {
break;
}
if (sscanf(line, "%d %lf", &variable, &value) == 2) {
CHKS(((variable <= 0)
|| (variable >= RS274NGC_MAX_PARAMETERS)),
NCE_PARAMETER_NUMBER_OUT_OF_RANGE);
for (; k < RS274NGC_MAX_PARAMETERS; k++) {
if (k > variable) {
fclose(infile);
ERS(NCE_PARAMETER_FILE_OUT_OF_ORDER);
} else if (k == variable) {
pars[k] = value;
if (k == required)
required = _required_parameters[index++];
k++;
break;
} else {
if (k == required)
required = _required_parameters[index++];
pars[k] = 0;
}
}
}
}
fclose(infile);
for (; k < RS274NGC_MAX_PARAMETERS; k++) {
pars[k] = 0;
}
return INTERP_OK;
}
int Interp::save_parameters(const char *filename, const double parameters[]) {
FILE *infile;
FILE *outfile;
char line[PATH_MAX];
int variable;
double value;
int required; int index; int k;
std::string tempfile = std::string(filename) + ".new";
outfile = fopen(tempfile.c_str(), "w");
CHKS((outfile == NULL), NCE_CANNOT_OPEN_VARIABLE_FILE);
infile = fopen(filename, "r");
if(!infile)
infile = fopen("/dev/null", "r");
k = 0;
index = 0;
required = _required_parameters[index++];
while (feof(infile) == 0) {
if (fgets(line, sizeof(line), infile) == NULL) {
break;
}
if (sscanf(line, "%d %lf", &variable, &value) == 2) {
CHKS(((variable <= 0)
|| (variable >= RS274NGC_MAX_PARAMETERS)),
NCE_PARAMETER_NUMBER_OUT_OF_RANGE);
for (; k < RS274NGC_MAX_PARAMETERS; k++) {
if (k > variable) {
fclose(infile);
fclose(outfile);
ERS(NCE_PARAMETER_FILE_OUT_OF_ORDER);
} else if (k == variable) {
sprintf(line, "%d\t%f\n", k, parameters[k]);
fputs(line, outfile);
if (k == required)
required = _required_parameters[index++];
k++;
break;
} else if (k == required) {
sprintf(line, "%d\t%f\n", k, parameters[k]);
fputs(line, outfile);
required = _required_parameters[index++];
}
}
}
}
fclose(infile);
for (; k < RS274NGC_MAX_PARAMETERS; k++) {
if (k == required) {
sprintf(line, "%d\t%f\n", k, parameters[k]);
fputs(line, outfile);
required = _required_parameters[index++];
}
}
fflush(outfile);
fdatasync(fileno(outfile));
fclose(outfile);
std::string bakfile = std::string(filename)
+ RS274NGC_PARAMETER_FILE_BACKUP_SUFFIX;
unlink(bakfile.c_str());
if(link(filename, bakfile.c_str()) < 0)
perror("link (updating variable file)");
if(rename(tempfile.c_str(), filename) < 0)
perror("rename (updating variable file)");
return INTERP_OK;
}
int Interp::synch()
{
char file_name[LINELEN];
_setup.current_x = GET_EXTERNAL_POSITION_X();
_setup.current_y = GET_EXTERNAL_POSITION_Y();
_setup.current_z = GET_EXTERNAL_POSITION_Z();
_setup.AA_current = GET_EXTERNAL_POSITION_A();
_setup.BB_current = GET_EXTERNAL_POSITION_B();
_setup.CC_current = GET_EXTERNAL_POSITION_C();
_setup.u_current = GET_EXTERNAL_POSITION_U();
_setup.v_current = GET_EXTERNAL_POSITION_V();
_setup.w_current = GET_EXTERNAL_POSITION_W();
_setup.control_mode = GET_EXTERNAL_MOTION_CONTROL_MODE();
_setup.current_pocket = GET_EXTERNAL_TOOL_SLOT();
_setup.feed_rate = GET_EXTERNAL_FEED_RATE();
_setup.flood = GET_EXTERNAL_FLOOD();
_setup.length_units = GET_EXTERNAL_LENGTH_UNIT_TYPE();
_setup.mist = GET_EXTERNAL_MIST();
_setup.plane = GET_EXTERNAL_PLANE();
_setup.selected_pocket = GET_EXTERNAL_SELECTED_TOOL_SLOT();
_setup.pockets_max = GET_EXTERNAL_POCKETS_MAX();
_setup.traverse_rate = GET_EXTERNAL_TRAVERSE_RATE();
_setup.feed_override = GET_EXTERNAL_FEED_OVERRIDE_ENABLE();
_setup.adaptive_feed = GET_EXTERNAL_ADAPTIVE_FEED_ENABLE();
_setup.feed_hold = GET_EXTERNAL_FEED_HOLD_ENABLE();
for (int s = 0; s < EMCMOT_MAX_SPINDLES; s++){
_setup.speed[s] = GET_EXTERNAL_SPEED(s);
_setup.spindle_turning[s] = GET_EXTERNAL_SPINDLE(s);
_setup.speed_override[s] = GET_EXTERNAL_SPINDLE_OVERRIDE_ENABLE(s);
_setup.spindle_mode[s] = CONSTANT_RPM;
}
GET_EXTERNAL_PARAMETER_FILE_NAME(file_name, (LINELEN - 1));
save_parameters(((file_name[0] ==
0) ?
RS274NGC_PARAMETER_FILE_NAME_DEFAULT :
file_name), _setup.parameters);
load_tool_table();
write_settings(&_setup);
return INTERP_OK;
}
void Interp::active_g_codes(int *codes) {
int n;
for (n = 0; n < ACTIVE_G_CODES; n++) {
codes[n] = _setup.active_g_codes[n];
}
}
void Interp::active_m_codes(int *codes) {
int n;
for (n = 0; n < ACTIVE_M_CODES; n++) {
codes[n] = _setup.active_m_codes[n];
}
}
void Interp::active_settings(double *settings) {
int n;
for (n = 0; n < ACTIVE_SETTINGS; n++) {
settings[n] = _setup.active_settings[n];
}
}
void Interp::setError(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsnprintf(savedError, LINELEN, fmt, ap);
va_end(ap);
}
const char *Interp::getSavedError()
{
return savedError;
}
int Interp::setSavedError(const char *msg)
{
savedError[0] = '\0';
strncpy(savedError, msg, LINELEN);
return INTERP_OK;
}
char * Interp::error_text(int error_code, char *error_text, size_t max_size) {
if(error_code == INTERP_ERROR)
{
strncpy(error_text, savedError, max_size);
error_text[max_size-1] = 0;
return error_text;
}
else if (error_code == INTERP_FILE_NOT_OPEN)
{
strncpy(error_text, "File not open", max_size);
error_text[max_size-1] = 0;
return error_text;
}
error_text[0] = 0;
return error_text;
}
char *Interp::file_name(char *file_name, size_t max_size) {
if (strlen(_setup.filename) < ((size_t) max_size))
strcpy(file_name, _setup.filename);
else
file_name[0] = 0;
return file_name;
}
size_t Interp::line_length()
{
return _setup.line_length;
}
char *Interp::line_text(char *line_text, size_t max_size) {
size_t n;
char *the_text;
the_text = _setup.linetext;
for (n = 0; n < (max_size - 1); n++) {
if (the_text[n] != 0)
line_text[n] = the_text[n];
else
break;
}
line_text[n] = 0;
return line_text;
}
int Interp::sequence_number()
{
return _setup.sequence_number;
}
char *Interp::stack_name(int stack_index, char *function_name, size_t max_size) {
size_t n;
char *the_name;
if ((stack_index > -1) && (stack_index < STACK_LEN)) {
the_name = _setup.stack[stack_index];
for (n = 0; n < (max_size - 1); n++) {
if (the_name[n] != 0)
function_name[n] = the_name[n];
else
break;
}
function_name[n] = 0;
} else
function_name[0] = 0;
return function_name;
}
int Interp::ini_load(const char *filename)
{
IniFile inifile;
const char *inistring;
if (inifile.Open(filename) == false) {
logDebug("Unable to open inifile:%s:", filename);
return -1;
}
logDebug("Opened inifile:%s:", filename);
char parameter_file_name[LINELEN]={};
if (NULL != (inistring = inifile.Find("PARAMETER_FILE", "RS274NGC"))) {
strncpy(parameter_file_name, inistring, LINELEN);
if (parameter_file_name[LINELEN-1] != '\0') {
logDebug("%s:[RS274NGC]PARAMETER_FILE is too long (max len %d)", filename, LINELEN-1);
} else {
logDebug("found PARAMETER_FILE:%s:", parameter_file_name);
}
} else {
logDebug("did not find PARAMETER_FILE");
}
SET_PARAMETER_FILE_NAME(parameter_file_name);
CHKS(strlen(parameter_file_name) > 0, _("Parameter file name is missing"));
inifile.Close();
return 0;
}
int Interp::init_tool_parameters()
{
if (_setup.random_toolchanger) {
_setup.parameters[5400] = _setup.tool_table[0].toolno;
_setup.parameters[5401] = _setup.tool_table[0].offset.tran.x;
_setup.parameters[5402] = _setup.tool_table[0].offset.tran.y;
_setup.parameters[5403] = _setup.tool_table[0].offset.tran.z;
_setup.parameters[5404] = _setup.tool_table[0].offset.a;
_setup.parameters[5405] = _setup.tool_table[0].offset.b;
_setup.parameters[5406] = _setup.tool_table[0].offset.c;
_setup.parameters[5407] = _setup.tool_table[0].offset.u;
_setup.parameters[5408] = _setup.tool_table[0].offset.v;
_setup.parameters[5409] = _setup.tool_table[0].offset.w;
_setup.parameters[5410] = _setup.tool_table[0].diameter;
_setup.parameters[5411] = _setup.tool_table[0].frontangle;
_setup.parameters[5412] = _setup.tool_table[0].backangle;
_setup.parameters[5413] = _setup.tool_table[0].orientation;
} else {
if (_setup.tool_table[0].toolno == -1) {
default_tool_parameters();
}
}
return 0;
}
int Interp::default_tool_parameters()
{
_setup.parameters[5400] = 0; _setup.parameters[5401] = 0; _setup.parameters[5402] = 0; _setup.parameters[5403] = 0; _setup.parameters[5404] = 0; _setup.parameters[5405] = 0; _setup.parameters[5406] = 0; _setup.parameters[5407] = 0; _setup.parameters[5408] = 0; _setup.parameters[5409] = 0; _setup.parameters[5410] = 0; _setup.parameters[5411] = 0; _setup.parameters[5412] = 0; _setup.parameters[5413] = 0; return 0;
}
int Interp::set_tool_parameters()
{
if ((! _setup.random_toolchanger) && (_setup.tool_table[0].toolno <= 0)) {
default_tool_parameters();
return 0;
}
_setup.parameters[5400] = _setup.tool_table[0].toolno;
_setup.parameters[5401] = _setup.tool_table[0].offset.tran.x;
_setup.parameters[5402] = _setup.tool_table[0].offset.tran.y;
_setup.parameters[5403] = _setup.tool_table[0].offset.tran.z;
_setup.parameters[5404] = _setup.tool_table[0].offset.a;
_setup.parameters[5405] = _setup.tool_table[0].offset.b;
_setup.parameters[5406] = _setup.tool_table[0].offset.c;
_setup.parameters[5407] = _setup.tool_table[0].offset.u;
_setup.parameters[5408] = _setup.tool_table[0].offset.v;
_setup.parameters[5409] = _setup.tool_table[0].offset.w;
_setup.parameters[5410] = _setup.tool_table[0].diameter;
_setup.parameters[5411] = _setup.tool_table[0].frontangle;
_setup.parameters[5412] = _setup.tool_table[0].backangle;
_setup.parameters[5413] = _setup.tool_table[0].orientation;
return 0;
}
int Interp::enter_remap(void)
{
_setup.remap_level++;
if (_setup.remap_level == MAX_NESTED_REMAPS) {
_setup.remap_level = 0;
ERS("maximum nesting of remapped blocks execeeded");
}
CONTROLLING_BLOCK(_setup) = EXECUTING_BLOCK(_setup);
CONTROLLING_BLOCK(_setup).breadcrumbs = 0; CONTROLLING_BLOCK(_setup).executing_remap = NULL;
logRemap("enter_remap into %d - saved_line_number=%d",
_setup.remap_level, _setup.sequence_number);
CONTROLLING_BLOCK(_setup).saved_line_number = _setup.sequence_number;
_setup.sequence_number = 0;
return INTERP_OK;
}
int Interp::leave_remap(void)
{
logRemap("leave_remap from %d propagate saved_line_number=%d",
_setup.remap_level, CONTROLLING_BLOCK(_setup).saved_line_number);
_setup.sequence_number = CONTROLLING_BLOCK(_setup).saved_line_number;
_setup.blocks[_setup.remap_level].executing_remap = NULL;
_setup.remap_level--; if (_setup.remap_level < 0) {
ERS("BUG: remap_level < 0 : %d",_setup.remap_level);
}
return INTERP_OK;
}
int Interp::on_abort(int reason, const char *message)
{
logDebug("on_abort reason=%d message='%s'", reason, message);
reset();
_setup.mdi_interrupt = false;
_setup.toolchange_flag = false;
_setup.probe_flag = false;
_setup.input_flag = false;
if (_setup.on_abort_command == NULL) {
return -1;
}
char cmd[LINELEN];
snprintf(cmd,sizeof(cmd), "%s [%d]",_setup.on_abort_command, reason);
int status = execute(cmd);
ERP(status);
return status;
}
FILE *Interp::find_ngc_file(setup_pointer settings,const char *basename, char *foundhere )
{
FILE *newFP;
char tmpFileName[PATH_MAX+1];
char newFileName[PATH_MAX+1];
char foundPlace[PATH_MAX+1];
int dct;
sprintf(tmpFileName, "%s.ngc", basename);
sprintf(newFileName, "%s/%s", settings->program_prefix, tmpFileName);
newFP = fopen(newFileName, "r");
if (!newFP) {
for (dct = 0; dct < MAX_SUB_DIRS; dct++) {
if (!settings->subroutines[dct])
continue;
sprintf(newFileName, "%s/%s", settings->subroutines[dct], tmpFileName);
newFP = fopen(newFileName, "r");
if (newFP) {
break; }
}
}
if (!newFP) {
int ret;
ret = findFile(settings->wizard_root, tmpFileName, foundPlace);
if (INTERP_OK == ret) {
sprintf(newFileName, "%s/%s",
foundPlace, tmpFileName);
newFP = fopen(newFileName, "r");
}
}
if (foundhere && (newFP != NULL))
strcpy(foundhere, newFileName);
return newFP;
}
const char *strstore(const char *s)
{
static std::unordered_set<std::string> stringtable;
using namespace std;
if (s == nullptr) {
throw 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();
}