2 * Copyright (c) 2015 ARM Limited
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Copyright (c) 2013 Andreas Sandberg
15 * Copyright (c) 2005 The Regents of The University of Michigan
16 * All rights reserved.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 * Authors: Nathan Binkert
47 #ifndef __BASE_OUTPUT_HH__
48 #define __BASE_OUTPUT_HH__
54 #include "base/compiler.hh"
56 class OutputDirectory;
61 virtual ~OutputStream();
63 /** Get the output underlying output stream */
64 std::ostream *stream() const { return _stream; };
67 * Can the file be recreated if the output directory is moved?
69 * @return true if the file will be created in the new location,
72 virtual bool recreateable() const { return false; }
74 /** Get the file name in the output directory */
75 const std::string &name() const { return _name; }
78 friend class OutputDirectory;
80 /** Wrap an existing stream */
81 OutputStream(const std::string &name,
82 std::ostream *stream);
85 OutputStream(const OutputStream &f);
87 /** Re-create the in a new location if recreateable. */
88 virtual void relocate(const OutputDirectory &dir);
90 /** Name in output directory */
91 const std::string _name;
93 /** Underlying output stream */
94 std::ostream *const _stream;
97 template<class StreamType>
102 typedef StreamType stream_type_t;
104 virtual ~OutputFile();
107 * Can the file be recreated if the output directory is moved?
109 * @return true if the file will be created in the new location,
112 bool recreateable() const override { return _recreateable; }
115 friend class OutputDirectory;
117 OutputFile(const OutputDirectory &dir,
118 const std::string &name,
119 std::ios_base::openmode mode,
122 /* Prevent copying */
123 OutputFile(const OutputFile<StreamType> &f);
125 /** Re-create the file in a new location if it is relocatable. */
126 void relocate(const OutputDirectory &dir) override;
128 /** File mode when opened */
129 const std::ios_base::openmode _mode;
131 /** Can the file be recreated in a new location? */
132 const bool _recreateable;
134 /** Pointer to the file stream */
135 stream_type_t *const _fstream;
138 /** Interface for creating files in a gem5 output directory. */
139 class OutputDirectory
142 /** File names and associated stream handles */
143 typedef std::map<std::string, OutputStream *> file_map_t;
145 /** Output subdirectories */
146 typedef std::map<std::string, OutputDirectory *> dir_map_t;
148 /** Open file streams within this directory */
151 /** Output sub-directories */
154 /** Name of this directory */
157 /** System-specific path separator character */
158 static const char PATH_SEPARATOR = '/';
160 static OutputStream stdout;
161 static OutputStream stderr;
165 * Determines whether given file name corresponds to standard output
168 * @param name name of file to check
169 * @return output stream for standard output or error stream if name
170 * corresponds to one or the other; NULL otherwise
172 static OutputStream *checkForStdio(const std::string &name);
179 OutputDirectory(const std::string &name);
185 * Returns relative file names prepended with name of this directory.
186 * Returns absolute file names unaltered.
188 * @param name file name to prepend with directory name
189 * @return file name prepended with base directory name or unaltered
192 std::string resolve(const std::string &name) const;
195 * Sets name of this directory.
196 * @param dir name of this directory
198 void setDirectory(const std::string &dir);
201 * Gets name of this directory.
202 * @return name of this directory
204 const std::string &directory() const;
207 * Creates a file in this directory (optionally compressed).
209 * Will open a file as a compressed stream if filename ends in .gz, unless
210 * explicitly disabled.
212 * Relative output paths will result in the creation of a
213 * recreateable (see OutputFile) output file in the current output
214 * directory. Files created with an absolute path will not be
217 * @param name name of file to create (without this directory's name
219 * @param binary true to create a binary file; false otherwise
220 * @param no_gz true to disable opening the file as a gzip compressed output
221 * stream; false otherwise
222 * @return OutputStream instance representing the created file
224 OutputStream *create(const std::string &name,
229 * Open a file in this directory (optionally compressed).
231 * Will open a file as a compressed stream if filename ends in .gz, unless
232 * explicitly disabled.
234 * @param filename file to open
235 * @param mode attributes to open file with
236 * @param recreateable Set to true if the file can be recreated in a new
238 * @param no_gz true to disable opening the file as a gzip compressed output
239 * stream; false otherwise
240 * @return OutputStream instance representing the opened file
242 OutputStream *open(const std::string &name,
243 std::ios_base::openmode mode,
244 bool recreateable = true,
248 * Closes an output file and free the corresponding OutputFile.
250 * The output file must have been opened by the same
251 * OutputDirectory instance as the one closing it, or sim will
254 * @param file OutputStream instance in this OutputDirectory.
256 void close(OutputStream *file);
259 * Finds stream associated with an open file or stdout/stderr.
261 * @param name of file
262 * @return stream to specified file or NULL if file does not exist
264 OutputStream *find(const std::string &name) const;
266 OutputStream *findOrCreate(const std::string &name, bool binary = false);
269 * Determines whether a file name corresponds to a file in this directory.
270 * @param name name of file to evaluate
271 * @return true iff file has been opened in this directory or exists on the
272 * file system within this directory
274 bool isFile(const std::string &name) const;
277 * Test if a path is absolute.
279 static inline bool isAbsolute(const std::string &name) {
280 return name[0] == PATH_SEPARATOR;
284 * Creates a subdirectory within this directory.
285 * @param name name of subdirectory
286 * @return the new subdirectory's name suffixed with a path separator
288 OutputDirectory *createSubdirectory(const std::string &name);
291 * Removes a specified file or subdirectory.
293 * Will cause sim to fail for most errors. However, it will only warn the
294 * user if a directory could not be removed. This is in place to
295 * accommodate slow file systems where file deletions within a subdirectory
296 * may not be recognized quickly enough thereby causing the subsequent call
297 * to remove the directory to fail (seemingly unempty directory).
299 * @param name name of file or subdirectory to remove; name should not
300 * be prepended with the name of this directory object
301 * @param recursive set to true to attempt to recursively delete a
302 * subdirectory and its contents
304 void remove(const std::string &name, bool recursive=false);
307 extern OutputDirectory simout;
309 #endif // __BASE_OUTPUT_HH__