aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-01-22 07:15:29 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-01-22 07:15:29 +0000
commit3dff66adc5903d575c63da59e034742ac17a8cad (patch)
tree0aefb96cd081eb3d7e242515cc0642b44bf18c09
parentab4ad3f5c900baab0d66cdcd4ba72a2b1d5c18b9 (diff)
downloadpaludis-3dff66adc5903d575c63da59e034742ac17a8cad.tar.gz
paludis-3dff66adc5903d575c63da59e034742ac17a8cad.tar.xz
Add new constructors to ConfigFile and descendents that take filenames rather than stream pointers. Use them where appropriate. Move ConfigFileError into config_file.
-rw-r--r--paludis/config_file.cc47
-rw-r--r--paludis/config_file.hh39
-rw-r--r--paludis/config_file_TEST.cc36
-rwxr-xr-xpaludis/config_file_TEST_cleanup.sh10
-rwxr-xr-xpaludis/config_file_TEST_setup.sh9
-rw-r--r--paludis/config_file_error.cc29
-rw-r--r--paludis/config_file_error.hh44
-rw-r--r--paludis/default_config.cc30
-rw-r--r--paludis/files.m43
-rw-r--r--paludis/key_value_config_file.cc5
-rw-r--r--paludis/key_value_config_file.hh2
-rw-r--r--paludis/line_config_file.cc5
-rw-r--r--paludis/line_config_file.hh2
-rw-r--r--paludis/portage_repository.cc31
14 files changed, 161 insertions, 131 deletions
diff --git a/paludis/config_file.cc b/paludis/config_file.cc
index ea05bd0..0c40c19 100644
--- a/paludis/config_file.cc
+++ b/paludis/config_file.cc
@@ -19,17 +19,57 @@
*/
#include "config_file.hh"
-#include "config_file_error.hh"
#include "strip.hh"
#include "exception.hh"
#include "stringify.hh"
+#include <fstream>
using namespace paludis;
+ConfigFileError::ConfigFileError(const std::string & message) throw () :
+ Exception("Config file error: " + message)
+{
+}
+
ConfigFile::ConfigFile(std::istream * const stream) :
_stream(stream),
- _has_lines(false)
+ _has_lines(false),
+ _destroy_stream(false)
+{
+}
+
+ConfigFile::ConfigFile(const std::string & filename) try :
+ _stream(_make_stream(filename)),
+ _has_lines(false),
+ _filename(filename),
+ _destroy_stream(true)
+{
+}
+catch (...)
+{
+ _destroy_stream = false;
+ throw;
+}
+
+ConfigFile::~ConfigFile()
+{
+ if (_stream && _destroy_stream)
+ delete _stream;
+}
+
+std::istream *
+ConfigFile::_make_stream(const std::string & filename)
{
+ Context context("When creating the filestream for a ConfigFile from file '" + filename + "':");
+
+ std::ifstream * result(new std::ifstream(filename.c_str()));
+ if (! *result)
+ {
+ delete result;
+ throw ConfigFileError("Could not open '" + filename + "'");
+ }
+
+ return result;
}
void
@@ -42,7 +82,8 @@ ConfigFile::need_lines() const
unsigned line_number(0);
while (std::getline(*_stream, line))
{
- Context c("When handling line " + stringify(++line_number) + ":");
+ Context c("When handling line " + stringify(++line_number) +
+ (_filename.empty() ? std::string(":") : " in file '" + _filename + "':"));
normalise_line(line);
if (skip_line(line))
continue;
diff --git a/paludis/config_file.hh b/paludis/config_file.hh
index 198891f..95742db 100644
--- a/paludis/config_file.hh
+++ b/paludis/config_file.hh
@@ -30,11 +30,27 @@
* Declarations for the ConfigFile class.
*
* \ingroup ConfigFile
+ * \ingroup Exception
*/
namespace paludis
{
/**
+ * Thrown if an error occurs when reading a ConfigFile.
+ *
+ * \ingroup Exception
+ * \ingroup ConfigFile
+ */
+ class ConfigFileError : public Exception
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ ConfigFileError(const std::string & message) throw ();
+ };
+
+ /**
* A ConfigFile is a file containing one entry per line, with lines
* starting with a # being ignored and leading and trailing whitespace
* being discarded.
@@ -49,6 +65,12 @@ namespace paludis
mutable bool _has_lines;
+ std::string _filename;
+
+ bool _destroy_stream;
+
+ static std::istream * _make_stream(const std::string & filename);
+
protected:
/**
* In-place normalise a line. By default, trims leading and
@@ -79,13 +101,24 @@ namespace paludis
*/
ConfigFile(std::istream * const stream);
- public:
/**
- * Destructor.
+ * Constructor, from a file.
+ */
+ ConfigFile(const std::string & filename);
+
+ /**
+ * Our filename, or blank if unknown.
*/
- virtual ~ConfigFile()
+ std::string filename() const
{
+ return _filename;
}
+
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~ConfigFile();
};
}
diff --git a/paludis/config_file_TEST.cc b/paludis/config_file_TEST.cc
index d103e90..7fd8db4 100644
--- a/paludis/config_file_TEST.cc
+++ b/paludis/config_file_TEST.cc
@@ -20,6 +20,7 @@
#include "stringify.hh"
#include "config_file.hh"
+#include "fs_entry.hh"
#include <test/test_framework.hh>
#include <test/test_runner.hh>
#include <sstream>
@@ -45,6 +46,12 @@ class TestFile : protected ConfigFile
need_lines();
}
+ TestFile(const std::string & filename) :
+ ConfigFile(filename)
+ {
+ need_lines();
+ }
+
mutable std::vector<std::string> lines;
protected:
@@ -87,5 +94,34 @@ namespace test_cases
TEST_CHECK_EQUAL(f.lines.at(3), "four four");
}
} test_config_file;
+
+ /**
+ * \test Test ConfigFile with file opening.
+ *
+ * \ingroup Test
+ */
+ struct ConfigFileOpenFileTest : TestCase
+ {
+ ConfigFileOpenFileTest() : TestCase("config file open file") { }
+
+ void run()
+ {
+ FSEntry ff("config_file_TEST_dir/config_file");
+ TEST_CHECK(ff.is_regular_file());
+ TestFile f(ff);
+ TEST_CHECK_EQUAL(f.lines.size(), 1);
+ TEST_CHECK_EQUAL(f.lines.at(0), "I am a fish.");
+
+ FSEntry ff2("config_file_TEST_dir/not_a_config_file");
+ TEST_CHECK(! ff2.exists());
+ TestFile * f2;
+ TEST_CHECK_THROWS(f2 = new TestFile(ff2), ConfigFileError);
+
+ FSEntry ff3("config_file_TEST_dir/unreadable_file");
+ TEST_CHECK(ff3.is_regular_file());
+ TestFile * f3;
+ TEST_CHECK_THROWS(f3 = new TestFile(ff3), ConfigFileError);
+ }
+ } test_config_file_open_file;
}
diff --git a/paludis/config_file_TEST_cleanup.sh b/paludis/config_file_TEST_cleanup.sh
new file mode 100755
index 0000000..d2f0bd8
--- /dev/null
+++ b/paludis/config_file_TEST_cleanup.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d config_file_TEST_dir ] ; then
+ rm -fr config_file_TEST_dir
+else
+ true
+fi
+
+
diff --git a/paludis/config_file_TEST_setup.sh b/paludis/config_file_TEST_setup.sh
new file mode 100755
index 0000000..766011d
--- /dev/null
+++ b/paludis/config_file_TEST_setup.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir config_file_TEST_dir || exit 2
+cd config_file_TEST_dir || exit 3
+echo "I am a fish." > config_file || exit 4
+echo "I am a fish too." > unreadable_file || exit 5
+chmod a-r unreadable_file || exit 6
+
diff --git a/paludis/config_file_error.cc b/paludis/config_file_error.cc
deleted file mode 100644
index 1dd881b..0000000
--- a/paludis/config_file_error.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@gentoo.org>
- *
- * 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 as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * 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 "config_file_error.hh"
-
-using namespace paludis;
-
-ConfigFileError::ConfigFileError(const std::string & message) throw () :
- Exception("Config file error: " + message)
-{
-}
-
diff --git a/paludis/config_file_error.hh b/paludis/config_file_error.hh
deleted file mode 100644
index f14534c..0000000
--- a/paludis/config_file_error.hh
+++ /dev/null
@@ -1,44 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@gentoo.org>
- *
- * 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 as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * 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_CONFIG_FILE_ERROR_HH
-#define PALUDIS_GUARD_PALUDIS_CONFIG_FILE_ERROR_HH 1
-
-#include <paludis/exception.hh>
-
-namespace paludis
-{
- /**
- * Thrown if an error occurs when reading a ConfigFile.
- *
- * \ingroup Exception
- * \ingroup ConfigFile
- */
- class ConfigFileError : public Exception
- {
- public:
- /**
- * Constructor.
- */
- ConfigFileError(const std::string & message) throw ();
- };
-}
-
-#endif
diff --git a/paludis/default_config.cc b/paludis/default_config.cc
index fc14db7..0237832 100644
--- a/paludis/default_config.cc
+++ b/paludis/default_config.cc
@@ -70,11 +70,7 @@ DefaultConfig::DefaultConfig()
{
Context local_context("When reading repository file '" + stringify(*repo_file) + "':");
- std::ifstream kf(stringify(*repo_file).c_str());
- if (! kf)
- throw DefaultConfigError("Couldn't open " + stringify(*repo_file));
-
- KeyValueConfigFile k(&kf);
+ KeyValueConfigFile k(*repo_file);
if (k.get("location").empty())
throw DefaultConfigError("Key 'location' empty or not specified in " +
@@ -114,11 +110,7 @@ DefaultConfig::DefaultConfig()
if (! file->is_regular_file())
continue;
- std::ifstream kf(stringify(*file).c_str());
- if (! kf)
- throw DefaultConfigError("Couldn't open " + stringify(*file));
-
- LineConfigFile f(&kf);
+ LineConfigFile f(*file);
for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
line != line_end ; ++line)
{
@@ -164,11 +156,7 @@ DefaultConfig::DefaultConfig()
if (! file->is_regular_file())
continue;
- std::ifstream kf(stringify(*file).c_str());
- if (! kf)
- throw DefaultConfigError("Couldn't open " + stringify(*file));
-
- LineConfigFile f(&kf);
+ LineConfigFile f(*file);
for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
line != line_end ; ++line)
{
@@ -198,11 +186,7 @@ DefaultConfig::DefaultConfig()
if (! file->is_regular_file())
continue;
- std::ifstream kf(stringify(*file).c_str());
- if (! kf)
- throw DefaultConfigError("Couldn't open " + stringify(*file));
-
- LineConfigFile f(&kf);
+ LineConfigFile f(*file);
for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
line != line_end ; ++line)
{
@@ -232,11 +216,7 @@ DefaultConfig::DefaultConfig()
if (! file->is_regular_file())
continue;
- std::ifstream kf(stringify(*file).c_str());
- if (! kf)
- throw DefaultConfigError("Couldn't open " + stringify(*file));
-
- LineConfigFile f(&kf);
+ LineConfigFile f(*file);
for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
line != line_end ; ++line)
{
diff --git a/paludis/files.m4 b/paludis/files.m4
index c527046..0abc353 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -23,8 +23,7 @@ add(`circular_dependency_error', `hh', `cc')
add(`comparison_policy', `hh', `cc', `test')
add(`composite_dep_atom', `hh', `cc')
add(`composite_pattern', `hh', `cc')
-add(`config_file', `hh', `cc', `test')
-add(`config_file_error', `hh', `cc')
+add(`config_file', `hh', `cc', `test', `testscript')
add(`configuration_error', `hh', `cc')
add(`container_entry', `hh', `cc', `test')
add(`counted_ptr', `hh', `cc', `test')
diff --git a/paludis/key_value_config_file.cc b/paludis/key_value_config_file.cc
index 468728b..80006e5 100644
--- a/paludis/key_value_config_file.cc
+++ b/paludis/key_value_config_file.cc
@@ -29,6 +29,11 @@ KeyValueConfigFile::KeyValueConfigFile(std::istream * const s) :
need_lines();
}
+KeyValueConfigFile::KeyValueConfigFile(const std::string & filename) :
+ ConfigFile(filename)
+{
+}
+
KeyValueConfigFile::~KeyValueConfigFile()
{
}
diff --git a/paludis/key_value_config_file.hh b/paludis/key_value_config_file.hh
index 8f6f2e1..67858d3 100644
--- a/paludis/key_value_config_file.hh
+++ b/paludis/key_value_config_file.hh
@@ -54,6 +54,8 @@ namespace paludis
public:
KeyValueConfigFile(std::istream * const);
+ KeyValueConfigFile(const std::string & filename);
+
~KeyValueConfigFile();
typedef std::map<std::string, std::string>::const_iterator Iterator;
diff --git a/paludis/line_config_file.cc b/paludis/line_config_file.cc
index 46f760b..a96ca87 100644
--- a/paludis/line_config_file.cc
+++ b/paludis/line_config_file.cc
@@ -28,6 +28,11 @@ LineConfigFile::LineConfigFile(std::istream * const s) :
need_lines();
}
+LineConfigFile::LineConfigFile(const std::string & filename) :
+ ConfigFile(filename)
+{
+}
+
void
LineConfigFile::accept_line(const std::string & s) const
{
diff --git a/paludis/line_config_file.hh b/paludis/line_config_file.hh
index 8f6b9ac..1898efd 100644
--- a/paludis/line_config_file.hh
+++ b/paludis/line_config_file.hh
@@ -49,6 +49,8 @@ namespace paludis
public:
LineConfigFile(std::istream * const);
+ LineConfigFile(const std::string & filename);
+
typedef std::list<std::string>::const_iterator Iterator;
Iterator begin() const
diff --git a/paludis/portage_repository.cc b/paludis/portage_repository.cc
index c4e80e7..d5909af 100644
--- a/paludis/portage_repository.cc
+++ b/paludis/portage_repository.cc
@@ -118,10 +118,7 @@ Implementation<PortageRepository>::add_profile(const FSEntry & f) const
if ((f / "parent").exists())
{
- std::ifstream parent_file(stringify(f / "parent").c_str());
- if (! parent_file)
- throw InternalError(PALUDIS_HERE, "todo"); /// \bug exception
- LineConfigFile parent(&parent_file);
+ LineConfigFile parent(f / "parent");
if (parent.begin() != parent.end())
add_profile((f / *parent.begin()).realpath());
else
@@ -132,10 +129,7 @@ Implementation<PortageRepository>::add_profile(const FSEntry & f) const
{
static Tokeniser<delim_kind::AnyOfTag, delim_mode::DelimiterTag> tokeniser(" \t\n");
- std::ifstream make_defaults_file(stringify(f / "make.defaults").c_str());
- if (! make_defaults_file)
- throw InternalError(PALUDIS_HERE, "todo"); /// \bug exception
- KeyValueConfigFile make_defaults_f(&make_defaults_file);
+ KeyValueConfigFile make_defaults_f(f / "make.defaults");
std::vector<std::string> uses;
tokeniser.tokenise(make_defaults_f.get("USE"), std::back_inserter(uses));
for (std::vector<std::string>::const_iterator u(uses.begin()), u_end(uses.end()) ;
@@ -150,10 +144,7 @@ Implementation<PortageRepository>::add_profile(const FSEntry & f) const
if ((f / "use.mask").exists())
{
- std::ifstream use_mask_file(stringify(f / "use.mask").c_str());
- if (! use_mask_file)
- throw InternalError(PALUDIS_HERE, "todo"); /// \bug exception
- LineConfigFile use_mask_f(&use_mask_file);
+ LineConfigFile use_mask_f(f / "use.mask");
for (LineConfigFile::Iterator line(use_mask_f.begin()), line_end(use_mask_f.end()) ;
line != line_end ; ++line)
if ('-' == line->at(0))
@@ -295,13 +286,7 @@ PortageRepository::need_category_names() const
Context context("When loading category names for " + stringify(name()) + ":");
- std::ifstream cat_file(stringify(_implementation->location /
- "profiles/categories").c_str());
-
- if (! cat_file)
- throw InternalError(PALUDIS_HERE, "todo"); /// \bug real exception needed
-
- LineConfigFile cats(&cat_file);
+ LineConfigFile cats(_implementation->location / "profiles" / "categories");
for (LineConfigFile::Iterator line(cats.begin()), line_end(cats.end()) ;
line != line_end ; ++line)
@@ -358,8 +343,7 @@ PortageRepository::fetch_repo_name(const std::string & location)
if (! name_file.is_regular_file())
break;
- std::ifstream file(std::string(name_file).c_str());
- LineConfigFile f(&file);
+ LineConfigFile f(name_file);
if (f.begin() == f.end())
break;
return RepositoryName(*f.begin());
@@ -435,10 +419,7 @@ PortageRepository::do_query_repository_masks(const CategoryNamePart & c,
Context context("When querying repository mask for '" + stringify(c) + "/" + stringify(p) + "-"
+ stringify(v) + "':");
- std::ifstream f(stringify(_implementation->location / "profiles" / "package.mask").c_str());
- if (! f)
- throw InternalError(PALUDIS_HERE, "todo"); /// \bug exception
- LineConfigFile ff(&f);
+ LineConfigFile ff(_implementation->location / "profiles" / "package.mask");
for (LineConfigFile::Iterator line(ff.begin()), line_end(ff.end()) ;
line != line_end ; ++line)
{