From 7f06006a34267c9d713f62da9f54cd20a25079b4 Mon Sep 17 00:00:00 2001 From: Lars Bilke <lars.bilke@ufz.de> Date: Fri, 28 Jan 2022 20:12:15 +0100 Subject: [PATCH] [prj] Use xmlStrEqual instead of reinterpret_cast comparison. --- BaseLib/ConfigTreeUtil.cpp | 1 - BaseLib/ConfigTreeUtil.h | 2 +- BaseLib/PrjProcessing.cpp | 59 ++++++++++----------- BaseLib/PrjProcessing.h | 10 ++-- ProcessLib/SteadyStateDiffusion/Tests.cmake | 2 +- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/BaseLib/ConfigTreeUtil.cpp b/BaseLib/ConfigTreeUtil.cpp index 13bae333c9c..786692aff08 100644 --- a/BaseLib/ConfigTreeUtil.cpp +++ b/BaseLib/ConfigTreeUtil.cpp @@ -60,7 +60,6 @@ ConfigTree makeConfigTreeFromFile(const std::string& filepath, { std::stringstream buffer; buffer << file.rdbuf(); - file.close(); return makeConfigTree(filepath, be_ruthless, toplevel_tag, buffer); } diff --git a/BaseLib/ConfigTreeUtil.h b/BaseLib/ConfigTreeUtil.h index 677847607f7..1026272d222 100644 --- a/BaseLib/ConfigTreeUtil.h +++ b/BaseLib/ConfigTreeUtil.h @@ -20,7 +20,7 @@ namespace BaseLib * \param be_ruthless see ConfigTreeTopLevel::ConfigTreeTopLevel() * \param toplevel_tag name of the outermost tag in the XML file. The returned * ConfigTree is rooted one level below that tag. - * \param patch_files optional vector of strings with patch file paths. + * \param prj_stream content of the (pre-processed) prj file. * * The parameter \c toplevel_tag is provided for compatibility with our existing * configuration files whose toplevel tags are written in camel case, which diff --git a/BaseLib/PrjProcessing.cpp b/BaseLib/PrjProcessing.cpp index 1f2105ddaf8..84702330f45 100644 --- a/BaseLib/PrjProcessing.cpp +++ b/BaseLib/PrjProcessing.cpp @@ -14,30 +14,26 @@ #include <libxml/tree.h> #include <xml_patch.h> +#include <filesystem> +#include <fstream> + #include "Error.h" +#include "FileTools.h" #include "Logging.h" namespace BaseLib { -bool isEqual(const unsigned char* a, std::string const& b) -{ - return std::string{reinterpret_cast<const char*>(a)} == b; -} - void traverseIncludes(xmlDoc* doc, xmlNode* node, std::filesystem::path const& prj_dir) { xmlNode* cur_node = nullptr; for (cur_node = node; cur_node; cur_node = cur_node->next) { - if (cur_node->type != XML_ELEMENT_NODE || - cur_node->type == XML_TEXT_NODE) + if (cur_node->type != XML_ELEMENT_NODE) { continue; } - if (isEqual(cur_node->name, "include")) - // if (!strcmp(reinterpret_cast<const char*>(cur_node->name), - // "include")) + if (xmlStrEqual(cur_node->name, xmlCharStrdup("include"))) { auto include_file_char_pointer = xmlGetProp(cur_node, xmlCharStrdup("file")); @@ -48,8 +44,10 @@ void traverseIncludes(xmlDoc* doc, xmlNode* node, "element '{:s}' on line {:d}: no file attribute given!", cur_node->name, cur_node->line); } + auto filename_length = xmlStrlen(include_file_char_pointer); std::string filename( - reinterpret_cast<char*>(include_file_char_pointer)); + reinterpret_cast<char*>(include_file_char_pointer), + filename_length); if (auto const filepath = std::filesystem::path(filename); filepath.is_relative()) { @@ -157,8 +155,8 @@ void patchStream(std::string const& patch_file, std::stringstream& prj_stream, // Check for after_includes-attribute xmlChar* value = xmlNodeListGetString(node->doc, attribute->children, 1); - if (isEqual(attribute->name, "after_includes") && - isEqual(value, "true")) + if (xmlStrEqual(attribute->name, xmlCharStrdup("after_includes")) && + xmlStrEqual(value, xmlCharStrdup("true"))) { node_after_includes = true; } @@ -172,15 +170,15 @@ void patchStream(std::string const& patch_file, std::stringstream& prj_stream, continue; } - if (isEqual(node->name, "add")) + if (xmlStrEqual(node->name, xmlCharStrdup("add"))) { rc = xml_patch_add(doc, node); } - else if (isEqual(node->name, "replace")) + else if (xmlStrEqual(node->name, xmlCharStrdup("replace"))) { rc = xml_patch_replace(doc, node); } - else if (isEqual(node->name, "remove")) + else if (xmlStrEqual(node->name, xmlCharStrdup("remove"))) { rc = xml_patch_remove(doc, node); } @@ -261,12 +259,9 @@ void readAndPatchPrj(std::stringstream& prj_stream, std::string& prj_file, } // apply xml patches to stream - if (!patch_files.empty()) + for (const auto& patch_file : patch_files) { - for (const auto& patch_file : patch_files) - { - patchStream(patch_file, prj_stream); - } + patchStream(patch_file, prj_stream); } } @@ -279,15 +274,17 @@ void prepareProjectFile(std::stringstream& prj_stream, std::vector<std::string> patch_files_copy = patch_files; readAndPatchPrj(prj_stream, prj_file, patch_files_copy); - replaceIncludes(prj_stream, std::filesystem::path(prj_file).parent_path()); + // LB TODO later: replace canonical with absolute when a mesh input dir + // ogs parameter is implemented. + replaceIncludes(prj_stream, + std::filesystem::canonical(std::filesystem::path(prj_file)) + .parent_path()); // re-apply xml patches to stream - if (!patch_files_copy.empty()) + for (const auto& patch_file : patch_files_copy) { - for (const auto& patch_file : patch_files_copy) - { - patchStream(patch_file, prj_stream, true); - } + patchStream(patch_file, prj_stream, true); } + if (write_prj) { // pretty-print @@ -297,13 +294,15 @@ void prepareProjectFile(std::stringstream& prj_stream, // not work. 2 spaces are default. // // xmlThrDefIndentTreeOutput(1); - // xmlThrDefTreeIndentString(""); + // xmlThrDefTreeIndentString(" "); // 4 spaces indent auto doc = xmlParseMemory(prj_stream.str().c_str(), prj_stream.str().size()); - auto prj_out = std::string(std::filesystem::path(out_directory) / - std::filesystem::path(prj_file).stem()) + + auto prj_out = (std::filesystem::path(out_directory) / + std::filesystem::path(filepath).stem()) + .string() + "_processed.prj"; xmlSaveFormatFileEnc(prj_out.c_str(), doc, "utf-8", 1); + INFO("Processed project file written to {:s}.", prj_out); xmlFreeDoc(doc); } xmlCleanupParser(); diff --git a/BaseLib/PrjProcessing.h b/BaseLib/PrjProcessing.h index 267f81cd834..138ee7d0faa 100644 --- a/BaseLib/PrjProcessing.h +++ b/BaseLib/PrjProcessing.h @@ -16,11 +16,13 @@ namespace BaseLib { /** - * @brief Applies includes and patch files to project file. + * \brief Applies includes and patch files to project file. * - * @param prj_stream The processed prj as a stringstream. - * @param filepath The prj file. - * @param patch_files Optional patch files. + * \param prj_stream The processed prj as a stringstream. + * \param filepath The prj file. + * \param patch_files Optional patch files. + * \param write_prj Write the processed project file to disk? + * \param out_directory The directory to write the processed file to. */ void prepareProjectFile(std::stringstream& prj_stream, const std::string& filepath, diff --git a/ProcessLib/SteadyStateDiffusion/Tests.cmake b/ProcessLib/SteadyStateDiffusion/Tests.cmake index c7c7c6de2f6..3d183ba286f 100644 --- a/ProcessLib/SteadyStateDiffusion/Tests.cmake +++ b/ProcessLib/SteadyStateDiffusion/Tests.cmake @@ -4,7 +4,7 @@ foreach(mesh_size 1e0 1e1 1e2 1e3) NAME SteadyStateDiffusion_cube_1x1x1_${mesh_size} PATH Elliptic/cube_1x1x1_SteadyStateDiffusion EXECUTABLE ogs - EXECUTABLE_ARGS cube_${mesh_size}.xml + EXECUTABLE_ARGS cube_${mesh_size}.xml --write-prj TESTER vtkdiff REQUIREMENTS NOT OGS_USE_MPI DIFF_DATA -- GitLab