--- /dev/null
+New: Parameter entries in the ParameterHandler class can now be marked as
+deprecated using the function 'mark_as_deprecated'. If deprecated parameters
+are found in a parameter file an exception of type
+'ExcEncounteredDeprecatedEntries' is thrown that can be caught in
+the calling code, or if ignored will emit an error message.
+<br>
+(Rene Gassmoeller, 2024/08/11)
const std::string &documentation = "",
const bool has_to_be_set = false);
+ /**
+ * Mark a previously declared parameter as deprecated. This will cause an
+ * exception of type ExcEncounteredDeprecatedEntries to be thrown if
+ * the parameter is used in the input file.
+ *
+ * The exception message will list the name of the parameter.
+ *
+ * @param entry The name of the parameter to mark as deprecated.
+ * @param deprecation_status An optional parameter that can be used to
+ * toggle the deprecation status of the parameter. If set to true, the
+ * parameter will be marked as deprecated. This is the default behavior.
+ * If set to false, the parameter will be marked as not deprecated.
+ * This is useful if a parameter is marked as deprecated by
+ * one function, but another function wants to keep using it.
+ */
+ void
+ mark_as_deprecated(const std::string &entry,
+ const bool deprecation_status = true);
+
/**
* Attach an action to the parameter with name @p entry in the current
* section. The action needs to be a function-like object that takes the
DeclException1(ExcEntryAlreadyExists,
std::string,
<< "The following entry already exists: " << arg1 << '.');
+
+ /**
+ * Exception
+ */
+ DeclException3(ExcEntryIsDeprecated,
+ int,
+ std::string,
+ std::string,
+ << "Line <" << arg1 << "> of file <" << arg2 << ">: "
+ << "Entry <" << arg3 << "> is deprecated.");
+
+ /**
+ * Exception
+ */
+ DeclException1(ExcEncounteredDeprecatedEntries,
+ std::string,
+ << "The following deprecated entries were encountered:\n\n"
+ << arg1);
+
/**
* Exception
*/
ExcAlreadyAtTopLevel,
"You can't leave a subsection if you are already at the top level "
"of the subsection hierarchy.");
+
/**
* Exception
*/
unsigned int current_line_n = 0;
unsigned int current_logical_line_n = 0;
+ // Keep a list of deprecation messages if we encounter deprecated entries.
+ std::string deprecation_messages;
+
// define an action that tries to scan a line.
//
// if that fails, i.e., if scan_line throws
// unknown state.
//
// after unwinding the subsection stack, just re-throw the exception
- auto scan_line_or_cleanup = [this,
- &skip_undefined,
- &saved_path](const std::string &line,
- const std::string &filename,
- const unsigned int line_number) {
- try
- {
- scan_line(line, filename, line_number, skip_undefined);
- }
- catch (...)
- {
- while ((saved_path != subsection_path) && (subsection_path.size() > 0))
- leave_subsection();
+ auto scan_line_or_cleanup =
+ [this,
+ &skip_undefined,
+ &saved_path,
+ &deprecation_messages](const std::string &line,
+ const std::string &filename,
+ const unsigned int line_number) {
+ try
+ {
+ scan_line(line, filename, line_number, skip_undefined);
+ }
+ catch (ExcEntryIsDeprecated &e)
+ {
+ deprecation_messages += e.what();
+ }
+ catch (...)
+ {
+ while ((saved_path != subsection_path) &&
+ (subsection_path.size() > 0))
+ leave_subsection();
- throw;
- }
- };
+ throw;
+ }
+ };
while (std::getline(input, input_line))
AssertThrow(false,
ExcUnbalancedSubsections(filename, paths_message.str()));
}
+
+ // if we encountered deprecated entries, throw an exception
+ // that contains all the deprecation messages
+ AssertThrow(deprecation_messages.empty(),
+ ExcEncounteredDeprecatedEntries(deprecation_messages));
}
entries->put(get_current_full_path(alias_name) + path_separator + "alias",
existing_entry_name);
- entries->put(get_current_full_path(alias_name) + path_separator +
+
+ if (alias_is_deprecated)
+ mark_as_deprecated(alias_name);
+ else
+ mark_as_deprecated(alias_name, false);
+}
+
+
+
+void
+ParameterHandler::mark_as_deprecated(const std::string &existing_entry_name,
+ const bool deprecation_status)
+{
+ // assert that the entry exists
+ Assert(entries->get_optional<std::string>(
+ get_current_full_path(existing_entry_name)),
+ ExcMessage("You are trying to mark the entry <" + existing_entry_name +
+ "> as deprecated, but the entry does not exist."));
+
+ // then also make sure that what is being referred to is in
+ // fact a parameter or alias (not a subsection)
+ Assert(
+ entries->get_optional<std::string>(
+ get_current_full_path(existing_entry_name) + path_separator + "value") ||
+ entries->get_optional<std::string>(
+ get_current_full_path(existing_entry_name) + path_separator + "alias"),
+ ExcMessage("You are trying to mark the entry <" + existing_entry_name +
+ "> as deprecated, but the entry does not seem to be a "
+ "parameter declaration or a parameter alias."));
+
+ entries->put(get_current_full_path(existing_entry_name) + path_separator +
"deprecation_status",
- (alias_is_deprecated ? "true" : "false"));
+ deprecation_status ? "true" : "false");
}
if (!is_short &&
!p.second.get<std::string>("documentation").empty())
out << "{\\it Description:} "
- << p.second.get<std::string>("documentation") << "\n\n"
+ << p.second.get<std::string>("documentation")
+ << ((p.second.get_optional<std::string>(
+ "deprecation_status") &&
+ p.second.get<std::string>("deprecation_status") ==
+ "true") ?
+ " This parameter is deprecated.\n\n" :
+ "\n\n")
<< '\n';
if (!is_short)
{
// finally write the new value into the database
entries->put(path + path_separator + "value", entry_value);
+ // record that the entry has been set manually
auto map_iter = entries_set_status.find(path);
if (map_iter != entries_set_status.end())
map_iter->second =
AssertThrow(false,
ExcMessage("Could not find parameter " + path +
" in map entries_set_status."));
+
+ // Check if the entry (or the resolved alias) is deprecated,
+ // throw an exception if it is
+ if (entries->get_optional<std::string>(path + path_separator +
+ "deprecation_status") &&
+ entries->get<std::string>(path + path_separator +
+ "deprecation_status") == "true")
+ {
+ AssertThrow(false,
+ ExcEntryIsDeprecated(current_line_n,
+ input_filename,
+ entry_name));
+ }
}
else
{
--- /dev/null
+// ------------------------------------------------------------------------
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright (C) 2003 - 2023 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// Part of the source code is dual licensed under Apache-2.0 WITH
+// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
+// governing the source code and code contributions can be found in
+// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
+//
+// ------------------------------------------------------------------------
+
+
+
+// test the output generated by
+// ParameterHandler::print_parameters(LaTeX). like the _4a test, but
+// deprecates the parameters.
+
+#include <deal.II/base/parameter_handler.h>
+
+#include "../tests.h"
+
+// header for chdir is platform dependent; when the day comes that we support
+// Windows in the test suite then conditionally include direction.h
+#include <unistd.h>
+
+int
+main()
+{
+ initlog();
+
+ // We need a local path for the file to get consistent output messages.
+ const int chdir_return_code = chdir(SOURCE_DIR);
+ AssertThrow(chdir_return_code == 0, ExcInternalError());
+
+ ParameterHandler prm;
+
+ try
+ {
+ prm.enter_subsection("Testing");
+ {
+ prm.enter_subsection("Testing 2");
+ {
+ prm.declare_entry("string list 2",
+ "a",
+ Patterns::List(
+ Patterns::Selection("a|b|c|d|e|f|g|h")),
+ "docs 1");
+ prm.declare_entry("int 2", "1", Patterns::Integer());
+ prm.declare_entry("double 2",
+ "3.1415926",
+ Patterns::Double(),
+ "docs 3");
+ prm.mark_as_deprecated("string list 2");
+ prm.mark_as_deprecated("int 2");
+ prm.mark_as_deprecated("double 2");
+ }
+ prm.leave_subsection();
+
+ prm.declare_entry("string list",
+ "a",
+ Patterns::List(
+ Patterns::Selection("a|b|c|d|e|f|g|h")),
+ "docs 1");
+ prm.declare_entry("int", "1", Patterns::Integer());
+ prm.declare_entry("double", "3.1415926", Patterns::Double(), "docs 3");
+ prm.mark_as_deprecated("string list");
+ prm.mark_as_deprecated("int");
+ prm.mark_as_deprecated("double");
+ }
+ prm.leave_subsection();
+
+ // read and then write
+ // parameters. take same input file
+ // as for parameter_handler_3, but
+ // use different output format
+ prm.parse_input("prm/parameter_handler_3.prm");
+ prm.print_parameters(std::cout, ParameterHandler::LaTeX);
+ }
+ catch (const ParameterHandler::ExcEncounteredDeprecatedEntries &exc)
+ {
+ deallog << exc.get_exc_name() << std::endl;
+ exc.print_info(deallog.get_file_stream());
+
+ // Check that the deprecated entries are still accessible.
+ prm.enter_subsection("Testing");
+ {
+ deallog << prm.get("string list") << std::endl;
+ deallog << prm.get("int") << std::endl;
+ }
+ prm.leave_subsection();
+ }
+ catch (...)
+ {
+ deallog << std::endl
+ << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ deallog << "Unknown exception!" << std::endl
+ << "Aborting!" << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ return 1;
+ };
+
+ return 0;
+}
--- /dev/null
+
+DEAL::ExcEncounteredDeprecatedEntries(deprecation_messages)
+ The following deprecated entries were encountered:
+
+
+--------------------------------------------------------
+An error occurred in file <parameter_handler.cc> in function
+ void dealii::ParameterHandler::scan_line(std::string, const string&, unsigned int, bool)
+Additional information:
+ Line <2> of file <prm/parameter_handler_3.prm>: Entry <string list> is
+ deprecated.
+--------------------------------------------------------
+
+--------------------------------------------------------
+An error occurred in file <parameter_handler.cc> in function
+ void dealii::ParameterHandler::scan_line(std::string, const string&, unsigned int, bool)
+Additional information:
+ Line <3> of file <prm/parameter_handler_3.prm>: Entry <int> is
+ deprecated.
+--------------------------------------------------------
+
+DEAL::a, b, c
+DEAL::3