1a2,14
> * Copyright (c) 2015 ARM Limited
> * All rights reserved
> *
> * The license below extends only to copyright in the software and shall
> * not be construed as granting a license to any other intellectual
> * property including but not limited to intellectual property relating
> * to a hardware implementation of the functionality of the software
> * licensed hereunder. You may use the software subject to the license
> * terms below provided that you ensure that this notice is replicated
> * unmodified and in its entirety in all distributions of the software,
> * modified or unmodified, in source code or in binary form.
> *
> * Copyright (c) 2013 Andreas Sandberg
29a43,44
> * Andreas Sandberg
> * Sascha Bischoff
51a67,115
>
> OutputStream::OutputStream(const std::string &name, std::ostream *stream)
> : _name(name), _stream(stream)
> {
> }
>
> OutputStream::~OutputStream()
> {
> }
>
> void
> OutputStream::relocate(const OutputDirectory &dir)
> {
> }
>
> template<class StreamType>
> OutputFile<StreamType>::OutputFile(const OutputDirectory &dir,
> const std::string &name,
> std::ios_base::openmode mode,
> bool recreateable)
> : OutputStream(name, new stream_type_t()),
> _mode(mode), _recreateable(recreateable),
> _fstream(static_cast<stream_type_t *>(_stream))
> {
> _fstream->open(dir.resolve(_name).c_str(), _mode);
>
> assert(_fstream->is_open());
> }
>
> template<class StreamType>
> OutputFile<StreamType>::~OutputFile()
> {
> if (_fstream->is_open())
> _fstream->close();
> }
>
> template<class StreamType>
> void
> OutputFile<StreamType>::relocate(const OutputDirectory &dir)
> {
> if (_recreateable) {
> _fstream->close();
> _fstream->open(dir.resolve(_name).c_str(), _mode);
> }
> }
>
> OutputStream OutputDirectory::stdout("stdout", &cout);
> OutputStream OutputDirectory::stderr("stderr", &cerr);
>
57a122,126
> OutputDirectory::OutputDirectory(const std::string &name)
> {
> setDirectory(name);
> }
>
60,62c129,131
< for (map_t::iterator i = files.begin(); i != files.end(); i++) {
< if (i->second)
< delete i->second;
---
> for (auto& f: files) {
> if (f.second)
> delete f.second;
66,67c135,136
< std::ostream *
< OutputDirectory::checkForStdio(const string &name) const
---
> OutputStream *
> OutputDirectory::checkForStdio(const string &name)
70c139
< return &cerr;
---
> return &stderr;
73c142
< return &cout;
---
> return &stdout;
78,100d146
< ostream *
< OutputDirectory::openFile(const string &filename,
< ios_base::openmode mode, bool no_gz)
< {
< bool gz = !no_gz;
< gz = gz && filename.find(".gz", filename.length()-3) < filename.length();
< if (gz) {
< gzofstream *file = new gzofstream(filename.c_str(), mode);
< if (!file->is_open())
< fatal("Cannot open file %s", filename);
< assert(files.find(filename) == files.end());
< files[filename] = file;
< return file;
< } else {
< ofstream *file = new ofstream(filename.c_str(), mode);
< if (!file->is_open())
< fatal("Cannot open file %s", filename);
< assert(files.find(filename) == files.end());
< files[filename] = file;
< return file;
< }
< }
<
102,122c148,150
< OutputDirectory::close(ostream *openStream) {
< map_t::iterator i;
< for (i = files.begin(); i != files.end(); i++) {
< if (i->second != openStream)
< continue;
<
< ofstream *fs = dynamic_cast<ofstream*>(i->second);
< if (fs) {
< fs->close();
< delete i->second;
< break;
< } else {
< gzofstream *gfs = dynamic_cast<gzofstream*>(i->second);
< if (gfs) {
< gfs->close();
< delete i->second;
< break;
< }
< }
< }
<
---
> OutputDirectory::close(OutputStream *file)
> {
> auto i = files.find(file->name());
126a155,156
>
> delete file;
132,133c162
< if (!dir.empty())
< panic("Output directory already set!\n");
---
> const string old_dir(dir);
139a169,187
>
> // Try to create the directory. If it already exists, that's ok;
> // otherwise, fail if we couldn't create it.
> if ((mkdir(dir.c_str(), 0755) != 0) && (errno != EEXIST))
> fatal("Failed to create new output subdirectory '%s'\n", dir);
>
> // Check if we need to recreate anything
> if (!old_dir.empty()) {
> // Recreate output files
> for (file_map_t::iterator i = files.begin(); i != files.end(); ++i) {
> i->second->relocate(*this);
> }
>
> // Relocate sub-directories
> for (dir_map_t::iterator i = dirs.begin(); i != dirs.end(); ++i) {
> i->second->setDirectory(dir + PATH_SEPARATOR + i->first);
> }
> }
>
154c202
< return (name[0] != PATH_SEPARATOR) ? dir + name : name;
---
> return !isAbsolute(name) ? dir + name : name;
157c205
< ostream *
---
> OutputStream *
160c208
< ostream *file = checkForStdio(name);
---
> OutputStream *file = checkForStdio(name);
164,167c212,214
< string filename = resolve(name);
< ios_base::openmode mode =
< ios::trunc | (binary ? ios::binary : (ios::openmode)0);
< file = openFile(filename, mode, no_gz);
---
> const ios_base::openmode mode(
> ios::trunc | (binary ? ios::binary : (ios::openmode)0));
> const bool recreateable(!isAbsolute(name));
169c216
< return file;
---
> return open(name, mode, recreateable, no_gz);
172c219,242
< ostream *
---
> OutputStream *
> OutputDirectory::open(const std::string &name,
> ios_base::openmode mode,
> bool recreateable,
> bool no_gz)
> {
> OutputStream *os;
>
> if (!no_gz && name.find(".gz", name.length() - 3) < name.length()) {
> // Although we are creating an output stream, we still need to pass the
> // correct mode for gzofstream as this used directly to set the file
> // mode.
> mode |= std::ios::out;
> os = new OutputFile<gzofstream>(*this, name, mode, recreateable);
> } else {
> os = new OutputFile<ofstream>(*this, name, mode, recreateable);
> }
>
> files[name] = os;
>
> return os;
> }
>
> OutputStream *
175c245
< ostream *file = checkForStdio(name);
---
> OutputStream *file = checkForStdio(name);
179,180c249
< const string filename = resolve(name);
< map_t::const_iterator i = files.find(filename);
---
> auto i = files.find(name);
187,188c256,258
< bool
< OutputDirectory::isFile(const std::ostream *os)
---
>
> OutputStream *
> OutputDirectory::findOrCreate(const std::string &name, bool binary)
190c260,264
< return os && os != &cerr && os != &cout;
---
> OutputStream *os(find(name));
> if (os)
> return os;
> else
> return create(name, binary);
204,205c278,279
< string
< OutputDirectory::createSubdirectory(const string &name) const
---
> OutputDirectory *
> OutputDirectory::createSubdirectory(const string &name)
211,213c285,286
< // if it already exists, that's ok; otherwise, fail if we couldn't create
< if ((mkdir(new_dir.c_str(), 0755) != 0) && (errno != EEXIST))
< fatal("Failed to create new output subdirectory '%s'\n", new_dir);
---
> OutputDirectory *dir(new OutputDirectory(new_dir));
> dirs[name] = dir;
215c288
< return name + PATH_SEPARATOR;
---
> return dir;
228,231c301,304
< map_t::iterator itr = files.find(fname);
< if (itr != files.end()) {
< delete itr->second;
< files.erase(itr);
---
> auto i = files.find(fname);
> if (i != files.end()) {
> delete i->second;
> files.erase(i);
249c322
< fname);
---
> fname);