mirror of
https://github.com/moses-smt/mosesdecoder.git
synced 2024-10-05 15:58:03 +03:00
New helper classes: temp_dir & temp_file.
I'm adding these because boost::filesystem::unique_path introduces encoding issues: on Windows the path is in wchar_t, breaking use of those strings in various places! Encoding the strings is just too much work. It's still possible that the current temp_file implementation won't build on Windows (it uses POSIX mkstemp() and close()) but that can be fixed underneath the API.
This commit is contained in:
parent
c5e9a58ae2
commit
d56f317f2e
@ -1,11 +1,11 @@
|
||||
// vim:tabstop=2
|
||||
#include <cstdlib>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "PhraseDictionaryTransliteration.h"
|
||||
#include "moses/TranslationModel/CYKPlusParser/ChartRuleLookupManagerSkeleton.h"
|
||||
#include "moses/DecodeGraph.h"
|
||||
#include "moses/DecodeStep.h"
|
||||
#include "util/tempfile.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -70,11 +70,10 @@ void PhraseDictionaryTransliteration::GetTargetPhraseCollection(InputPath &input
|
||||
inputPath.SetTargetPhrases(*this, tpColl, NULL);
|
||||
} else {
|
||||
// TRANSLITERATE
|
||||
const boost::filesystem::path
|
||||
inFile = boost::filesystem::unique_path(),
|
||||
outDir = boost::filesystem::unique_path();
|
||||
const util::temp_file inFile;
|
||||
const util::temp_dir outDir;
|
||||
|
||||
ofstream inStream(inFile.c_str());
|
||||
ofstream inStream(inFile.path().c_str());
|
||||
inStream << sourcePhrase.ToString() << endl;
|
||||
inStream.close();
|
||||
|
||||
@ -84,14 +83,14 @@ void PhraseDictionaryTransliteration::GetTargetPhraseCollection(InputPath &input
|
||||
" --external-bin-dir " + m_externalDir +
|
||||
" --input-extension " + m_inputLang +
|
||||
" --output-extension " + m_outputLang +
|
||||
" --oov-file " + inFile.native() +
|
||||
" --out-dir " + outDir.native();
|
||||
" --oov-file " + inFile.path() +
|
||||
" --out-dir " + outDir.path();
|
||||
|
||||
int ret = system(cmd.c_str());
|
||||
UTIL_THROW_IF2(ret != 0, "Transliteration script error");
|
||||
|
||||
TargetPhraseCollection *tpColl = new TargetPhraseCollection();
|
||||
vector<TargetPhrase*> targetPhrases = CreateTargetPhrases(sourcePhrase, outDir.native());
|
||||
vector<TargetPhrase*> targetPhrases = CreateTargetPhrases(sourcePhrase, outDir.path());
|
||||
vector<TargetPhrase*>::const_iterator iter;
|
||||
for (iter = targetPhrases.begin(); iter != targetPhrases.end(); ++iter) {
|
||||
TargetPhrase *tp = *iter;
|
||||
@ -102,10 +101,6 @@ void PhraseDictionaryTransliteration::GetTargetPhraseCollection(InputPath &input
|
||||
cache[hash] = value;
|
||||
|
||||
inputPath.SetTargetPhrases(*this, tpColl, NULL);
|
||||
|
||||
// clean up temporary files
|
||||
remove(inFile.c_str());
|
||||
boost::filesystem::remove_all(outDir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,5 +32,5 @@ import testing ;
|
||||
run file_piece_test.o kenutil /top//boost_unit_test_framework : : file_piece.cc ;
|
||||
for local t in [ glob *_test.cc : file_piece_test.cc read_compressed_test.cc ] {
|
||||
local name = [ MATCH "(.*)\.cc" : $(t) ] ;
|
||||
unit-test $(name) : $(t) kenutil /top//boost_unit_test_framework /top//boost_system ;
|
||||
unit-test $(name) : $(t) kenutil /top//boost_unit_test_framework /top//boost_filesystem /top//boost_system ;
|
||||
}
|
||||
|
79
util/tempfile.hh
Normal file
79
util/tempfile.hh
Normal file
@ -0,0 +1,79 @@
|
||||
#ifndef UTIL_TEMPFILE_H
|
||||
#define UTIL_TEMPFILE_H
|
||||
|
||||
// Utilities for creating temporary files and directories.
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "util/exception.hh"
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
||||
/** Temporary directory.
|
||||
*
|
||||
* Automatically creates, and on destruction deletes, a temporary directory.
|
||||
* The actual directory in the filesystem will only exist while the temp_dir
|
||||
* object exists.
|
||||
*
|
||||
* If the directory no longer exists by the time the temp_dir is destroyed,
|
||||
* no cleanup happens.
|
||||
*/
|
||||
class temp_dir : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
temp_dir()
|
||||
{
|
||||
char buf[] = "tmpdir.XXXXXX";
|
||||
m_path = std::string(mkdtemp(buf));
|
||||
}
|
||||
|
||||
~temp_dir()
|
||||
{
|
||||
boost::filesystem::remove_all(path());
|
||||
}
|
||||
|
||||
/// Return the temporary directory's full path.
|
||||
const std::string &path() const { return m_path; }
|
||||
|
||||
private:
|
||||
std::string m_path;
|
||||
};
|
||||
|
||||
|
||||
/** Temporary file.
|
||||
*
|
||||
* Automatically creates, and on destruction deletes, a temporary file.
|
||||
*/
|
||||
class temp_file : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
temp_file()
|
||||
{
|
||||
char buf[] = "tmp.XXXXXX";
|
||||
const int fd = mkstemp(buf);
|
||||
if (fd == -1) throw ErrnoException();
|
||||
close(fd);
|
||||
m_path = buf;
|
||||
}
|
||||
|
||||
~temp_file()
|
||||
{
|
||||
boost::filesystem::remove(path());
|
||||
}
|
||||
|
||||
/// Return the temporary file's full path.
|
||||
const std::string &path() const { return m_path; }
|
||||
|
||||
private:
|
||||
std::string m_path;
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
|
||||
#endif
|
119
util/tempfile_test.cc
Normal file
119
util/tempfile_test.cc
Normal file
@ -0,0 +1,119 @@
|
||||
#include "util/tempfile.hh"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#define BOOST_TEST_MODULE TempFileTest
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace util
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_dir_has_path)
|
||||
{
|
||||
BOOST_CHECK(temp_dir().path().size() > 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_dir_creates_temp_directory)
|
||||
{
|
||||
const temp_dir t;
|
||||
BOOST_CHECK(boost::filesystem::exists(t.path()));
|
||||
BOOST_CHECK(boost::filesystem::is_directory(t.path()));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_dir_creates_unique_directory)
|
||||
{
|
||||
BOOST_CHECK(temp_dir().path() != temp_dir().path());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_dir_cleans_up_directory)
|
||||
{
|
||||
std::string path;
|
||||
{
|
||||
const temp_dir t;
|
||||
path = t.path();
|
||||
}
|
||||
BOOST_CHECK(!boost::filesystem::exists(path));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_dir_cleanup_succeeds_if_directory_contains_file)
|
||||
{
|
||||
std::string path;
|
||||
{
|
||||
const temp_dir t;
|
||||
path = t.path();
|
||||
boost::filesystem::create_directory(path + "/directory");
|
||||
std::ofstream file((path + "/file").c_str());
|
||||
file << "Text";
|
||||
file.flush();
|
||||
}
|
||||
BOOST_CHECK(!boost::filesystem::exists(path));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_dir_cleanup_succeeds_if_directory_is_gone)
|
||||
{
|
||||
std::string path;
|
||||
{
|
||||
const temp_dir t;
|
||||
path = t.path();
|
||||
boost::filesystem::remove_all(path);
|
||||
}
|
||||
BOOST_CHECK(!boost::filesystem::exists(path));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_file_has_path)
|
||||
{
|
||||
BOOST_CHECK(temp_file().path().size() > 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_file_creates_temp_file)
|
||||
{
|
||||
const temp_file f;
|
||||
BOOST_CHECK(boost::filesystem::exists(f.path()));
|
||||
BOOST_CHECK(boost::filesystem::is_regular_file(f.path()));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_file_creates_unique_file)
|
||||
{
|
||||
BOOST_CHECK(temp_file().path() != temp_file().path());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_file_creates_writable_file)
|
||||
{
|
||||
const std::string data = "Test-data-goes-here";
|
||||
const temp_file f;
|
||||
std::ofstream outfile(f.path().c_str());
|
||||
outfile << data;
|
||||
outfile.flush();
|
||||
std::string read_data;
|
||||
std::ifstream infile(f.path().c_str());
|
||||
infile >> read_data;
|
||||
BOOST_CHECK_EQUAL(data, read_data);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_file_cleans_up_file)
|
||||
{
|
||||
std::string path;
|
||||
{
|
||||
const temp_file f;
|
||||
path = f.path();
|
||||
}
|
||||
BOOST_CHECK(!boost::filesystem::exists(path));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(temp_file_cleanup_succeeds_if_file_is_gone)
|
||||
{
|
||||
std::string path;
|
||||
{
|
||||
const temp_file t;
|
||||
path = t.path();
|
||||
boost::filesystem::remove(path);
|
||||
}
|
||||
BOOST_CHECK(!boost::filesystem::exists(path));
|
||||
}
|
||||
|
||||
} // namespace anonymous
|
||||
} // namespace util
|
Loading…
Reference in New Issue
Block a user