接续上一轮:推进浏览器验证与M428配置收拢

结论:已完成浏览器侧真实加载验证,M428/M429/M430 的配置入口进一步从 LinuxCNC INI/HALFILE/REMAP 来源生成,native 与 source-link 验证通过。
This commit is contained in:
cnc
2026-05-30 10:03:21 +08:00
parent b40914747d
commit de273bf830
141 changed files with 11255 additions and 1259 deletions

3
core/wasm_shims/Python.h Normal file
View File

@@ -0,0 +1,3 @@
#pragma once
#include "boost/python/object.hpp"

View File

@@ -0,0 +1,18 @@
#ifndef CNC_SIM_WASM_SHIMS_BOOST_NONCOPYABLE_HPP
#define CNC_SIM_WASM_SHIMS_BOOST_NONCOPYABLE_HPP
namespace boost {
class noncopyable {
protected:
noncopyable() = default;
~noncopyable() = default;
private:
noncopyable(const noncopyable &) = delete;
noncopyable &operator=(const noncopyable &) = delete;
};
} // namespace boost
#endif // CNC_SIM_WASM_SHIMS_BOOST_NONCOPYABLE_HPP

View File

@@ -0,0 +1,10 @@
#pragma once
#include <boost/call_traits.hpp>
#include <boost/config.hpp>
#ifndef BOOST_DEDUCED_TYPENAME
#define BOOST_DEDUCED_TYPENAME typename
#endif
#include "boost/python/object.hpp"

View File

@@ -0,0 +1,3 @@
#pragma once
#include "boost/python/object.hpp"

View File

@@ -0,0 +1,13 @@
#pragma once
#include "boost/python/object.hpp"
namespace boost {
namespace python {
template <typename... Args>
void def(Args &&...) {
}
} // namespace python
} // namespace boost

View File

@@ -0,0 +1,3 @@
#pragma once
#include "boost/python/object.hpp"

View File

@@ -0,0 +1,25 @@
#pragma once
#include "boost/python/object.hpp"
namespace boost {
namespace python {
template <typename T>
class enum_ {
public:
explicit enum_(const char *) {
}
template <typename Value>
enum_ &value(const char *, Value) {
return *this;
}
enum_ &export_values() {
return *this;
}
};
} // namespace python
} // namespace boost

View File

@@ -0,0 +1,13 @@
#pragma once
#include "boost/python/object.hpp"
namespace boost {
namespace python {
template <typename Exception, typename Translator>
void register_exception_translator(Translator) {
}
} // namespace python
} // namespace boost

View File

@@ -0,0 +1,5 @@
#pragma once
#include "boost/python/object.hpp"
#define BOOST_PYTHON_MODULE(name) extern "C" void init_##name()

View File

@@ -1,24 +1,126 @@
#pragma once
#include <cstddef>
#include <cstdarg>
#include <sstream>
#include <stdexcept>
#include <string>
#include "boost/noncopyable.hpp"
extern "C" {
using Py_ssize_t = std::ptrdiff_t;
struct _object;
using PyObject = _object;
struct _typeobject {
const char *tp_name;
std::size_t tp_basicsize;
std::size_t tp_itemsize;
void *tp_dealloc;
void *tp_print;
void *tp_getattr;
void *tp_setattr;
void *tp_compare;
void *tp_repr;
void *tp_as_number;
void *tp_as_sequence;
void *tp_as_mapping;
void *tp_hash;
void *tp_call;
void *tp_str;
void *tp_getattro;
void *tp_setattro;
void *tp_as_buffer;
unsigned long tp_flags;
const char *tp_doc;
void *tp_traverse;
void *tp_clear;
void *tp_richcompare;
Py_ssize_t tp_weaklistoffset;
void *tp_iter;
void *tp_iternext;
void *tp_methods;
void *tp_members;
void *tp_getset;
struct _typeobject *tp_base;
void *tp_dict;
void *tp_descr_get;
void *tp_descr_set;
Py_ssize_t tp_dictoffset;
void *tp_init;
void *tp_alloc;
PyObject *(*tp_new)(struct _typeobject *, PyObject *, PyObject *);
void *tp_free;
void *tp_is_gc;
void *tp_bases;
void *tp_mro;
void *tp_cache;
void *tp_subclasses;
void *tp_weaklink;
void *tp_del;
unsigned int tp_version_tag;
void *tp_finalize;
#if PY_VERSION_HEX >= 0x030800f0
void *tp_vectorcall;
#if PY_VERSION_HEX >= 0x030c00f0
void *tp_watched;
#if PY_VERSION_HEX >= 0x030d00f0
void *tp_versions_used;
#endif
#endif
#endif
};
using PyTypeObject = _typeobject;
struct _object {
PyTypeObject *ob_type;
};
using PyObject = _object;
struct _inittab {
const char *name;
PyObject *(*initfunc)(void);
};
using PyCFunction = PyObject *(*)(PyObject *, PyObject *);
using getter = PyObject *(*)(PyObject *, void *);
using setter = int (*)(PyObject *, PyObject *, void *);
struct PyGetSetDef {
char *name;
getter get;
setter set;
char *doc;
void *closure;
};
struct PyMemberDef {
char *name;
int type;
Py_ssize_t offset;
int flags;
char *doc;
};
struct PyMethodDef {
const char *ml_name;
PyCFunction ml_meth;
int ml_flags;
const char *ml_doc;
};
struct PyModuleDef {
void *m_base;
const char *m_name;
const char *m_doc;
Py_ssize_t m_size;
PyMethodDef *m_methods;
void *m_slots;
void *m_traverse;
void *m_clear;
void *m_free;
};
int Py_IsInitialized(void);
PyObject *PyErr_Occurred(void);
void PyErr_Clear(void);
@@ -31,21 +133,66 @@ int PyUnicode_Check(PyObject *);
int PyLong_Check(PyObject *);
int PyFloat_Check(PyObject *);
int PyGen_Check(PyObject *);
int PyObject_IsInstance(PyObject *, PyObject *);
PyObject *PyObject_Str(PyObject *);
const char *PyUnicode_AsUTF8(PyObject *);
PyObject *PyUnicode_FromString(const char *);
void PyErr_SetObject(PyObject *, PyObject *);
PyObject *PyErr_Format(PyObject *, const char *, ...);
void Py_DecRef(PyObject *);
int PyArg_ParseTuple(PyObject *, const char *, ...);
int PyArg_VaParse(PyObject *, const char *, va_list);
PyObject *PyObject_CallMethod(PyObject *, char *, char *, ...);
PyObject *PyObject_GetAttrString(PyObject *, const char *);
int PyObject_SetAttrString(PyObject *, const char *, PyObject *);
int PyObject_IsTrue(PyObject *);
PyObject *PyLong_FromLong(long);
long PyLong_AsLong(PyObject *);
double PyFloat_AsDouble(PyObject *);
PyObject *PyTuple_New(Py_ssize_t);
PyObject *PyTuple_GetItem(PyObject *, Py_ssize_t);
Py_ssize_t PyTuple_Size(PyObject *);
int PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *);
PyObject *PyList_New(Py_ssize_t);
PyObject *PyList_GetItem(PyObject *, Py_ssize_t);
Py_ssize_t PyList_Size(PyObject *);
int PyList_SetItem(PyObject *, Py_ssize_t, PyObject *);
PyObject *PySequence_GetItem(PyObject *, Py_ssize_t);
Py_ssize_t PySequence_Length(PyObject *);
PyObject *Py_BuildValue(const char *, ...);
PyObject *PyModule_Create(PyModuleDef *);
int PyModule_AddObject(PyObject *, const char *, PyObject *);
int PyType_Ready(PyTypeObject *);
PyObject *PyType_GenericNew(PyTypeObject *, PyObject *, PyObject *);
void *PyObject_NewShim(std::size_t, PyTypeObject *);
extern PyObject *PyExc_KeyError;
extern PyObject *PyExc_KeyboardInterrupt;
extern PyObject *PyExc_RuntimeError;
extern PyObject *PyExc_StopIteration;
extern PyObject *PyExc_TypeError;
extern PyObject *_Py_NoneStructPtr;
extern PyTypeObject PyString_Type;
extern PyTypeObject PyInt_Type;
extern PyTypeObject PyList_Type;
#define PyObject_HEAD PyObject ob_base;
#define PyVarObject_HEAD_INIT(type, size)
#define PyModuleDef_HEAD_INIT nullptr
#define Py_TPFLAGS_DEFAULT 0
#define PyMODINIT_FUNC extern "C" PyObject *
#define METH_VARARGS 0x0001
#define Py_None (_Py_NoneStructPtr)
#define Py_TYPE(ob) ((ob)->ob_type)
#define Py_DECREF(ob) Py_DecRef(reinterpret_cast<PyObject *>(ob))
#define Py_XDECREF(ob) \
do { \
if (ob) { \
Py_DecRef(ob); \
Py_DecRef(reinterpret_cast<PyObject *>(ob)); \
} \
} while (0)
#define PyTuple_SET_ITEM(op, i, v) PyTuple_SetItem((op), (i), (v))
#define PyList_SET_ITEM(op, i, v) PyList_SetItem((op), (i), (v))
#define PyObject_New(type, typeobj) reinterpret_cast<type *>(PyObject_NewShim(sizeof(type), (typeobj)))
}
@@ -106,6 +253,93 @@ public:
}
};
struct no_init_t {};
inline constexpr no_init_t no_init{};
struct default_call_policies {};
struct reference_existing_object {};
template <typename T>
struct return_value_policy {
};
template <int, int>
struct with_custodian_and_ward_postcall {
};
template <typename... Args>
struct init {
};
class arg {
public:
explicit arg(const char *) {
}
};
template <typename T = void>
struct type_info {
};
template <typename T>
type_info<T> type_id() {
return {};
}
template <typename... Args>
object make_getter(Args &&...) {
return {};
}
template <typename... Args>
object make_setter(Args &&...) {
return {};
}
template <typename... Args>
object make_function(Args &&...) {
return {};
}
template <typename T, typename Bases = void>
class class_ {
public:
explicit class_(const char *) {
}
class_(const char *, no_init_t) {
}
class_(const char *, const char *) {
}
class_(const char *, const char *, no_init_t) {
}
template <typename Arg>
class_(const char *, Arg) {
}
template <typename... Args>
class_ &def(Args &&...) {
return *this;
}
template <typename... Args>
class_ &def_readwrite(Args &&...) {
return *this;
}
template <typename... Args>
class_ &add_property(Args &&...) {
return *this;
}
PyObject *ptr() const {
return nullptr;
}
};
inline object getattr(const object &, const char *) {
return {};
}
@@ -115,6 +349,10 @@ public:
template <typename T>
void append(const T &) {
}
template <typename T>
void extend(const T &) {
}
};
class dict : public object {
@@ -131,8 +369,35 @@ public:
}
};
template <typename... Args>
tuple make_tuple(Args &&...) {
return {};
}
inline object operator%(const char *, const tuple &) {
return {};
}
inline object operator%(const object &, const tuple &) {
return {};
}
inline object operator+(const object &, const object &) {
return {};
}
inline object operator+(const object &, const char *) {
return {};
}
inline object operator+(const char *, const object &) {
return {};
}
class scope {
public:
scope() = default;
explicit scope(const object &) {
}
@@ -187,6 +452,8 @@ allow_null_result<T> allow_null(T *value) {
template <typename T = void>
class handle {
public:
handle() = default;
template <typename U>
explicit handle(const U &) {
}
@@ -194,6 +461,10 @@ public:
explicit operator bool() const {
return false;
}
void *get() const {
return nullptr;
}
};
class str : public object {

View File

@@ -0,0 +1,16 @@
#pragma once
#include "boost/python/object.hpp"
namespace boost {
namespace python {
namespace objects {
template <typename T>
void *registered_class_object(T) {
return nullptr;
}
} // namespace objects
} // namespace python
} // namespace boost

View File

@@ -0,0 +1,13 @@
#pragma once
#include "boost/python/object.hpp"
namespace boost {
namespace python {
template <int Owner = 1, typename BasePolicy = default_call_policies>
struct return_internal_reference : BasePolicy {
};
} // namespace python
} // namespace boost

View File

@@ -0,0 +1,11 @@
#pragma once
namespace boost {
namespace python {
template <typename Map>
class map_indexing_suite {
};
} // namespace python
} // namespace boost

View File

@@ -0,0 +1,99 @@
#include "cnc_sim_api.h"
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <wordexp.h>
namespace {
int collect_event(const CncSimEvent *event, void *user_data) {
auto *events = static_cast<std::vector<CncSimEvent> *>(user_data);
events->push_back(*event);
return 0;
}
bool near(double lhs, double rhs) {
return std::fabs(lhs - rhs) < 0.000001;
}
bool wordexp_expands_home() {
const char *home = std::getenv("HOME");
if (!home || !home[0]) {
return true;
}
wordexp_t expanded{};
if (wordexp("~/cnc_sim_wordexp_probe", &expanded, 0) != 0) {
return false;
}
const std::string expected = std::string(home) + "/cnc_sim_wordexp_probe";
const bool ok = expanded.we_wordc == 1 &&
expanded.we_wordv &&
expanded.we_wordv[0] &&
std::strcmp(expanded.we_wordv[0], expected.c_str()) == 0;
wordfree(&expanded);
return ok;
}
bool wordexp_expands_environment_variables() {
setenv("CNC_SIM_WORDEXP_PROBE", "linuxcnc-wordexp", 1);
wordexp_t expanded{};
if (wordexp("$CNC_SIM_WORDEXP_PROBE/path", &expanded, 0) != 0) {
return false;
}
const bool ok = expanded.we_wordc == 1 &&
expanded.we_wordv &&
expanded.we_wordv[0] &&
std::strcmp(expanded.we_wordv[0], "linuxcnc-wordexp/path") == 0;
wordfree(&expanded);
return ok;
}
} // namespace
int main() {
if (!wordexp_expands_home()) {
return 5;
}
if (!wordexp_expands_environment_variables()) {
return 6;
}
std::vector<CncSimEvent> events;
CncSimHandle *sim = cnc_sim_create();
if (!sim) {
return 1;
}
if (cnc_sim_set_event_callback(sim, collect_event, &events) != 0) {
cnc_sim_destroy(sim);
return 2;
}
const char program[] =
"G21 G90 G17\n"
"G0 X1\n"
"M30\n";
if (cnc_sim_parse_program(sim, program, sizeof(program) - 1) != 0) {
cnc_sim_destroy(sim);
return 3;
}
bool saw_linuxcnc_rapid = false;
bool saw_program_end = false;
for (const auto &event : events) {
saw_linuxcnc_rapid = saw_linuxcnc_rapid ||
(event.type == CNC_SIM_EVENT_RAPID &&
event.line == 2 &&
near(event.end.x, 1.0));
saw_program_end = saw_program_end || event.type == CNC_SIM_EVENT_PROGRAM_END;
}
cnc_sim_destroy(sim);
return saw_linuxcnc_rapid && saw_program_end ? 0 : 4;
}

20
core/wasm_shims/libgen.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef CNC_SIM_WASM_SHIMS_LIBGEN_H
#define CNC_SIM_WASM_SHIMS_LIBGEN_H
#ifdef __cplusplus
extern "C" {
#endif
char *dirname(char *);
char *basename(char *);
#ifdef __cplusplus
}
inline char *basename(const char *path)
{
return basename(const_cast<char *>(path));
}
#endif
#endif // CNC_SIM_WASM_SHIMS_LIBGEN_H

View File

@@ -1,6 +1,12 @@
#include "boost/python/object.hpp"
#include "hal.h"
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <string>
#include <wordexp.h>
int _task = 0;
extern "C" PyObject *PyInit_interpreter(void) {
@@ -11,6 +17,10 @@ extern "C" PyObject *PyInit_emccanon(void) {
return nullptr;
}
extern "C" PyObject *PyInit_gcode(void) {
return nullptr;
}
extern "C" {
struct _inittab builtin_modules[] = {
{"interpreter", PyInit_interpreter},
@@ -70,3 +80,119 @@ extern "C" int hal_get_param_value_by_name(const char *,
}
return -1;
}
namespace {
std::string expand_home_directory(const char *words) {
std::string expanded(words);
if (expanded.empty() || expanded[0] != '~') {
return expanded;
}
if (expanded.size() > 1 && expanded[1] != '/') {
return expanded;
}
const char *home = std::getenv("HOME");
if (!home || !home[0]) {
return expanded;
}
expanded.replace(0, 1, home);
return expanded;
}
bool variable_start(char value) {
const unsigned char ch = static_cast<unsigned char>(value);
return std::isalpha(ch) || value == '_';
}
bool variable_char(char value) {
const unsigned char ch = static_cast<unsigned char>(value);
return std::isalnum(ch) || value == '_';
}
std::string expand_environment_variables(const std::string &words) {
std::string expanded;
expanded.reserve(words.size());
for (size_t index = 0; index < words.size();) {
if (words[index] != '$' || index + 1 >= words.size()) {
expanded.push_back(words[index++]);
continue;
}
if (words[index + 1] == '{') {
const size_t end = words.find('}', index + 2);
if (end == std::string::npos || end == index + 2) {
expanded.push_back(words[index++]);
continue;
}
const std::string name = words.substr(index + 2, end - index - 2);
if (const char *value = std::getenv(name.c_str())) {
expanded += value;
}
index = end + 1;
continue;
}
if (!variable_start(words[index + 1])) {
expanded.push_back(words[index++]);
continue;
}
size_t end = index + 2;
while (end < words.size() && variable_char(words[end])) {
++end;
}
const std::string name = words.substr(index + 1, end - index - 1);
if (const char *value = std::getenv(name.c_str())) {
expanded += value;
}
index = end;
}
return expanded;
}
std::string expand_path_word(const char *words) {
return expand_environment_variables(expand_home_directory(words));
}
} // namespace
extern "C" int wordexp(const char *words, wordexp_t *pwordexp, int) {
if (!words || !pwordexp) {
return WRDE_BADVAL;
}
const std::string expanded = expand_path_word(words);
char **wordv = static_cast<char **>(std::calloc(2, sizeof(char *)));
if (!wordv) {
return WRDE_NOSPACE;
}
wordv[0] = static_cast<char *>(std::malloc(expanded.size() + 1));
if (!wordv[0]) {
std::free(wordv);
return WRDE_NOSPACE;
}
std::strcpy(wordv[0], expanded.c_str());
pwordexp->we_wordc = 1;
pwordexp->we_wordv = wordv;
pwordexp->we_offs = 0;
return 0;
}
extern "C" void wordfree(wordexp_t *pwordexp) {
if (!pwordexp || !pwordexp->we_wordv) {
return;
}
for (size_t index = 0; index < pwordexp->we_wordc; ++index) {
std::free(pwordexp->we_wordv[index]);
}
std::free(pwordexp->we_wordv);
pwordexp->we_wordc = 0;
pwordexp->we_wordv = nullptr;
pwordexp->we_offs = 0;
}

View File

@@ -1,13 +1,21 @@
#include "boost/python/object.hpp"
#include <cstdlib>
extern "C" {
static PyTypeObject none_type = {"NoneType"};
static PyObject none_object = {&none_type};
PyObject *PyExc_KeyError = reinterpret_cast<PyObject *>(1);
PyObject *PyExc_StopIteration = reinterpret_cast<PyObject *>(2);
PyObject *PyExc_KeyboardInterrupt = reinterpret_cast<PyObject *>(2);
PyObject *PyExc_RuntimeError = reinterpret_cast<PyObject *>(3);
PyObject *PyExc_StopIteration = reinterpret_cast<PyObject *>(4);
PyObject *PyExc_TypeError = reinterpret_cast<PyObject *>(5);
PyObject *_Py_NoneStructPtr = &none_object;
PyTypeObject PyString_Type = {"str"};
PyTypeObject PyInt_Type = {"int"};
PyTypeObject PyList_Type = {"list"};
int Py_IsInitialized(void) {
return 1;
@@ -62,6 +70,10 @@ int PyGen_Check(PyObject *) {
return 0;
}
int PyObject_IsInstance(PyObject *, PyObject *) {
return 0;
}
PyObject *PyObject_Str(PyObject *) {
return &none_object;
}
@@ -70,7 +82,122 @@ const char *PyUnicode_AsUTF8(PyObject *) {
return "";
}
PyObject *PyUnicode_FromString(const char *) {
return &none_object;
}
void PyErr_SetObject(PyObject *, PyObject *) {
}
PyObject *PyErr_Format(PyObject *, const char *, ...) {
return nullptr;
}
void Py_DecRef(PyObject *) {
}
int PyArg_ParseTuple(PyObject *, const char *, ...) {
return 0;
}
int PyArg_VaParse(PyObject *, const char *, va_list) {
return 0;
}
PyObject *PyObject_CallMethod(PyObject *, char *, char *, ...) {
return &none_object;
}
PyObject *PyObject_GetAttrString(PyObject *, const char *) {
return &none_object;
}
int PyObject_SetAttrString(PyObject *, const char *, PyObject *) {
return 0;
}
int PyObject_IsTrue(PyObject *) {
return 0;
}
PyObject *PyLong_FromLong(long) {
return &none_object;
}
long PyLong_AsLong(PyObject *) {
return 0;
}
double PyFloat_AsDouble(PyObject *) {
return 0.0;
}
PyObject *PyTuple_New(Py_ssize_t) {
return &none_object;
}
PyObject *PyTuple_GetItem(PyObject *, Py_ssize_t) {
return &none_object;
}
Py_ssize_t PyTuple_Size(PyObject *) {
return 0;
}
int PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *) {
return 0;
}
PyObject *PyList_New(Py_ssize_t) {
return &none_object;
}
PyObject *PyList_GetItem(PyObject *, Py_ssize_t) {
return &none_object;
}
Py_ssize_t PyList_Size(PyObject *) {
return 0;
}
int PyList_SetItem(PyObject *, Py_ssize_t, PyObject *) {
return 0;
}
PyObject *PySequence_GetItem(PyObject *, Py_ssize_t) {
return &none_object;
}
Py_ssize_t PySequence_Length(PyObject *) {
return 0;
}
PyObject *Py_BuildValue(const char *, ...) {
return &none_object;
}
PyObject *PyModule_Create(PyModuleDef *) {
return &none_object;
}
int PyModule_AddObject(PyObject *, const char *, PyObject *) {
return 0;
}
int PyType_Ready(PyTypeObject *) {
return 0;
}
PyObject *PyType_GenericNew(PyTypeObject *, PyObject *, PyObject *) {
return &none_object;
}
void *PyObject_NewShim(std::size_t size, PyTypeObject *type) {
auto *object = static_cast<PyObject *>(std::calloc(1, size));
if (object) {
object->ob_type = type;
}
return object;
}
}

View File

@@ -1,5 +1,8 @@
#include "pythonplugin/python_plugin.hh"
#include <cstdio>
#include <cstdlib>
__attribute__((weak)) std::string handle_pyerror() {
return "python disabled in wasm-safe probe";
}
@@ -13,7 +16,30 @@ PythonPlugin *PythonPlugin::instantiate(struct _inittab *) {
return python_plugin;
}
int PythonPlugin::configure(const char *, const char *) {
int PythonPlugin::configure(const char *iniFilename, const char *section) {
if (!section) {
error_msg = "no section";
status = PLUGIN_NO_SECTION;
return status;
}
if (!iniFilename) {
iniFilename = std::getenv("INI_FILE_NAME");
if (!iniFilename) {
error_msg = "no inifile";
status = PLUGIN_NO_INIFILE;
return status;
}
}
FILE *file = std::fopen(iniFilename, "r");
if (!file) {
error_msg = "bad inifile";
status = PLUGIN_BAD_INIFILE;
return status;
}
std::fclose(file);
status = PLUGIN_OK;
return status;
}
@@ -23,12 +49,17 @@ bool PythonPlugin::is_callable(const char *, const char *) {
}
int PythonPlugin::call(const char *,
const char *,
const char *callable,
boost::python::object,
boost::python::object,
boost::python::object &retval) {
if (!callable) {
return PLUGIN_NO_CALLABLE;
}
retval = boost::python::object();
status = PLUGIN_NO_CALLABLE;
exception_msg = handle_pyerror();
status = PLUGIN_EXCEPTION;
return status;
}

View File

@@ -8,10 +8,34 @@ int main() {
if (!plugin->usable()) {
return 2;
}
if (plugin->configure(nullptr, nullptr) != PLUGIN_NO_SECTION) {
return 6;
}
if (plugin->configure("/tmp/cnc_sim_missing_python_plugin_probe.ini", "PYTHON") != PLUGIN_BAD_INIFILE) {
return 7;
}
boost::python::object retval;
if (plugin->run_string("noop", retval, false) != PLUGIN_OK) {
return 3;
}
if (plugin->call(nullptr, nullptr, boost::python::object(), boost::python::object(), retval) != PLUGIN_NO_CALLABLE) {
return 8;
}
if (plugin->plugin_status() != PLUGIN_OK) {
return 9;
}
if (plugin->call(nullptr, "noop", boost::python::object(), boost::python::object(), retval) != PLUGIN_EXCEPTION) {
return 10;
}
if (plugin->plugin_status() != PLUGIN_EXCEPTION) {
return 11;
}
if (plugin->last_exception().empty()) {
return 12;
}
if (plugin->run_string("noop", retval, false) != PLUGIN_OK) {
return 13;
}
if (plugin->is_callable(nullptr, "noop")) {
return 4;
}
@@ -20,4 +44,3 @@ int main() {
}
return 0;
}

View File

@@ -0,0 +1,7 @@
#pragma once
#include "boost/python/object.hpp"
#define T_INT 1
#define T_DOUBLE 2
#define READONLY 1

View File

@@ -19,6 +19,7 @@ extern "C" {
toolidx_t tooldata_put(CANON_TOOL_TABLE tdata, int idx) {
if (!mmap_created) {
std::fprintf(stderr, "%5d tooldata_put() no tool_mmap_base\n", getpid());
return IDX_FAIL;
}
if (idx < 0 || idx >= CANON_POCKETS_MAX) {
@@ -110,7 +111,11 @@ int tool_mmap_creator(EMC_TOOL_STAT const *ptr, int random_toolchanger) {
}
int tool_mmap_user(void) {
return mmap_created ? 0 : -1;
if (!mmap_created) {
std::fprintf(stderr, "tool_mmap_user(): tool mmap not available\n");
return -1;
}
return 0;
}
void tool_mmap_close(void) {