aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2007-10-28 23:41:35 +0000
committerAvatar David Leverton <levertond@googlemail.com> 2007-10-28 23:41:35 +0000
commite6d9f10e7fdb353bb42728e3b56dd2b9dd24d212 (patch)
tree604b2dd993cb5268e3106e0699c7377fe23bfed1
parent0f2d6f7bd42ec620ce197ffa1c81112c0ca1b79c (diff)
downloadpaludis-e6d9f10e7fdb353bb42728e3b56dd2b9dd24d212.tar.gz
paludis-e6d9f10e7fdb353bb42728e3b56dd2b9dd24d212.tar.xz
Handle spaces in the VDB better.
-rw-r--r--NEWS2
-rw-r--r--doc/faq/stricter.html.part5
-rw-r--r--paludis/repositories/e/Makefile.am1
-rw-r--r--paludis/repositories/e/e_key.cc18
-rw-r--r--paludis/repositories/e/vdb_contents_tokeniser.hh113
-rw-r--r--paludis/repositories/e/vdb_merger.cc29
-rw-r--r--paludis/repositories/e/vdb_merger.hh4
-rw-r--r--paludis/repositories/e/vdb_merger_TEST.cc50
-rwxr-xr-xpaludis/repositories/e/vdb_merger_TEST_setup.sh23
-rw-r--r--paludis/repositories/e/vdb_repository_TEST.cc107
-rwxr-xr-xpaludis/repositories/e/vdb_repository_TEST_setup.sh38
-rw-r--r--paludis/repositories/e/vdb_unmerger.cc96
-rw-r--r--paludis/repositories/e/vdb_unmerger_TEST.cc70
-rwxr-xr-xpaludis/repositories/e/vdb_unmerger_TEST_setup.sh15
14 files changed, 470 insertions, 101 deletions
diff --git a/NEWS b/NEWS
index 7c00d15..10a1d9b 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ trunk/:
* More verbose paludis --info output.
+ * Paludis now fully supports filenames containing spaces.
+
* Bug fixes: --dl-deps-default works again.
0.26.0_alpha2:
diff --git a/doc/faq/stricter.html.part b/doc/faq/stricter.html.part
index 493437f..dff850d 100644
--- a/doc/faq/stricter.html.part
+++ b/doc/faq/stricter.html.part
@@ -20,11 +20,6 @@
anything with them. Ebuilds that need to install fancy file types should do
so in <code>pkg_postinst</code>.</li>
- <li>Things containing spaces. The VDB format, which cannot be changed
- without breaking Portage compatibility, uses spaces as a delimiter. Portage
- behaves incorrectly on items with spaces in the name; Paludis simply refuses
- to touch them.</li>
-
<li>Non-directories on top of directories. Paludis will not let a package
overwrite a directory with a non-directory. This is for your own safety.
Portage doesn't bail out on this, but instead ends up partially merging
diff --git a/paludis/repositories/e/Makefile.am b/paludis/repositories/e/Makefile.am
index 4d10227..0b7c46a 100644
--- a/paludis/repositories/e/Makefile.am
+++ b/paludis/repositories/e/Makefile.am
@@ -82,6 +82,7 @@ paludis_repositories_e_include_HEADERS = \
source_uri_finder.hh \
traditional_layout.hh \
use_desc.hh \
+ vdb_contents_tokeniser.hh \
vdb_id.hh \
vdb_merger-sr.hh \
vdb_merger.hh \
diff --git a/paludis/repositories/e/e_key.cc b/paludis/repositories/e/e_key.cc
index 6f7c5c3..f0e6e27 100644
--- a/paludis/repositories/e/e_key.cc
+++ b/paludis/repositories/e/e_key.cc
@@ -22,6 +22,7 @@
#include <paludis/repositories/e/dep_parser.hh>
#include <paludis/repositories/e/eapi.hh>
#include <paludis/repositories/e/dep_spec_pretty_printer.hh>
+#include <paludis/repositories/e/vdb_contents_tokeniser.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/stringify.hh>
@@ -1119,11 +1120,7 @@ EContentsKey::value() const
++line_number;
std::vector<std::string> tokens;
- WhitespaceTokeniser::tokenise(line, std::back_inserter(tokens));
- if (tokens.empty())
- continue;
-
- if (tokens.size() < 2)
+ if (! VDBContentsTokeniser::tokenise(line, std::back_inserter(tokens)))
{
Log::get_instance()->message(ll_warning, lc_no_context) << "CONTENTS has broken line " <<
line_number << ", skipping";
@@ -1141,16 +1138,7 @@ EContentsKey::value() const
else if ("dev" == tokens.at(0))
_imp->value->add(tr1::shared_ptr<ContentsEntry>(new ContentsDevEntry(tokens.at(1))));
else if ("sym" == tokens.at(0))
- {
- if (tokens.size() < 4)
- {
- Log::get_instance()->message(ll_warning, lc_no_context) << "CONTENTS has broken sym line " <<
- line_number << ", skipping";
- continue;
- }
-
- _imp->value->add(tr1::shared_ptr<ContentsEntry>(new ContentsSymEntry(tokens.at(1), tokens.at(3))));
- }
+ _imp->value->add(tr1::shared_ptr<ContentsEntry>(new ContentsSymEntry(tokens.at(1), tokens.at(2))));
}
return _imp->value;
diff --git a/paludis/repositories/e/vdb_contents_tokeniser.hh b/paludis/repositories/e/vdb_contents_tokeniser.hh
new file mode 100644
index 0000000..f17037b
--- /dev/null
+++ b/paludis/repositories/e/vdb_contents_tokeniser.hh
@@ -0,0 +1,113 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 David Leverton
+ *
+ * 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
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_VDB_CONTENTS_TOKENISER_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_VDB_CONTENTS_TOKENISER_HH
+
+#include <string>
+
+namespace paludis
+{
+ namespace erepository
+ {
+ class VDBContentsTokeniser
+ {
+ private:
+ VDBContentsTokeniser();
+
+ public:
+ template <typename Iter_>
+ static bool tokenise(const std::string &, Iter_);
+ };
+
+ template <typename Iter_>
+ bool
+ VDBContentsTokeniser::tokenise(const std::string & s, Iter_ iter)
+ {
+ static const std::string space(" \t\r\n");
+
+ std::string::size_type type_begin(s.find_first_not_of(space));
+ if (std::string::npos == type_begin)
+ return false;
+
+ std::string::size_type type_end(s.find_first_of(space, type_begin + 1));
+ // need at least one character for the filename after the
+ // whitespace
+ if (std::string::npos == type_end || s.length() <= type_end + 1)
+ return false;
+ // skip the whitespace
+ std::string::size_type filename_begin(type_end + 1);
+
+ std::string type(s.substr(type_begin, type_end - type_begin));
+ int extra_fields(0);
+ if ("obj" == type)
+ extra_fields = 2;
+ else if ("sym" == type)
+ extra_fields = 1;
+
+ std::string::size_type filename_end(s.length());
+ for (int x(0); x < extra_fields; ++x)
+ {
+ // filename_end is exclusive, but the second argument
+ // to find_last_not_of is inclusive
+ std::string::size_type extra_end(s.find_last_not_of(space, filename_end - 1));
+ if (std::string::npos == extra_end || extra_end <= filename_begin)
+ return false;
+ // filename_end will point /at/ the delimeter space,
+ // which is fine because it's exclusive
+ filename_end = s.find_last_of(space, extra_end);
+ if (std::string::npos == filename_end || filename_end <= filename_begin)
+ return false;
+ }
+
+ if ("sym" == type)
+ {
+ // need at least one character each for the symlink
+ // name itself and the target
+ std::string::size_type arrow_begin(s.find(" -> ", filename_begin + 1));
+ if (std::string::npos == arrow_begin || arrow_begin >= filename_end - 4)
+ return false;
+
+ *iter++ = type;
+ *iter++ = s.substr(filename_begin, arrow_begin - filename_begin);
+ *iter++ = s.substr(arrow_begin + 4, filename_end - (arrow_begin + 4));
+ }
+ else
+ {
+ *iter++ = type;
+ *iter++ = s.substr(filename_begin, filename_end - filename_begin);
+ }
+
+ // none of these finds should fail because we already
+ // counted the extra fields above
+ std::string::size_type pos(filename_end + 1);
+ for (int x(0); x < extra_fields; ++x)
+ {
+ std::string::size_type extra_begin(s.find_first_not_of(space, pos));
+ std::string::size_type extra_end(s.find_first_of(space, extra_begin + 1));
+ *iter++ = s.substr(extra_begin, extra_end - extra_begin);
+ pos = extra_end + 1;
+ }
+
+ return true;
+ }
+ }
+}
+
+#endif
diff --git a/paludis/repositories/e/vdb_merger.cc b/paludis/repositories/e/vdb_merger.cc
index 0a2d5ab..59d7c9f 100644
--- a/paludis/repositories/e/vdb_merger.cc
+++ b/paludis/repositories/e/vdb_merger.cc
@@ -260,6 +260,35 @@ VDBMerger::on_enter_dir(bool is_check, const FSEntry)
}
void
+VDBMerger::on_file(bool is_check, const FSEntry & src, const FSEntry & dst)
+{
+ if (is_check && std::string::npos != src.basename().find('\n'))
+ throw MergerError("File '" + stringify(src) + "' contains a newline in its name, which cannot be stored by VDB");
+ Merger::on_file(is_check, src, dst);
+}
+
+void
+VDBMerger::on_dir(bool is_check, const FSEntry & src, const FSEntry & dst)
+{
+ if (is_check && std::string::npos != src.basename().find('\n'))
+ throw MergerError("Directory '" + stringify(src) + "' contains a newline in its name, which cannot be stored by VDB");
+ Merger::on_dir(is_check, src, dst);
+}
+
+void
+VDBMerger::on_sym(bool is_check, const FSEntry & src, const FSEntry & dst)
+{
+ if (is_check)
+ {
+ if (std::string::npos != src.basename().find('\n'))
+ throw MergerError("'" + stringify(src) + "Symlink ' contains a newline in its name, which cannot be stored by VDB");
+ if (std::string::npos != stringify(src).find(" -> "))
+ throw MergerError("'" + stringify(src) + "Symlink ' contains a ' -> ' in its name, which cannot be stored by VDB");
+ }
+ Merger::on_sym(is_check, src, dst);
+}
+
+void
VDBMerger::display_override(const std::string & message) const
{
std::cout << message << std::endl;
diff --git a/paludis/repositories/e/vdb_merger.hh b/paludis/repositories/e/vdb_merger.hh
index 9838de6..b5a5896 100644
--- a/paludis/repositories/e/vdb_merger.hh
+++ b/paludis/repositories/e/vdb_merger.hh
@@ -62,6 +62,10 @@ namespace paludis
virtual void on_warn(bool is_check, const std::string &);
virtual void on_enter_dir(bool is_check, const FSEntry);
+ virtual void on_file(bool is_check, const FSEntry &, const FSEntry &);
+ virtual void on_dir(bool is_check, const FSEntry &, const FSEntry &);
+ virtual void on_sym(bool is_check, const FSEntry &, const FSEntry &);
+
virtual bool config_protected(const FSEntry &, const FSEntry &);
virtual std::string make_config_protect_name(const FSEntry &, const FSEntry &);
diff --git a/paludis/repositories/e/vdb_merger_TEST.cc b/paludis/repositories/e/vdb_merger_TEST.cc
index d5b96e2..88eb657 100644
--- a/paludis/repositories/e/vdb_merger_TEST.cc
+++ b/paludis/repositories/e/vdb_merger_TEST.cc
@@ -177,5 +177,55 @@ namespace test_cases
TEST_CHECK(! (root_dir / "protected_dir_not_really/._cfg0000_unprotected_file").exists());
}
} test_vdb_merger_config_protect;
+
+ struct VDBMergerTestFileNewline : VDBMergerTest
+ {
+ VDBMergerTestFileNewline() : VDBMergerTest("file_newline") { }
+
+ void run()
+ {
+ TEST_CHECK_THROWS(merger.check(), MergerError);
+ }
+ } test_vdb_merger_file_newline;
+
+ struct VDBMergerTestDirNewline : VDBMergerTest
+ {
+ VDBMergerTestDirNewline() : VDBMergerTest("dir_newline") { }
+
+ void run()
+ {
+ TEST_CHECK_THROWS(merger.check(), MergerError);
+ }
+ } test_vdb_merger_dir_newline;
+
+ struct VDBMergerTestSymNewline : VDBMergerTest
+ {
+ VDBMergerTestSymNewline() : VDBMergerTest("sym_newline") { }
+
+ void run()
+ {
+ TEST_CHECK_THROWS(merger.check(), MergerError);
+ }
+ } test_vdb_merger_sym_newline;
+
+ struct VDBMergerTestSymArrow : VDBMergerTest
+ {
+ VDBMergerTestSymArrow() : VDBMergerTest("sym_arrow") { }
+
+ void run()
+ {
+ TEST_CHECK_THROWS(merger.check(), MergerError);
+ }
+ } test_vdb_merger_sym_arrow;
+
+ struct VDBMergerTestSymArrow2 : VDBMergerTest
+ {
+ VDBMergerTestSymArrow2() : VDBMergerTest("sym_arrow2") { }
+
+ void run()
+ {
+ TEST_CHECK_THROWS(merger.check(), MergerError);
+ }
+ } test_vdb_merger_sym_arrow2;
}
diff --git a/paludis/repositories/e/vdb_merger_TEST_setup.sh b/paludis/repositories/e/vdb_merger_TEST_setup.sh
index 1cd9693..ea27bfc 100755
--- a/paludis/repositories/e/vdb_merger_TEST_setup.sh
+++ b/paludis/repositories/e/vdb_merger_TEST_setup.sh
@@ -3,9 +3,10 @@
mkdir vdb_merger_TEST_dir || exit 2
cd vdb_merger_TEST_dir || exit 3
+mkdir CONTENTS || exit 4
-mkdir -p config_protect_dir/{image,root,CONTENTS} || exit 4
+mkdir -p config_protect_dir/{image,root} || exit 4
cd config_protect_dir/image
@@ -60,6 +61,26 @@ echo bar >protected_dir_not_really/unprotected_file
cd ../..
+mkdir -p file_newline_dir/{image,root} || exit 4
+touch file_newline_dir/image/"file
+newline"
+
+mkdir -p dir_newline_dir/{image,root} || exit 4
+mkdir dir_newline_dir/image/"dir
+newline"
+
+mkdir -p sym_newline_dir/{image,root} || exit 4
+ln -s foo sym_newline_dir/image/"sym
+newline"
+
+mkdir -p sym_arrow_dir/{image,root} || exit 4
+ln -s bar sym_arrow_dir/image/"sym -> arrow"
+
+mkdir -p sym_arrow2_dir/{image,root} || exit 4
+mkdir sym_arrow2_dir/image/"dir -> ectory"
+ln -s bar sym_arrow2_dir/image/"dir -> ectory/sym"
+
+
for d in *_dir; do
ln -s ${d} ${d%_dir}
done
diff --git a/paludis/repositories/e/vdb_repository_TEST.cc b/paludis/repositories/e/vdb_repository_TEST.cc
index 72d9805..d6384b5 100644
--- a/paludis/repositories/e/vdb_repository_TEST.cc
+++ b/paludis/repositories/e/vdb_repository_TEST.cc
@@ -20,7 +20,9 @@
#include <paludis/repositories/e/vdb_repository.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/package_database.hh>
+#include <paludis/metadata_key.hh>
#include <paludis/util/sequence.hh>
+#include <paludis/util/visitor-impl.hh>
#include <paludis/query.hh>
#include <test/test_framework.hh>
#include <test/test_runner.hh>
@@ -243,5 +245,110 @@ namespace test_cases
TEST_CHECK_EQUAL(world_content, "cat-one/foo\ncat-one/bar\ncat-one/oink\ncat-one/foofoo\n");
}
} test_vdb_repository_add_to_world_no_match_no_eol;
+
+ /**
+ * \test Test VDBRepository CONTENTS.
+ */
+ struct VDBRepositoryContentsTest : TestCase
+ {
+ VDBRepositoryContentsTest() : TestCase("CONTENTS") { }
+
+ struct ContentsGatherer :
+ ConstVisitor<ContentsVisitorTypes>
+ {
+ std::string _str;
+
+ void visit(const ContentsFileEntry & e)
+ {
+ _str += "file\n";
+ _str += stringify(e.name());
+ _str += '\n';
+ }
+
+ void visit(const ContentsDirEntry & e)
+ {
+ _str += "directory\n";
+ _str += stringify(e.name());
+ _str += '\n';
+ }
+
+ void visit(const ContentsSymEntry & e)
+ {
+ _str += "symlink\n";
+ _str += stringify(e.name());
+ _str += '\n';
+ _str += stringify(e.target());
+ _str += '\n';
+ }
+
+ void visit(const ContentsMiscEntry & e)
+ {
+ _str += "miscellaneous\n";
+ _str += stringify(e.name());
+ _str += '\n';
+ }
+
+ void visit(const ContentsFifoEntry & e)
+ {
+ _str += "fifo\n";
+ _str += stringify(e.name());
+ _str += '\n';
+ }
+
+ void visit(const ContentsDevEntry & e)
+ {
+ _str += "device\n";
+ _str += stringify(e.name());
+ _str += '\n';
+ }
+ };
+
+ void run()
+ {
+ TestEnvironment env;
+ tr1::shared_ptr<Map<std::string, std::string> > keys(new Map<std::string, std::string>);
+ keys->insert("format", "vdb");
+ keys->insert("names_cache", "/var/empty");
+ keys->insert("provides_cache", "/var/empty");
+ keys->insert("location", "vdb_repository_TEST_dir/repo1");
+ keys->insert("world", "vdb_repository_TEST_dir/world-no-match-no-eol");
+ tr1::shared_ptr<Repository> repo(VDBRepository::make_vdb_repository(
+ &env, keys));
+ env.package_database()->add_repository(1, repo);
+
+ tr1::shared_ptr<const PackageID> e1(*env.package_database()->query(query::Matches(
+ PackageDepSpec("=cat-one/pkg-one-1", pds_pm_permissive)), qo_require_exactly_one)->begin());
+ ContentsGatherer gatherer;
+ std::for_each(indirect_iterator(e1->contents_key()->value()->begin()),
+ indirect_iterator(e1->contents_key()->value()->end()),
+ accept_visitor(gatherer));
+ TEST_CHECK_EQUAL(gatherer._str,
+ "directory\n/directory\n"
+ "file\n/directory/file\n"
+ "symlink\n/directory/symlink\ntarget\n"
+ "directory\n/directory with spaces\n"
+ "directory\n/directory with trailing space \n"
+ "directory\n/directory with consecutive spaces\n"
+ "file\n/file with spaces\n"
+ "file\n/file with consecutive spaces\n"
+ "file\n/file with trailing space\t \n"
+ "symlink\n/symlink\ntarget with consecutive spaces\n"
+ "symlink\n/symlink with spaces\ntarget with spaces\n"
+ "symlink\n/symlink with consecutive spaces\ntarget with consecutive spaces\n"
+ "symlink\n/symlink\ntarget -> with -> multiple -> arrows\n"
+ "symlink\n/symlink\ntarget with trailing space \n"
+ "symlink\n/symlink\n target with leading space\n"
+ "symlink\n/symlink with trailing space \ntarget\n"
+ "fifo\n/fifo\n"
+ "fifo\n/fifo with spaces\n"
+ "fifo\n/fifo with consecutive spaces\n"
+ "device\n/device\n"
+ "device\n/device with spaces\n"
+ "device\n/device with consecutive spaces\n"
+ "miscellaneous\n/miscellaneous\n"
+ "miscellaneous\n/miscellaneous with spaces\n"
+ "miscellaneous\n/miscellaneous with consecutive spaces\n");
+ }
+ } vdb_repository_contents_test;
}
diff --git a/paludis/repositories/e/vdb_repository_TEST_setup.sh b/paludis/repositories/e/vdb_repository_TEST_setup.sh
index 138a6b1..b208d1f 100755
--- a/paludis/repositories/e/vdb_repository_TEST_setup.sh
+++ b/paludis/repositories/e/vdb_repository_TEST_setup.sh
@@ -16,6 +16,44 @@ done
echo "flag1 flag2" >>repo1/cat-one/pkg-one-1/USE
+cat <<END >repo1/cat-one/pkg-one-1/CONTENTS
+dir /directory
+ obj /directory/file 4 2
+sym /directory/symlink -> target 2
+dir /directory with spaces
+dir /directory with trailing space
+dir /directory with consecutive spaces
+obj /file with spaces 4 2
+obj /file with consecutive spaces 4 2
+obj /file with trailing space 4 2
+sym /symlink -> target with consecutive spaces 2
+sym /symlink with spaces -> target with spaces 2
+sym /symlink with consecutive spaces -> target with consecutive spaces 2
+sym /symlink -> target -> with -> multiple -> arrows 2
+sym /symlink -> target with trailing space 2
+sym /symlink -> target with leading space 2
+sym /symlink with trailing space -> target 2
+fif /fifo
+fif /fifo with spaces
+fif /fifo with consecutive spaces
+dev /device
+dev /device with spaces
+dev /device with consecutive spaces
+misc /miscellaneous
+misc /miscellaneous with spaces
+misc /miscellaneous with consecutive spaces
+
+obj
+ obj
+obj /file
+obj /file
+obj /file 2
+sym foobar 2
+sym foo -> bar
+sym -> bar 2
+sym foo -> 2
+END
+
touch "world-empty"
cat <<END > world-no-match
cat-one/foo
diff --git a/paludis/repositories/e/vdb_unmerger.cc b/paludis/repositories/e/vdb_unmerger.cc
index bd6ff3f..ad9366b 100644
--- a/paludis/repositories/e/vdb_unmerger.cc
+++ b/paludis/repositories/e/vdb_unmerger.cc
@@ -19,6 +19,7 @@
*/
#include "vdb_unmerger.hh"
+#include "vdb_contents_tokeniser.hh"
using namespace paludis;
@@ -210,102 +211,39 @@ VDBUnmerger::populate_unmerge_set()
while (std::getline(c, line))
{
std::vector<std::string> tokens;
- WhitespaceTokeniser::tokenise(line, std::back_inserter(tokens));
- if (tokens.empty())
+ if (! erepository::VDBContentsTokeniser::tokenise(line, std::back_inserter(tokens)))
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
continue;
+ }
if ("obj" == tokens.at(0))
{
- while (tokens.size() > 4)
- {
- if (std::string::npos != tokens.at(4).find('='))
- break;
-
- tokens.at(1).append(" " + tokens.at(2));
- tokens.erase(next(tokens.begin(), 2));
- }
-
- if (tokens.size() != 4)
- Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
- else
- {
- std::string md5sum(tokens.at(2));
- time_t mtime(destringify<time_t>(tokens.at(3)));
- tr1::shared_ptr<ExtraInfo> extra(new FileExtraInfo(md5sum, mtime));
- add_unmerge_entry(tokens.at(1), et_file, extra);
- }
+ std::string md5sum(tokens.at(2));
+ time_t mtime(destringify<time_t>(tokens.at(3)));
+ tr1::shared_ptr<ExtraInfo> extra(new FileExtraInfo(md5sum, mtime));
+ add_unmerge_entry(tokens.at(1), et_file, extra);
}
else if ("sym" == tokens.at(0))
{
- while (tokens.size() > 5)
- {
- if (tokens.at(2) == "->")
- break;
-
- tokens.at(1).append(" " + tokens.at(2));
- tokens.erase(next(tokens.begin(), 2));
- }
-
- while (tokens.size() > 5)
- {
- if (std::string::npos != tokens.at(5).find('='))
- break;
-
- tokens.at(3).append(" " + tokens.at(4));
- tokens.erase(next(tokens.begin(), 4));
- }
-
- if (tokens.size() != 5 || tokens.at(2) != "->")
- Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
- else
- {
- std::string dest(tokens.at(3));
- time_t mtime(destringify<time_t>(tokens.at(4)));
- tr1::shared_ptr<ExtraInfo> extra(new SymlinkExtraInfo(dest, mtime));
- add_unmerge_entry(tokens.at(1), et_sym, extra);
- }
+ std::string dest(tokens.at(2));
+ time_t mtime(destringify<time_t>(tokens.at(3)));
+ tr1::shared_ptr<ExtraInfo> extra(new SymlinkExtraInfo(dest, mtime));
+ add_unmerge_entry(tokens.at(1), et_sym, extra);
}
else if ("misc" == tokens.at(0))
{
}
else if ("fif" == tokens.at(0) || "dev" == tokens.at(0))
{
- while (tokens.size() > 2)
- {
- if (std::string::npos != tokens.at(2).find('='))
- break;
-
- tokens.at(1).append(" " + tokens.at(2));
- tokens.erase(next(tokens.begin(), 2));
- }
-
- if (tokens.size() != 2)
- Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
- else
- {
- std::string type(tokens.at(0));
- tr1::shared_ptr<ExtraInfo> extra(new MiscExtraInfo(type));
- add_unmerge_entry(tokens.at(1), et_misc, extra);
- }
+ std::string type(tokens.at(0));
+ tr1::shared_ptr<ExtraInfo> extra(new MiscExtraInfo(type));
+ add_unmerge_entry(tokens.at(1), et_misc, extra);
}
else if ("dir" == tokens.at(0))
{
- while (tokens.size() > 2)
- {
- if (std::string::npos != tokens.at(2).find('='))
- break;
-
- tokens.at(1).append(" " + tokens.at(2));
- tokens.erase(next(tokens.begin(), 2));
- }
-
- if (tokens.size() != 2)
- Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
- else
- {
- add_unmerge_entry(tokens.at(1), et_dir, tr1::shared_ptr<ExtraInfo>());
- }
+ add_unmerge_entry(tokens.at(1), et_dir, tr1::shared_ptr<ExtraInfo>());
}
else
Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
diff --git a/paludis/repositories/e/vdb_unmerger_TEST.cc b/paludis/repositories/e/vdb_unmerger_TEST.cc
index 1c564d7..7036ec8 100644
--- a/paludis/repositories/e/vdb_unmerger_TEST.cc
+++ b/paludis/repositories/e/vdb_unmerger_TEST.cc
@@ -108,6 +108,34 @@ namespace test_cases
}
} test_vdb_unmerger_file_with_spaces;
+ struct VDBUnmergerTestFileWithLotsOfSpaces : VDBUnmergerTest
+ {
+ VDBUnmergerTestFileWithLotsOfSpaces() : VDBUnmergerTest("file_ with lots of spaces") { }
+
+ void run()
+ {
+ TEST_CHECK((root_dir / target).is_regular_file());
+
+ unmerger.unmerge();
+
+ TEST_CHECK(! (root_dir / target).exists());
+ }
+ } test_vdb_unmerger_file_with_lots_of_spaces;
+
+ struct VDBUnmergerTestFileWithTrailingSpace : VDBUnmergerTest
+ {
+ VDBUnmergerTestFileWithTrailingSpace() : VDBUnmergerTest("file_ with trailing space\t ") { }
+
+ void run()
+ {
+ TEST_CHECK((root_dir / target).is_regular_file());
+
+ unmerger.unmerge();
+
+ TEST_CHECK(! (root_dir / target).exists());
+ }
+ } test_vdb_unmerger_file_with_trailing_space;
+
struct VDBUnmergerTestFileBadType : VDBUnmergerTest
{
VDBUnmergerTestFileBadType() : VDBUnmergerTest("file_bad_type") { }
@@ -178,6 +206,20 @@ namespace test_cases
}
} test_vdb_unmerger_dir_with_spaces;
+ struct VDBUnmergerTestDirWithLotsOfSpaces : VDBUnmergerTest
+ {
+ VDBUnmergerTestDirWithLotsOfSpaces() : VDBUnmergerTest("dir_ with lots of spaces") { }
+
+ void run()
+ {
+ TEST_CHECK((root_dir / target).is_directory());
+
+ unmerger.unmerge();
+
+ TEST_CHECK(! (root_dir / target).exists());
+ }
+ } test_vdb_unmerger_dir_with_lots_of_spaces;
+
struct VDBUnmergerTestDirBadType : VDBUnmergerTest
{
VDBUnmergerTestDirBadType() : VDBUnmergerTest("dir_bad_type") { }
@@ -234,6 +276,34 @@ namespace test_cases
}
} test_vdb_unmerger_sym_with_spaces;
+ struct VDBUnmergerTestSymWithLotsOfSpaces : VDBUnmergerTest
+ {
+ VDBUnmergerTestSymWithLotsOfSpaces() : VDBUnmergerTest("sym_ with lots of spaces") { }
+
+ void run()
+ {
+ TEST_CHECK((root_dir / target).is_symbolic_link());
+
+ unmerger.unmerge();
+
+ TEST_CHECK(! (root_dir / target).exists());
+ }
+ } test_vdb_unmerger_sym_with_lots_of_spaces;
+
+ struct VDBUnmergerTestSymWithManyArrows : VDBUnmergerTest
+ {
+ VDBUnmergerTestSymWithManyArrows() : VDBUnmergerTest("sym with many arrows") { }
+
+ void run()
+ {
+ TEST_CHECK((root_dir / target).is_symbolic_link());
+
+ unmerger.unmerge();
+
+ TEST_CHECK(! (root_dir / target).exists());
+ }
+ } test_vdb_unmerger_sym_with_many_arrows;
+
struct VDBUnmergerTestSymBadType : VDBUnmergerTest
{
VDBUnmergerTestSymBadType() : VDBUnmergerTest("sym_bad_type") { }
diff --git a/paludis/repositories/e/vdb_unmerger_TEST_setup.sh b/paludis/repositories/e/vdb_unmerger_TEST_setup.sh
index 353713a..013441b 100755
--- a/paludis/repositories/e/vdb_unmerger_TEST_setup.sh
+++ b/paludis/repositories/e/vdb_unmerger_TEST_setup.sh
@@ -25,13 +25,17 @@ make_sym() {
ln -s "${dst}" "${src}"
mtime=${3:-$(${PALUDIS_EBUILD_DIR}/utils/wrapped_getmtime "sym_$1")}
- echo "sym /${src} -> sym_$1_dst ${mtime}" > "../CONTENTS/sym_$1"
+ echo "sym /${src} -> sym_$1_dst ${mtime}" > "../CONTENTS/sym_$1"
}
make_file "ok"
make_file " with spaces"
+make_file " with lots of spaces"
+
+make_file " with trailing space "
+
make_file "bad_type"
rm file_bad_type
mkdir file_bad_type
@@ -46,6 +50,9 @@ echo "dir /dir_ok" > ../CONTENTS/dir_ok
mkdir "dir_ with spaces"
echo "dir /dir_ with spaces" > "../CONTENTS/dir_ with spaces"
+mkdir "dir_ with lots of spaces"
+echo "dir /dir_ with lots of spaces" > "../CONTENTS/dir_ with lots of spaces"
+
> dir_bad_type
echo "dir /dir_bad_type" > ../CONTENTS/dir_bad_type
@@ -54,6 +61,12 @@ echo "dir /dir_not_empty" > ../CONTENTS/dir_not_empty
make_sym "ok"
make_sym " with spaces"
+make_sym " with lots of spaces"
+
+> "sym -> with -> many -> arrows -> dst"
+ln -s "sym -> with -> many -> arrows -> dst" "sym with many arrows"
+mtime=${3:-$(${PALUDIS_EBUILD_DIR}/utils/wrapped_getmtime "sym with many arrows")}
+echo "sym /sym with many arrows -> sym -> with -> many -> arrows -> dst ${mtime}" > "../CONTENTS/sym with many arrows"
make_sym "bad_type"
rm sym_bad_type