1/* 2 * Copyright (c) 2015 ARM Limited 3 * All rights reserved 4 * 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. 13 * 14 * Copyright (c) 2013 Andreas Sandberg 15 * Copyright (c) 2005 The Regents of The University of Michigan 16 * All rights reserved. 17 * 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. 28 * 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. 40 * 41 * Authors: Nathan Binkert 42 * Chris Emmons 43 * Andreas Sandberg 44 * Sascha Bischoff 45 */ 46 47#ifndef __BASE_OUTPUT_HH__ 48#define __BASE_OUTPUT_HH__ 49 50#include <ios> 51#include <map> 52#include <string> 53 54#include "base/compiler.hh" 55 56class OutputDirectory; 57 58class OutputStream 59{ 60 public: 61 virtual ~OutputStream(); 62 63 /** Get the output underlying output stream */ 64 std::ostream *stream() const { return _stream; }; 65 66 /** 67 * Can the file be recreated if the output directory is moved? 68 * 69 * @return true if the file will be created in the new location, 70 * false otherwise. 71 */ 72 virtual bool recreateable() const { return false; } 73 74 /** Get the file name in the output directory */ 75 const std::string &name() const { return _name; } 76 77 protected: 78 friend class OutputDirectory; 79 80 /** Wrap an existing stream */ 81 OutputStream(const std::string &name, 82 std::ostream *stream); 83 84 /* Prevent copying */ 85 OutputStream(const OutputStream &f); 86 87 /** Re-create the in a new location if recreateable. */ 88 virtual void relocate(const OutputDirectory &dir); 89 90 /** Name in output directory */ 91 const std::string _name; 92 93 /** Underlying output stream */ 94 std::ostream *const _stream; 95}; 96 97template<class StreamType> 98class OutputFile 99 : public OutputStream 100{ 101 public: 102 typedef StreamType stream_type_t; 103 104 virtual ~OutputFile(); 105 106 /** 107 * Can the file be recreated if the output directory is moved? 108 * 109 * @return true if the file will be created in the new location, 110 * false otherwise. 111 */ 112 bool recreateable() const override { return _recreateable; } 113 114 protected: 115 friend class OutputDirectory; 116 117 OutputFile(const OutputDirectory &dir, 118 const std::string &name, 119 std::ios_base::openmode mode, 120 bool recreateable); 121 122 /* Prevent copying */ 123 OutputFile(const OutputFile<StreamType> &f); 124 125 /** Re-create the file in a new location if it is relocatable. */ 126 void relocate(const OutputDirectory &dir) override; 127 128 /** File mode when opened */ 129 const std::ios_base::openmode _mode; 130 131 /** Can the file be recreated in a new location? */ 132 const bool _recreateable; 133 134 /** Pointer to the file stream */ 135 stream_type_t *const _fstream; 136}; 137 138/** Interface for creating files in a gem5 output directory. */ 139class OutputDirectory 140{ 141 private: 142 /** File names and associated stream handles */ 143 typedef std::map<std::string, OutputStream *> file_map_t; 144 145 /** Output subdirectories */ 146 typedef std::map<std::string, OutputDirectory *> dir_map_t; 147 148 /** Open file streams within this directory */ 149 file_map_t files; 150 151 /** Output sub-directories */ 152 dir_map_t dirs; 153 154 /** Name of this directory */ 155 std::string dir; 156 157 /** System-specific path separator character */ 158 static const char PATH_SEPARATOR = '/'; 159 160 static OutputStream stdout; 161 static OutputStream stderr; 162 163 protected: 164 /** 165 * Determines whether given file name corresponds to standard output 166 * streams. 167 * 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 171 */ 172 static OutputStream *checkForStdio(const std::string &name); 173 174 public: 175 /** Constructor. */ 176 OutputDirectory(); 177 178 /** Constructor. */ 179 OutputDirectory(const std::string &name); 180 181 /** Destructor. */ 182 ~OutputDirectory(); 183 184 /** 185 * Returns relative file names prepended with name of this directory. 186 * Returns absolute file names unaltered. 187 * 188 * @param name file name to prepend with directory name 189 * @return file name prepended with base directory name or unaltered 190 * absolute file name 191 */ 192 std::string resolve(const std::string &name) const; 193 194 /** 195 * Sets name of this directory. 196 * @param dir name of this directory 197 */ 198 void setDirectory(const std::string &dir); 199 200 /** 201 * Gets name of this directory. 202 * @return name of this directory 203 */ 204 const std::string &directory() const; 205 206 /** 207 * Creates a file in this directory (optionally compressed). 208 * 209 * Will open a file as a compressed stream if filename ends in .gz, unless 210 * explicitly disabled. 211 * 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 215 * recreateable. 216 * 217 * @param name name of file to create (without this directory's name 218 * leading it) 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 223 */ 224 OutputStream *create(const std::string &name, 225 bool binary = false, 226 bool no_gz = false); 227 228 /** 229 * Open a file in this directory (optionally compressed). 230 * 231 * Will open a file as a compressed stream if filename ends in .gz, unless 232 * explicitly disabled. 233 * 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 237 * location. 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 241 */ 242 OutputStream *open(const std::string &name, 243 std::ios_base::openmode mode, 244 bool recreateable = true, 245 bool no_gz = false); 246 247 /** 248 * Closes an output file and free the corresponding OutputFile. 249 * 250 * The output file must have been opened by the same 251 * OutputDirectory instance as the one closing it, or sim will 252 * fail. 253 * 254 * @param file OutputStream instance in this OutputDirectory. 255 */ 256 void close(OutputStream *file); 257 258 /** 259 * Finds stream associated with an open file or stdout/stderr. 260 * 261 * @param name of file 262 * @return stream to specified file or NULL if file does not exist 263 */ 264 OutputStream *find(const std::string &name) const; 265 266 OutputStream *findOrCreate(const std::string &name, bool binary = false); 267 268 /** 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 273 */ 274 bool isFile(const std::string &name) const; 275 276 /** 277 * Test if a path is absolute. 278 */ 279 static inline bool isAbsolute(const std::string &name) { 280 return name[0] == PATH_SEPARATOR; 281 } 282 283 /** 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 287 */ 288 OutputDirectory *createSubdirectory(const std::string &name); 289 290 /** 291 * Removes a specified file or subdirectory. 292 * 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). 298 * 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 303 */ 304 void remove(const std::string &name, bool recursive=false); 305}; 306 307extern OutputDirectory simout; 308 309#endif // __BASE_OUTPUT_HH__ 310