aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-05-07 20:40:11 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-05-11 14:58:00 +0100
commit69345817c6645c9696fb60fbf71db242e5fe2548 (patch)
tree7d2e45c566d5bbb83cb1caa387ab0d755a7749e0
parent753d5b7573190d742e64a2ac41531b900018db0f (diff)
downloadpaludis-69345817c6645c9696fb60fbf71db242e5fe2548.tar.gz
paludis-69345817c6645c9696fb60fbf71db242e5fe2548.tar.xz
No RDEPEND=DEPEND in EAPI 3
-rw-r--r--.gitignore1
-rw-r--r--paludis/repositories/e/Makefile.am19
-rw-r--r--paludis/repositories/e/depend_rdepend_TEST.cc230
-rwxr-xr-xpaludis/repositories/e/depend_rdepend_TEST_cleanup.sh10
-rwxr-xr-xpaludis/repositories/e/depend_rdepend_TEST_setup.sh76
-rw-r--r--paludis/repositories/e/eapis/3.conf2
-rw-r--r--paludis/repositories/e/ebuild.cc15
-rwxr-xr-xpaludis/repositories/e/ebuild/ebuild.bash10
-rw-r--r--paludis/repositories/e/pipe_command_handler.cc14
9 files changed, 370 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore
index 03f0dbc..e097f60 100644
--- a/.gitignore
+++ b/.gitignore
@@ -220,6 +220,7 @@ paludis-*.*.*.tar.bz2
/paludis/repositories/e/aa_visitor_TEST
/paludis/repositories/e/dep_parser_TEST
/paludis/repositories/e/dep_spec_pretty_printer_TEST
+/paludis/repositories/e/depend_rdepend_TEST
/paludis/repositories/e/e_repository_TEST
/paludis/repositories/e/e_repository_TEST_ever
/paludis/repositories/e/e_repository_TEST_exlibs
diff --git a/paludis/repositories/e/Makefile.am b/paludis/repositories/e/Makefile.am
index 357bd49..8ff1026 100644
--- a/paludis/repositories/e/Makefile.am
+++ b/paludis/repositories/e/Makefile.am
@@ -165,6 +165,20 @@ e_repository_TEST_LDADD = \
e_repository_TEST_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir) @PALUDIS_CXXFLAGS_NO_DEBUGGING@
+depend_rdepend_TEST_SOURCES = depend_rdepend_TEST.cc
+
+depend_rdepend_TEST_LDADD = \
+ libpaludiserepository_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/repositories/fake/libpaludisfakerepository_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/util/libpaludisutil_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/paludis/libpaludis_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/environments/test/libpaludistestenvironment_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/test/libtest.a \
+ $(DYNAMIC_LD_LIBS)
+
+depend_rdepend_TEST_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir) @PALUDIS_CXXFLAGS_NO_DEBUGGING@
+
e_repository_TEST_ever_SOURCES = e_repository_TEST_ever.cc
e_repository_TEST_ever_LDADD = \
@@ -395,6 +409,9 @@ EXTRA_DIST = \
dep_parser-se.cc \
dep_parser_TEST.cc \
dep_spec_pretty_printer_TEST.cc \
+ depend_rdepend_TEST.cc \
+ depend_rdepend_TEST_setup.sh \
+ depend_rdepend_TEST_cleanup.sh \
e_repository_TEST.cc \
e_repository_TEST_setup.sh \
e_repository_TEST_cleanup.sh \
@@ -452,6 +469,7 @@ BUILT_SOURCES = \
iuse-se.cc
check_SCRIPTS = \
+ depend_rdepend_TEST_setup.sh depend_rdepend_TEST_cleanup.sh \
e_repository_TEST_setup.sh e_repository_TEST_cleanup.sh \
e_repository_TEST_ever_setup.sh e_repository_TEST_ever_cleanup.sh \
e_repository_TEST_phases_setup.sh e_repository_TEST_phases_cleanup.sh \
@@ -544,6 +562,7 @@ TESTS = \
aa_visitor_TEST \
dep_parser_TEST \
dep_spec_pretty_printer_TEST \
+ depend_rdepend_TEST \
e_repository_TEST \
e_repository_TEST_ever \
e_repository_TEST_phases \
diff --git a/paludis/repositories/e/depend_rdepend_TEST.cc b/paludis/repositories/e/depend_rdepend_TEST.cc
new file mode 100644
index 0000000..6cc45e4
--- /dev/null
+++ b/paludis/repositories/e/depend_rdepend_TEST.cc
@@ -0,0 +1,230 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/repositories/e/e_repository.hh>
+#include <paludis/repositories/e/vdb_repository.hh>
+#include <paludis/environments/test/test_environment.hh>
+#include <paludis/util/map.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/repository_factory.hh>
+#include <paludis/repository.hh>
+#include <paludis/package_database.hh>
+#include <paludis/standard_output_manager.hh>
+#include <paludis/action.hh>
+#include <paludis/selection.hh>
+#include <paludis/generator.hh>
+#include <paludis/filtered_generator.hh>
+#include <paludis/filter.hh>
+#include <paludis/stringify_formatter.hh>
+#include <paludis/metadata_key.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace test;
+using namespace paludis;
+
+namespace
+{
+ void cannot_uninstall(const std::tr1::shared_ptr<const PackageID> & id, const UninstallActionOptions &)
+ {
+ if (id)
+ throw InternalError(PALUDIS_HERE, "cannot uninstall");
+ }
+
+ std::tr1::shared_ptr<OutputManager> make_standard_output_manager(const Action &)
+ {
+ return make_shared_ptr(new StandardOutputManager);
+ }
+
+ std::string from_keys(const std::tr1::shared_ptr<const Map<std::string, std::string> > & m,
+ const std::string & k)
+ {
+ Map<std::string, std::string>::ConstIterator mm(m->find(k));
+ if (m->end() == mm)
+ return "";
+ else
+ return mm->second;
+ }
+
+ WantPhase want_all_phases(const std::string &)
+ {
+ return wp_yes;
+ }
+}
+
+namespace
+{
+ struct DependRdependTest : TestCase
+ {
+ const std::string eapi;
+ const bool special;
+
+ DependRdependTest(const std::string & e, bool s) :
+ TestCase("RDEPEND=DEPEND EAPI " + e),
+ eapi(e),
+ special(s)
+ {
+ }
+
+ unsigned max_run_time() const
+ {
+ return 3000;
+ }
+
+ bool repeatable() const
+ {
+ return false;
+ }
+
+ void run()
+ {
+#ifdef ENABLE_VIRTUALS_REPOSITORY
+ ::setenv("PALUDIS_ENABLE_VIRTUALS_REPOSITORY", "yes", 1);
+#else
+ ::setenv("PALUDIS_ENABLE_VIRTUALS_REPOSITORY", "", 1);
+#endif
+
+ TestEnvironment env;
+ env.set_paludis_command("/bin/false");
+
+ std::tr1::shared_ptr<Map<std::string, std::string> > keys(new Map<std::string, std::string>);
+ keys->insert("format", "ebuild");
+ keys->insert("names_cache", "/var/empty");
+ keys->insert("location", stringify(FSEntry::cwd() / "depend_rdepend_TEST_dir" / "repo"));
+ keys->insert("profiles", stringify(FSEntry::cwd() / "depend_rdepend_TEST_dir" / "repo/profiles/profile"));
+ keys->insert("layout", "traditional");
+ keys->insert("eapi_when_unknown", "0");
+ keys->insert("eapi_when_unspecified", "0");
+ keys->insert("profile_eapi", "0");
+ keys->insert("distdir", stringify(FSEntry::cwd() / "depend_rdepend_TEST_dir" / "distdir"));
+ keys->insert("builddir", stringify(FSEntry::cwd() / "depend_rdepend_TEST_dir" / "build"));
+ keys->insert("root", stringify(FSEntry::cwd() / "depend_rdepend_TEST_dir" / "root"));
+ std::tr1::shared_ptr<Repository> repo(ERepository::repository_factory_create(&env,
+ std::tr1::bind(from_keys, keys, std::tr1::placeholders::_1)));
+ env.package_database()->add_repository(1, repo);
+
+ std::tr1::shared_ptr<Map<std::string, std::string> > v_keys(new Map<std::string, std::string>);
+ v_keys->insert("format", "vdb");
+ v_keys->insert("names_cache", "/var/empty");
+ v_keys->insert("provides_cache", "/var/empty");
+ v_keys->insert("location", stringify(FSEntry::cwd() / "depend_rdepend_TEST_dir" / "vdb"));
+ v_keys->insert("root", stringify(FSEntry::cwd() / "depend_rdepend_TEST_dir" / "root"));
+ std::tr1::shared_ptr<Repository> v_repo(VDBRepository::repository_factory_create(&env,
+ std::tr1::bind(from_keys, keys, std::tr1::placeholders::_1)));
+ env.package_database()->add_repository(1, v_repo);
+
+#ifdef ENABLE_VIRTUALS_REPOSITORY
+ std::tr1::shared_ptr<Map<std::string, std::string> > iv_keys(new Map<std::string, std::string>);
+ iv_keys->insert("root", "/");
+ iv_keys->insert("format", "installed_virtuals");
+ env.package_database()->add_repository(-2, RepositoryFactory::get_instance()->create(&env,
+ std::tr1::bind(from_keys, iv_keys, std::tr1::placeholders::_1)));
+ std::tr1::shared_ptr<Map<std::string, std::string> > v_keys(new Map<std::string, std::string>);
+ v_keys->insert("format", "virtuals");
+ env.package_database()->add_repository(-2, RepositoryFactory::get_instance()->create(&env,
+ std::tr1::bind(from_keys, v_keys, std::tr1::placeholders::_1)));
+#endif
+
+ InstallAction action(make_named_values<InstallActionOptions>(
+ value_for<n::destination>(v_repo),
+ value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
+ value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
+ value_for<n::want_phase>(&want_all_phases)
+ ));
+
+ StringifyFormatter f;
+
+ {
+ std::tr1::shared_ptr<const PackageID> id(*env[selection::RequireExactlyOne(generator::Package(
+ QualifiedPackageName("cat/eapi" + eapi + "donly")))]->begin());
+
+ TEST_CHECK_EQUAL(id->build_dependencies_key()->pretty_print_flat(f), "the/depend");
+ if (special)
+ TEST_CHECK_EQUAL(id->run_dependencies_key()->pretty_print_flat(f), "the/depend");
+ else
+ TEST_CHECK_EQUAL(id->run_dependencies_key()->pretty_print_flat(f), "");
+
+ id->perform_action(action);
+
+ v_repo->invalidate();
+
+ std::tr1::shared_ptr<const PackageID> v_id(*env[selection::RequireExactlyOne(generator::Package(
+ QualifiedPackageName("cat/eapi" + eapi + "donly")) |
+ filter::SupportsAction<InstalledAction>())]->begin());
+
+ TEST_CHECK_EQUAL(v_id->build_dependencies_key()->pretty_print_flat(f), "the/depend");
+ if (special)
+ TEST_CHECK_EQUAL(v_id->run_dependencies_key()->pretty_print_flat(f), "the/depend");
+ else
+ TEST_CHECK_EQUAL(v_id->run_dependencies_key()->pretty_print_flat(f), "");
+ }
+
+ {
+ std::tr1::shared_ptr<const PackageID> id(*env[selection::RequireExactlyOne(generator::Package(
+ QualifiedPackageName("cat/eapi" + eapi + "ronly")))]->begin());
+
+ TEST_CHECK_EQUAL(id->build_dependencies_key()->pretty_print_flat(f), "");
+ TEST_CHECK_EQUAL(id->run_dependencies_key()->pretty_print_flat(f), "the/rdepend");
+
+ id->perform_action(action);
+
+ v_repo->invalidate();
+
+ std::tr1::shared_ptr<const PackageID> v_id(*env[selection::RequireExactlyOne(generator::Package(
+ QualifiedPackageName("cat/eapi" + eapi + "ronly")) |
+ filter::SupportsAction<InstalledAction>())]->begin());
+
+ TEST_CHECK_EQUAL(v_id->build_dependencies_key()->pretty_print_flat(f), "");
+ TEST_CHECK_EQUAL(v_id->run_dependencies_key()->pretty_print_flat(f), "the/rdepend");
+ }
+
+ {
+ std::tr1::shared_ptr<const PackageID> id(*env[selection::RequireExactlyOne(generator::Package(
+ QualifiedPackageName("cat/eapi" + eapi + "both")))]->begin());
+
+ TEST_CHECK_EQUAL(id->build_dependencies_key()->pretty_print_flat(f), "the/depend");
+ TEST_CHECK_EQUAL(id->run_dependencies_key()->pretty_print_flat(f), "the/rdepend");
+
+ id->perform_action(action);
+
+ v_repo->invalidate();
+
+ std::tr1::shared_ptr<const PackageID> v_id(*env[selection::RequireExactlyOne(generator::Package(
+ QualifiedPackageName("cat/eapi" + eapi + "both")) |
+ filter::SupportsAction<InstalledAction>())]->begin());
+
+ TEST_CHECK_EQUAL(v_id->build_dependencies_key()->pretty_print_flat(f), "the/depend");
+ TEST_CHECK_EQUAL(v_id->run_dependencies_key()->pretty_print_flat(f), "the/rdepend");
+ }
+ }
+ };
+}
+
+namespace test_cases
+{
+ DependRdependTest eapi_0("0", true);
+ DependRdependTest eapi_1("1", true);
+ DependRdependTest eapi_2("2", true);
+ DependRdependTest eapi_3("3", false);
+}
+
diff --git a/paludis/repositories/e/depend_rdepend_TEST_cleanup.sh b/paludis/repositories/e/depend_rdepend_TEST_cleanup.sh
new file mode 100755
index 0000000..f6c8211
--- /dev/null
+++ b/paludis/repositories/e/depend_rdepend_TEST_cleanup.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d depend_rdepend_TEST_dir ] ; then
+ rm -fr depend_rdepend_TEST_dir
+else
+ true
+fi
+
+
diff --git a/paludis/repositories/e/depend_rdepend_TEST_setup.sh b/paludis/repositories/e/depend_rdepend_TEST_setup.sh
new file mode 100755
index 0000000..8a3491f
--- /dev/null
+++ b/paludis/repositories/e/depend_rdepend_TEST_setup.sh
@@ -0,0 +1,76 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir depend_rdepend_TEST_dir || exit 1
+cd depend_rdepend_TEST_dir || exit 1
+
+mkdir -p root/etc
+
+mkdir -p vdb
+touch vdb/THISISTHEVDB
+
+mkdir -p build
+ln -s build symlinked_build
+
+mkdir -p distdir
+
+mkdir -p repo/{profiles/profile,metadata,eclass} || exit 1
+cd repo || exit 1
+echo "test-repo" >> profiles/repo_name || exit 1
+echo "cat" >> profiles/categories || exit 1
+cat <<END > profiles/profile/virtuals
+END
+cat <<END > profiles/profile/make.defaults
+ARCH="test"
+USERLAND="GNU"
+KERNEL="linux"
+LIBC="glibc"
+CHOST="i286-badger-linux-gnu"
+END
+
+for e in 0 1 2 3 ; do
+
+ mkdir -p "cat/eapi${e}donly"
+ cat <<END > cat/eapi${e}donly/eapi${e}donly-1.ebuild || exit 1
+EAPI="${e}"
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+DEPEND="the/depend"
+END
+
+ mkdir -p "cat/eapi${e}ronly"
+ cat <<END > cat/eapi${e}ronly/eapi${e}ronly-1.ebuild || exit 1
+EAPI="${e}"
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND="the/rdepend"
+END
+
+ mkdir -p "cat/eapi${e}both"
+ cat <<END > cat/eapi${e}both/eapi${e}both-1.ebuild || exit 1
+EAPI="${e}"
+DESCRIPTION="The Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+DEPEND="the/depend"
+RDEPEND="the/rdepend"
+END
+
+done
+
+cd ..
+
diff --git a/paludis/repositories/e/eapis/3.conf b/paludis/repositories/e/eapis/3.conf
index ee7e041..cf52a52 100644
--- a/paludis/repositories/e/eapis/3.conf
+++ b/paludis/repositories/e/eapis/3.conf
@@ -36,3 +36,5 @@ ebuild_pretend = \
dodoc_r = true
doins_r_symlink = true
+rdepend_defaults_to_depend = false
+
diff --git a/paludis/repositories/e/ebuild.cc b/paludis/repositories/e/ebuild.cc
index 64fda66..f81b3c5 100644
--- a/paludis/repositories/e/ebuild.cc
+++ b/paludis/repositories/e/ebuild.cc
@@ -475,7 +475,20 @@ EbuildMetadataCommand::load(const std::tr1::shared_ptr<const EbuildID> & id)
id->load_build_depend(m.build_depend()->name(), m.build_depend()->description(), get(keys, m.build_depend()->name()), false);
if (! m.run_depend()->name().empty())
- id->load_run_depend(m.run_depend()->name(), m.run_depend()->description(), get(keys, m.run_depend()->name()), false);
+ {
+ if (id->eapi()->supported()->ebuild_options()->rdepend_defaults_to_depend())
+ {
+ if (! get(keys, "PALUDIS_EBUILD_RDEPEND_WAS_SET").empty())
+ id->load_run_depend(m.run_depend()->name(), m.run_depend()->description(),
+ get(keys, m.run_depend()->name()), false);
+ else
+ id->load_run_depend(m.run_depend()->name(), m.run_depend()->description(),
+ get(keys, "PALUDIS_EBUILD_DEPEND") + " " + get(keys, m.run_depend()->name()), false);
+ }
+ else
+ id->load_run_depend(m.run_depend()->name(), m.run_depend()->description(),
+ get(keys, m.run_depend()->name()), false);
+ }
if (! m.pdepend()->name().empty())
id->load_post_depend(m.pdepend()->name(), m.pdepend()->description(), get(keys, m.pdepend()->name()), false);
diff --git a/paludis/repositories/e/ebuild/ebuild.bash b/paludis/repositories/e/ebuild/ebuild.bash
index 4741aa3..52af55b 100755
--- a/paludis/repositories/e/ebuild/ebuild.bash
+++ b/paludis/repositories/e/ebuild/ebuild.bash
@@ -52,7 +52,8 @@ EBUILD_METADATA_VARIABLES="DEPEND RDEPEND PDEPEND IUSE SRC_URI DOWNLOADS RESTRIC
MYOPTIONS E_MYOPTIONS E_DEPENDENCIES BINARY_KEYWORDS BINARY_URI \
GENERATED_USING GENERATED_TIME BINARY_PLATFORMS REMOTE_IDS \
SUMMARY BUGS_TO UPSTREAM_DOCUMENTATION UPSTREAM_CHANGELOG \
- UPSTREAM_RELEASE_NOTES PROPERTIES PALUDIS_DECLARED_FUNCTIONS SLOT EAPI OPTIONS USE"
+ UPSTREAM_RELEASE_NOTES PROPERTIES PALUDIS_DECLARED_FUNCTIONS SLOT EAPI OPTIONS USE \
+ PALUDIS_EBUILD_RDEPEND_WAS_SET PALUDIS_EBUILD_DEPEND"
EBUILD_METADATA_VARIABLES_FROM_CPLUSPLUS="SLOT EAPI OPTIONS USE"
if [[ -z "${PALUDIS_DO_NOTHING_SANDBOXY}" ]] ; then
@@ -306,9 +307,10 @@ ebuild_load_ebuild()
[[ -f ${1} ]] || die "Ebuild '${1}' is not a file"
source ${1} || die "Error sourcing ebuild '${1}'"
- if [[ -n ${PALUDIS_RDEPEND_DEFAULTS_TO_DEPEND} ]] ; then
- [[ ${RDEPEND+set} != set ]] && RDEPEND=${DEPEND}
- fi
+ # we may or may not use this later
+ PALUDIS_EBUILD_RDEPEND_WAS_SET=
+ PALUDIS_EBUILD_DEPEND="${DEPEND}"
+ [[ ${RDEPEND+set} != set ]] || PALUDIS_EBUILD_RDEPEND_WAS_SET=true
for paludis_v in ${PALUDIS_SOURCE_MERGED_VARIABLES} ; do
paludis_e_v=E_${paludis_v}
diff --git a/paludis/repositories/e/pipe_command_handler.cc b/paludis/repositories/e/pipe_command_handler.cc
index cfb1db0..d51a052 100644
--- a/paludis/repositories/e/pipe_command_handler.cc
+++ b/paludis/repositories/e/pipe_command_handler.cc
@@ -330,8 +330,18 @@ paludis::erepository::pipe_command_handler(const Environment * const environment
(var == eapi->supported()->ebuild_metadata_variables()->pdepend()->name()) ||
(var == eapi->supported()->ebuild_metadata_variables()->dependencies()->name()))
{
- std::tr1::shared_ptr<const DependencySpecTree> before(parse_depend(join(tokens.begin() + 4, tokens.end(), " "),
- environment, package_id, *eapi));
+ /* use the value in the metadata key, since RDEPEND in the
+ * ebuild env isn't modified for DEPEND=RDEPEND */
+ PackageID::MetadataConstIterator m(package_id->find_metadata(var));
+ if (m == package_id->end_metadata())
+ throw InternalError(PALUDIS_HERE, "oops. can't find key '" + var + "'");
+
+ const MetadataSpecTreeKey<DependencySpecTree> * mm(
+ simple_visitor_cast<const MetadataSpecTreeKey<DependencySpecTree> >(**m));
+ if (! mm)
+ throw InternalError(PALUDIS_HERE, "oops. key '" + var + "' isn't a DependencySpecTree key");
+
+ std::tr1::shared_ptr<const DependencySpecTree> before(mm->value());
std::tr1::shared_ptr<const DependencySpecTree> after(fix_locked_dependencies(
environment, *eapi, package_id, before));
StringifyFormatter ff;