From 6638edcf452bb76086b8588847063328f562da1d Mon Sep 17 00:00:00 2001 From: Lowri Jenkins Date: Mon, 8 Sep 2025 10:59:33 +0100 Subject: [PATCH 1/6] Add initial defaults loading method --- icpconfigApp/src/icpconfig.cpp | 35 ++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/icpconfigApp/src/icpconfig.cpp b/icpconfigApp/src/icpconfig.cpp index c11e46a..55dfcbc 100644 --- a/icpconfigApp/src/icpconfig.cpp +++ b/icpconfigApp/src/icpconfig.cpp @@ -575,23 +575,35 @@ static int loadIOCs(MAC_HANDLE *h, const std::string& config_name, const std::st std::cerr << "icpconfigLoad: Error in \"" << xfile << "\" " << result.description() << " at offset " << result.offset << std::endl; return -1; } + pugi::xpath_variable_set vars; vars.add("iocname", pugi::xpath_type_string); vars.add("iocgroup", pugi::xpath_type_string); vars.set("iocname",ioc_name.c_str()); vars.set("iocgroup",ioc_group.c_str()); // default macros - if (!quiet) + + pugi::xml_document confXMLDoc; + std::string confXML = std::string(macEnvExpand("$(TOP)")) +"/iocBoot/" + std::string(macEnvExpand("$(IOC)")) +"/config.xml"; + result = confXMLDoc.load_file(confXML.c_str()); + if (!result) + { + std::cerr << "icpconfigLoad: Error in \"" << confXML << "\" " << result.description() << " at offset " << result.offset << std::endl; + return -1; + } + pugi::xpath_node_set default_macros = confXMLDoc.select_nodes("/ioc_config/config_part/macros/macro"); + default_macros.sort(); // forward document order + if (!quiet) { - printf("icpconfigLoad: Loading default macros for \"%s\"\n", config_name.c_str()); + printf("icpconfigLoad: checking %d macro(s) for default values in %s\n", (int)default_macros.size(), confXML.c_str()); } - pugi::xpath_node_set default_macros = doc.select_nodes("/iocs/defaults/macros/macro"); - default_macros.sort(); // forward document order for (pugi::xpath_node_set::const_iterator it = default_macros.begin(); it != default_macros.end(); ++it) { - std::string name = it->node().attribute("name").value(); - std::string value = it->node().attribute("value").value(); - setValue(h, name.c_str(), value.c_str(), config_name.c_str()); + if (it->node().attribute("hasDefault").as_bool()) { + std::string name = it->node().attribute("name").value(); + std::string value = it->node().attribute("defaultValue").value(); + setValue(h, name.c_str(), value.c_str(), config_name.c_str()); + } } // ioc sim level if (!quiet) @@ -645,7 +657,14 @@ static int loadIOCs(MAC_HANDLE *h, const std::string& config_name, const std::st { std::string name = it->node().attribute("name").value(); std::string value = it->node().attribute("value").value(); - setValue(h, name.c_str(), value.c_str(), config_name.c_str()); + MacroItem& item = macro_map[name]; + if (item.defined) { + if(value!=""){ + setValue(h, name.c_str(), value.c_str(), config_name.c_str()); + } + }else{ + setValue(h, name.c_str(), value.c_str(), config_name.c_str()); + } } // ioc pvs if (!quiet) From 4eac8eff4c7127af92be10874644bcc1e77c81a3 Mon Sep 17 00:00:00 2001 From: Lowri Jenkins Date: Mon, 8 Sep 2025 11:23:22 +0100 Subject: [PATCH 2/6] Pull out loadDefaultMacros Function --- icpconfigApp/src/icpconfig.cpp | 49 +++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/icpconfigApp/src/icpconfig.cpp b/icpconfigApp/src/icpconfig.cpp index 55dfcbc..0a0fd2b 100644 --- a/icpconfigApp/src/icpconfig.cpp +++ b/icpconfigApp/src/icpconfig.cpp @@ -565,27 +565,10 @@ epicsShareExtern void icpconfigGetMacros(const std::string& iocName, const std:: } } -static int loadIOCs(MAC_HANDLE *h, const std::string& config_name, const std::string& config_root, const std::string& ioc_name, const std::string& ioc_group, bool warn_if_not_found, bool filter, bool verbose) -{ - pugi::xml_document doc; - std::string xfile = config_root + config_name + "/iocs.xml"; - pugi::xml_parse_result result = doc.load_file(xfile.c_str()); - if (!result) - { - std::cerr << "icpconfigLoad: Error in \"" << xfile << "\" " << result.description() << " at offset " << result.offset << std::endl; - return -1; - } - - pugi::xpath_variable_set vars; - vars.add("iocname", pugi::xpath_type_string); - vars.add("iocgroup", pugi::xpath_type_string); - vars.set("iocname",ioc_name.c_str()); - vars.set("iocgroup",ioc_group.c_str()); - // default macros - - pugi::xml_document confXMLDoc; +static int loadDefaultMacros(MAC_HANDLE *h, const std::string& config_name){ + pugi::xml_document confXMLDoc; std::string confXML = std::string(macEnvExpand("$(TOP)")) +"/iocBoot/" + std::string(macEnvExpand("$(IOC)")) +"/config.xml"; - result = confXMLDoc.load_file(confXML.c_str()); + pugi::xml_parse_result result = confXMLDoc.load_file(confXML.c_str()); if (!result) { std::cerr << "icpconfigLoad: Error in \"" << confXML << "\" " << result.description() << " at offset " << result.offset << std::endl; @@ -595,7 +578,7 @@ static int loadIOCs(MAC_HANDLE *h, const std::string& config_name, const std::st default_macros.sort(); // forward document order if (!quiet) { - printf("icpconfigLoad: checking %d macro(s) for default values in %s\n", (int)default_macros.size(), confXML.c_str()); + printf("icpconfigLoad: Checking %d macro(s) for default values in %s\n", (int)default_macros.size(), confXML.c_str()); } for (pugi::xpath_node_set::const_iterator it = default_macros.begin(); it != default_macros.end(); ++it) { @@ -605,6 +588,30 @@ static int loadIOCs(MAC_HANDLE *h, const std::string& config_name, const std::st setValue(h, name.c_str(), value.c_str(), config_name.c_str()); } } + return 0; +} + +static int loadIOCs(MAC_HANDLE *h, const std::string& config_name, const std::string& config_root, const std::string& ioc_name, const std::string& ioc_group, bool warn_if_not_found, bool filter, bool verbose) +{ + pugi::xml_document doc; + std::string xfile = config_root + config_name + "/iocs.xml"; + pugi::xml_parse_result result = doc.load_file(xfile.c_str()); + if (!result) + { + std::cerr << "icpconfigLoad: Error in \"" << xfile << "\" " << result.description() << " at offset " << result.offset << std::endl; + return -1; + } + + pugi::xpath_variable_set vars; + vars.add("iocname", pugi::xpath_type_string); + vars.add("iocgroup", pugi::xpath_type_string); + vars.set("iocname",ioc_name.c_str()); + vars.set("iocgroup",ioc_group.c_str()); + // default macros + if (loadDefaultMacros(h, config_name)) { + return -1; + } + // ioc sim level if (!quiet) { From 5eab56f90b849ed98cb0479ca3367ec85c533779 Mon Sep 17 00:00:00 2001 From: Lowri Jenkins Date: Fri, 12 Sep 2025 14:29:55 +0100 Subject: [PATCH 3/6] update filepaths --- icpconfigApp/src/icpconfig.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/icpconfigApp/src/icpconfig.cpp b/icpconfigApp/src/icpconfig.cpp index 0a0fd2b..a00355e 100644 --- a/icpconfigApp/src/icpconfig.cpp +++ b/icpconfigApp/src/icpconfig.cpp @@ -567,7 +567,8 @@ epicsShareExtern void icpconfigGetMacros(const std::string& iocName, const std:: static int loadDefaultMacros(MAC_HANDLE *h, const std::string& config_name){ pugi::xml_document confXMLDoc; - std::string confXML = std::string(macEnvExpand("$(TOP)")) +"/iocBoot/" + std::string(macEnvExpand("$(IOC)")) +"/config.xml"; + std::string configXMLDir = std::string(macEnvExpand("$(IOC)")) +"/config.xml"; + std::string confXML = std::string(macEnvExpand("$(TOP)")) +"/iocBoot/" + configXMLDir; pugi::xml_parse_result result = confXMLDoc.load_file(confXML.c_str()); if (!result) { @@ -585,7 +586,7 @@ static int loadDefaultMacros(MAC_HANDLE *h, const std::string& config_name){ if (it->node().attribute("hasDefault").as_bool()) { std::string name = it->node().attribute("name").value(); std::string value = it->node().attribute("defaultValue").value(); - setValue(h, name.c_str(), value.c_str(), config_name.c_str()); + setValue(h, name.c_str(), value.c_str(), configXMLDir.c_str()); } } return 0; From a697d44ce06990f3c98383971add02a40d919c14 Mon Sep 17 00:00:00 2001 From: Lowri Jenkins Date: Tue, 16 Sep 2025 15:09:36 +0100 Subject: [PATCH 4/6] Remove checking for empty set's as macro's using defaults are no longer pushed to the config by the blockserver --- icpconfigApp/src/icpconfig.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/icpconfigApp/src/icpconfig.cpp b/icpconfigApp/src/icpconfig.cpp index a00355e..0fd7fcc 100644 --- a/icpconfigApp/src/icpconfig.cpp +++ b/icpconfigApp/src/icpconfig.cpp @@ -666,13 +666,7 @@ static int loadIOCs(MAC_HANDLE *h, const std::string& config_name, const std::st std::string name = it->node().attribute("name").value(); std::string value = it->node().attribute("value").value(); MacroItem& item = macro_map[name]; - if (item.defined) { - if(value!=""){ - setValue(h, name.c_str(), value.c_str(), config_name.c_str()); - } - }else{ - setValue(h, name.c_str(), value.c_str(), config_name.c_str()); - } + setValue(h, name.c_str(), value.c_str(), config_name.c_str()); } // ioc pvs if (!quiet) From 16f02e9144970bc1d8f7b83a8f19b1ea89eb0ff2 Mon Sep 17 00:00:00 2001 From: Lowri Jenkins Date: Thu, 18 Sep 2025 10:09:24 +0100 Subject: [PATCH 5/6] Missed removign line from previous commit --- icpconfigApp/src/icpconfig.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/icpconfigApp/src/icpconfig.cpp b/icpconfigApp/src/icpconfig.cpp index 0fd7fcc..d1f495f 100644 --- a/icpconfigApp/src/icpconfig.cpp +++ b/icpconfigApp/src/icpconfig.cpp @@ -665,7 +665,6 @@ static int loadIOCs(MAC_HANDLE *h, const std::string& config_name, const std::st { std::string name = it->node().attribute("name").value(); std::string value = it->node().attribute("value").value(); - MacroItem& item = macro_map[name]; setValue(h, name.c_str(), value.c_str(), config_name.c_str()); } // ioc pvs From ef2181d632e2f8d549029b74c818cf7f34aecd39 Mon Sep 17 00:00:00 2001 From: Lowri Jenkins Date: Wed, 25 Mar 2026 11:27:03 +0000 Subject: [PATCH 6/6] Fix defaults overwriding set value --- icpconfigApp/src/icpconfig.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/icpconfigApp/src/icpconfig.cpp b/icpconfigApp/src/icpconfig.cpp index d1f495f..fa986ff 100644 --- a/icpconfigApp/src/icpconfig.cpp +++ b/icpconfigApp/src/icpconfig.cpp @@ -108,6 +108,7 @@ struct PVSetItem }; static std::map pvset_map; +static bool defaultsSet = false; struct MacroItem { @@ -589,6 +590,7 @@ static int loadDefaultMacros(MAC_HANDLE *h, const std::string& config_name){ setValue(h, name.c_str(), value.c_str(), configXMLDir.c_str()); } } + defaultsSet = true; return 0; } @@ -608,9 +610,11 @@ static int loadIOCs(MAC_HANDLE *h, const std::string& config_name, const std::st vars.add("iocgroup", pugi::xpath_type_string); vars.set("iocname",ioc_name.c_str()); vars.set("iocgroup",ioc_group.c_str()); - // default macros - if (loadDefaultMacros(h, config_name)) { - return -1; + // default macros but only if they aren't already loaded, this prevents overwrites + if(!defaultsSet){ + if (loadDefaultMacros(h, config_name)) { + return -1; + } } // ioc sim level