diff --git a/check-linuxcnc-wasm-shims-source-map.sh b/check-linuxcnc-wasm-shims-source-map.sh index 480c3a1..23057f6 100755 --- a/check-linuxcnc-wasm-shims-source-map.sh +++ b/check-linuxcnc-wasm-shims-source-map.sh @@ -119,6 +119,8 @@ grep -F 'status = PLUGIN_EXCEPTION_DURING_PATH_APPEND;' \ grep -F 'int IniFile::tildeExpand(const std::string &path, std::string &result)' \ "$linuxcnc_root/src/emc/ini/inifile.cc" >/dev/null grep -F "if(!home)" "$linuxcnc_root/src/emc/ini/inifile.cc" >/dev/null +grep -F 'IniFile::trim(sect);' "$linuxcnc_root/src/emc/ini/inifile.cc" >/dev/null +grep -F 'Section header has trailing content, ignored' "$linuxcnc_root/src/emc/ini/inifile.cc" >/dev/null grep -F 'retval = bp::exec_file(cmd, main_namespace, main_namespace);' \ "$linuxcnc_root/src/emc/pythonplugin/python_plugin.cc" >/dev/null grep -F 'retval = bp::exec(cmd, main_namespace, main_namespace);' \ @@ -347,6 +349,8 @@ for needle in [ "status = PLUGIN_BAD_PATH;", "status = PLUGIN_INITTAB_FAILED;", "failed to initialize built-in module", + "read_ini_section(text, section_name)", + "section_name = trim_ini_value(text.substr(1, close - 1));", 'check_python_path_entries(iniFilename,', "PLUGIN_EXCEPTION_DURING_PATH_PREPEND", "PLUGIN_EXCEPTION_DURING_PATH_APPEND", @@ -369,6 +373,7 @@ for needle in [ if needle not in python_plugin_inittab_probe: raise SystemExit(f"PythonPlugin inittab probe missing first-caller status assertion: {needle}") for needle in [ + "[ PYTHON ] ; section comment", "PLUGIN_NO_SECTION", "PLUGIN_BAD_INIFILE", "PLUGIN_BAD_PATH", @@ -457,6 +462,7 @@ for phrase in [ "first-caller `_inittab` `PLUGIN_INITTAB_FAILED` edge", "preserve the `TOPLEVEL` missing-path `PLUGIN_BAD_PATH` edge", "preserve `PATH_PREPEND` and `PATH_APPEND` tilde-expansion failure statuses", + "preserve LinuxCNC INI section-name trimming and trailing section-comment handling", "LinuxCNC `rcs_print_error` split entry points", "without native print routing", "LinuxCNC userspace `rtapi_snprintf()` formatting", diff --git a/core/wasm_shims/pythonplugin/python_plugin.cc b/core/wasm_shims/pythonplugin/python_plugin.cc index 857d437..6d294fb 100644 --- a/core/wasm_shims/pythonplugin/python_plugin.cc +++ b/core/wasm_shims/pythonplugin/python_plugin.cc @@ -32,6 +32,21 @@ std::string trim_ini_value(std::string value) { return std::string(first, last); } +bool read_ini_section(const std::string &text, std::string §ion_name) { + if (text.empty() || text.front() != '[') { + return false; + } + const auto close = text.find(']'); + if (close == std::string::npos) { + return false; + } + + // LinuxCNC source basis: IniFile::processLine() trims the section name + // between '[' and ']' and ignores text after the closing bracket. + section_name = trim_ini_value(text.substr(1, close - 1)); + return true; +} + std::vector find_ini_values(const char *iniFilename, const char *section, const char *key) { @@ -48,8 +63,9 @@ std::vector find_ini_values(const char *iniFilename, if (text.empty() || text[0] == ';' || text[0] == '#') { continue; } - if (text.front() == '[' && text.back() == ']') { - in_section = text.substr(1, text.size() - 2) == section; + std::string section_name; + if (read_ini_section(text, section_name)) { + in_section = section_name == section; continue; } if (!in_section) { diff --git a/core/wasm_shims/pythonplugin/python_plugin_probe_main.cc b/core/wasm_shims/pythonplugin/python_plugin_probe_main.cc index 520547a..34ea018 100644 --- a/core/wasm_shims/pythonplugin/python_plugin_probe_main.cc +++ b/core/wasm_shims/pythonplugin/python_plugin_probe_main.cc @@ -128,6 +128,37 @@ int main() { setenv("HOME", saved_home_value.c_str(), 1); } std::remove(path_prepend_ini); + const char *spaced_section_ini = "/tmp/cnc_sim_python_plugin_probe_spaced_section.ini"; + { + FILE *file = std::fopen(spaced_section_ini, "w"); + if (!file) { + std::remove(ini); + return 47; + } + std::fputs("[ PYTHON ] ; section comment\nPATH_PREPEND = ~/linuxcnc-python\n", file); + std::fclose(file); + } + unsetenv("HOME"); + if (plugin->configure(spaced_section_ini, "PYTHON") != PLUGIN_EXCEPTION_DURING_PATH_PREPEND) { + if (saved_home) { + setenv("HOME", saved_home_value.c_str(), 1); + } + std::remove(ini); + std::remove(spaced_section_ini); + return 48; + } + if (plugin->last_errmsg() != "bad path prepend") { + if (saved_home) { + setenv("HOME", saved_home_value.c_str(), 1); + } + std::remove(ini); + std::remove(spaced_section_ini); + return 49; + } + if (saved_home) { + setenv("HOME", saved_home_value.c_str(), 1); + } + std::remove(spaced_section_ini); const char *path_append_ini = "/tmp/cnc_sim_python_plugin_probe_path_append.ini"; { FILE *file = std::fopen(path_append_ini, "w"); diff --git a/docs/linuxcnc-wasm-shims-source-map.md b/docs/linuxcnc-wasm-shims-source-map.md index 41abbd6..0390bee 100644 --- a/docs/linuxcnc-wasm-shims-source-map.md +++ b/docs/linuxcnc-wasm-shims-source-map.md @@ -67,6 +67,7 @@ only; it must not add CNC behavior and must not expand the temporary smoke parse - The PythonPlugin shim must preserve the first-caller `_inittab` `PLUGIN_INITTAB_FAILED` edge from `src/emc/pythonplugin/python_plugin.cc` when a built-in module init function fails, while keeping browser-safe probes detached from real Python module execution. - The PythonPlugin shim must preserve the `TOPLEVEL` missing-path `PLUGIN_BAD_PATH` edge from `src/emc/pythonplugin/python_plugin.cc` before reporting the browser-safe disabled Python runtime status. - The PythonPlugin shim must preserve `PATH_PREPEND` and `PATH_APPEND` tilde-expansion failure statuses from `src/emc/pythonplugin/python_plugin.cc` and `src/emc/ini/inifile.cc` without executing Python path mutation in browser-safe probes. +- The PythonPlugin shim must preserve LinuxCNC INI section-name trimming and trailing section-comment handling from `src/emc/ini/inifile.cc` for Python/remap configuration keys. - The PythonPlugin shim must not execute `bp::exec`, `bp::exec_file`, or real Python callable dispatch; `PyObject_Call` is an inert C API symbol only. Browser Python execution remains blocked until implemented as a source-backed