output.hh revision 11359
11388SN/A/* 211359Sandreas@sandberg.pp.se * Copyright (c) 2015 ARM Limited 311359Sandreas@sandberg.pp.se * All rights reserved 411359Sandreas@sandberg.pp.se * 511359Sandreas@sandberg.pp.se * The license below extends only to copyright in the software and shall 611359Sandreas@sandberg.pp.se * not be construed as granting a license to any other intellectual 711359Sandreas@sandberg.pp.se * property including but not limited to intellectual property relating 811359Sandreas@sandberg.pp.se * to a hardware implementation of the functionality of the software 911359Sandreas@sandberg.pp.se * licensed hereunder. You may use the software subject to the license 1011359Sandreas@sandberg.pp.se * terms below provided that you ensure that this notice is replicated 1111359Sandreas@sandberg.pp.se * unmodified and in its entirety in all distributions of the software, 1211359Sandreas@sandberg.pp.se * modified or unmodified, in source code or in binary form. 1311359Sandreas@sandberg.pp.se * 1411359Sandreas@sandberg.pp.se * Copyright (c) 2013 Andreas Sandberg 151388SN/A * Copyright (c) 2005 The Regents of The University of Michigan 161388SN/A * All rights reserved. 171388SN/A * 181388SN/A * Redistribution and use in source and binary forms, with or without 191388SN/A * modification, are permitted provided that the following conditions are 201388SN/A * met: redistributions of source code must retain the above copyright 211388SN/A * notice, this list of conditions and the following disclaimer; 221388SN/A * redistributions in binary form must reproduce the above copyright 231388SN/A * notice, this list of conditions and the following disclaimer in the 241388SN/A * documentation and/or other materials provided with the distribution; 251388SN/A * neither the name of the copyright holders nor the names of its 261388SN/A * contributors may be used to endorse or promote products derived from 271388SN/A * this software without specific prior written permission. 281388SN/A * 291388SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 301388SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 311388SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 321388SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 331388SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 341388SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 351388SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 361388SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 371388SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 381388SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 391388SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 428634Schris.emmons@arm.com * Chris Emmons 4311359Sandreas@sandberg.pp.se * Andreas Sandberg 4411359Sandreas@sandberg.pp.se * Sascha Bischoff 451388SN/A */ 461388SN/A 471388SN/A#ifndef __BASE_OUTPUT_HH__ 481388SN/A#define __BASE_OUTPUT_HH__ 491388SN/A 505749Scws3k@cs.virginia.edu#include <ios> 511388SN/A#include <map> 521388SN/A#include <string> 531388SN/A 5411359Sandreas@sandberg.pp.se#include "base/compiler.hh" 5511359Sandreas@sandberg.pp.se 5611359Sandreas@sandberg.pp.seclass OutputDirectory; 5711359Sandreas@sandberg.pp.se 5811359Sandreas@sandberg.pp.seclass OutputStream 5911359Sandreas@sandberg.pp.se{ 6011359Sandreas@sandberg.pp.se public: 6111359Sandreas@sandberg.pp.se virtual ~OutputStream(); 6211359Sandreas@sandberg.pp.se 6311359Sandreas@sandberg.pp.se /** Get the output underlying output stream */ 6411359Sandreas@sandberg.pp.se std::ostream *stream() const { return _stream; }; 6511359Sandreas@sandberg.pp.se 6611359Sandreas@sandberg.pp.se /** 6711359Sandreas@sandberg.pp.se * Can the file be recreated if the output directory is moved? 6811359Sandreas@sandberg.pp.se * 6911359Sandreas@sandberg.pp.se * @return true if the file will be created in the new location, 7011359Sandreas@sandberg.pp.se * false otherwise. 7111359Sandreas@sandberg.pp.se */ 7211359Sandreas@sandberg.pp.se virtual bool recreateable() const { return false; } 7311359Sandreas@sandberg.pp.se 7411359Sandreas@sandberg.pp.se /** Get the file name in the output directory */ 7511359Sandreas@sandberg.pp.se const std::string &name() const { return _name; } 7611359Sandreas@sandberg.pp.se 7711359Sandreas@sandberg.pp.se protected: 7811359Sandreas@sandberg.pp.se friend class OutputDirectory; 7911359Sandreas@sandberg.pp.se 8011359Sandreas@sandberg.pp.se /** Wrap an existing stream */ 8111359Sandreas@sandberg.pp.se OutputStream(const std::string &name, 8211359Sandreas@sandberg.pp.se std::ostream *stream); 8311359Sandreas@sandberg.pp.se 8411359Sandreas@sandberg.pp.se /* Prevent copying */ 8511359Sandreas@sandberg.pp.se OutputStream(const OutputStream &f); 8611359Sandreas@sandberg.pp.se 8711359Sandreas@sandberg.pp.se /** Re-create the in a new location if recreateable. */ 8811359Sandreas@sandberg.pp.se virtual void relocate(const OutputDirectory &dir); 8911359Sandreas@sandberg.pp.se 9011359Sandreas@sandberg.pp.se /** Name in output directory */ 9111359Sandreas@sandberg.pp.se const std::string _name; 9211359Sandreas@sandberg.pp.se 9311359Sandreas@sandberg.pp.se /** Underlying output stream */ 9411359Sandreas@sandberg.pp.se std::ostream *const _stream; 9511359Sandreas@sandberg.pp.se}; 9611359Sandreas@sandberg.pp.se 9711359Sandreas@sandberg.pp.setemplate<class StreamType> 9811359Sandreas@sandberg.pp.seclass OutputFile 9911359Sandreas@sandberg.pp.se : public OutputStream 10011359Sandreas@sandberg.pp.se{ 10111359Sandreas@sandberg.pp.se public: 10211359Sandreas@sandberg.pp.se typedef StreamType stream_type_t; 10311359Sandreas@sandberg.pp.se 10411359Sandreas@sandberg.pp.se virtual ~OutputFile(); 10511359Sandreas@sandberg.pp.se 10611359Sandreas@sandberg.pp.se /** 10711359Sandreas@sandberg.pp.se * Can the file be recreated if the output directory is moved? 10811359Sandreas@sandberg.pp.se * 10911359Sandreas@sandberg.pp.se * @return true if the file will be created in the new location, 11011359Sandreas@sandberg.pp.se * false otherwise. 11111359Sandreas@sandberg.pp.se */ 11211359Sandreas@sandberg.pp.se bool recreateable() const override { return _recreateable; } 11311359Sandreas@sandberg.pp.se 11411359Sandreas@sandberg.pp.se protected: 11511359Sandreas@sandberg.pp.se friend class OutputDirectory; 11611359Sandreas@sandberg.pp.se 11711359Sandreas@sandberg.pp.se OutputFile(const OutputDirectory &dir, 11811359Sandreas@sandberg.pp.se const std::string &name, 11911359Sandreas@sandberg.pp.se std::ios_base::openmode mode, 12011359Sandreas@sandberg.pp.se bool recreateable); 12111359Sandreas@sandberg.pp.se 12211359Sandreas@sandberg.pp.se /* Prevent copying */ 12311359Sandreas@sandberg.pp.se OutputFile(const OutputFile<StreamType> &f); 12411359Sandreas@sandberg.pp.se 12511359Sandreas@sandberg.pp.se /** Re-create the file in a new location if it is relocatable. */ 12611359Sandreas@sandberg.pp.se void relocate(const OutputDirectory &dir) override; 12711359Sandreas@sandberg.pp.se 12811359Sandreas@sandberg.pp.se /** File mode when opened */ 12911359Sandreas@sandberg.pp.se const std::ios_base::openmode _mode; 13011359Sandreas@sandberg.pp.se 13111359Sandreas@sandberg.pp.se /** Can the file be recreated in a new location? */ 13211359Sandreas@sandberg.pp.se const bool _recreateable; 13311359Sandreas@sandberg.pp.se 13411359Sandreas@sandberg.pp.se /** Pointer to the file stream */ 13511359Sandreas@sandberg.pp.se stream_type_t *const _fstream; 13611359Sandreas@sandberg.pp.se}; 13711359Sandreas@sandberg.pp.se 1388634Schris.emmons@arm.com/** Interface for creating files in a gem5 output directory. */ 1391388SN/Aclass OutputDirectory 1401388SN/A{ 1411388SN/A private: 1428634Schris.emmons@arm.com /** File names and associated stream handles */ 14311359Sandreas@sandberg.pp.se typedef std::map<std::string, OutputStream *> file_map_t; 14411359Sandreas@sandberg.pp.se 14511359Sandreas@sandberg.pp.se /** Output subdirectories */ 14611359Sandreas@sandberg.pp.se typedef std::map<std::string, OutputDirectory *> dir_map_t; 1471388SN/A 1488634Schris.emmons@arm.com /** Open file streams within this directory */ 14911359Sandreas@sandberg.pp.se file_map_t files; 15011359Sandreas@sandberg.pp.se 15111359Sandreas@sandberg.pp.se /** Output sub-directories */ 15211359Sandreas@sandberg.pp.se dir_map_t dirs; 1538634Schris.emmons@arm.com 1548634Schris.emmons@arm.com /** Name of this directory */ 1551388SN/A std::string dir; 1561388SN/A 1578634Schris.emmons@arm.com /** System-specific path separator character */ 1588634Schris.emmons@arm.com static const char PATH_SEPARATOR = '/'; 1598634Schris.emmons@arm.com 16011359Sandreas@sandberg.pp.se static OutputStream stdout; 16111359Sandreas@sandberg.pp.se static OutputStream stderr; 16211359Sandreas@sandberg.pp.se 1635749Scws3k@cs.virginia.edu protected: 1648634Schris.emmons@arm.com /** 1658634Schris.emmons@arm.com * Determines whether given file name corresponds to standard output 1668634Schris.emmons@arm.com * streams. 1678634Schris.emmons@arm.com * 1688634Schris.emmons@arm.com * @param name name of file to check 1698634Schris.emmons@arm.com * @return output stream for standard output or error stream if name 1708634Schris.emmons@arm.com * corresponds to one or the other; NULL otherwise 1718634Schris.emmons@arm.com */ 17211359Sandreas@sandberg.pp.se static OutputStream *checkForStdio(const std::string &name); 1738634Schris.emmons@arm.com 1748734Sdam.sunwoo@arm.com public: 1758734Sdam.sunwoo@arm.com /** Constructor. */ 1768734Sdam.sunwoo@arm.com OutputDirectory(); 1778734Sdam.sunwoo@arm.com 17811359Sandreas@sandberg.pp.se /** Constructor. */ 17911359Sandreas@sandberg.pp.se OutputDirectory(const std::string &name); 18011359Sandreas@sandberg.pp.se 1818734Sdam.sunwoo@arm.com /** Destructor. */ 1828734Sdam.sunwoo@arm.com ~OutputDirectory(); 1838734Sdam.sunwoo@arm.com 1849398Sandreas.hansson@arm.com /** 1859398Sandreas.hansson@arm.com * Returns relative file names prepended with name of this directory. 1869398Sandreas.hansson@arm.com * Returns absolute file names unaltered. 1879398Sandreas.hansson@arm.com * 1889398Sandreas.hansson@arm.com * @param name file name to prepend with directory name 1899398Sandreas.hansson@arm.com * @return file name prepended with base directory name or unaltered 1909398Sandreas.hansson@arm.com * absolute file name 1919398Sandreas.hansson@arm.com */ 1929398Sandreas.hansson@arm.com std::string resolve(const std::string &name) const; 1939398Sandreas.hansson@arm.com 1948634Schris.emmons@arm.com /** 1958634Schris.emmons@arm.com * Sets name of this directory. 1968634Schris.emmons@arm.com * @param dir name of this directory 1978634Schris.emmons@arm.com */ 1981388SN/A void setDirectory(const std::string &dir); 1998634Schris.emmons@arm.com 2008634Schris.emmons@arm.com /** 2018634Schris.emmons@arm.com * Gets name of this directory. 2028634Schris.emmons@arm.com * @return name of this directory 2038634Schris.emmons@arm.com */ 2045749Scws3k@cs.virginia.edu const std::string &directory() const; 2051388SN/A 2068634Schris.emmons@arm.com /** 2078634Schris.emmons@arm.com * Creates a file in this directory (optionally compressed). 2088634Schris.emmons@arm.com * 20911359Sandreas@sandberg.pp.se * Will open a file as a compressed stream if filename ends in .gz, unless 21011359Sandreas@sandberg.pp.se * explicitly disabled. 21111359Sandreas@sandberg.pp.se * 21211359Sandreas@sandberg.pp.se * Relative output paths will result in the creation of a 21311359Sandreas@sandberg.pp.se * recreateable (see OutputFile) output file in the current output 21411359Sandreas@sandberg.pp.se * directory. Files created with an absolute path will not be 21511359Sandreas@sandberg.pp.se * recreateable. 2168634Schris.emmons@arm.com * 2178634Schris.emmons@arm.com * @param name name of file to create (without this directory's name 2188634Schris.emmons@arm.com * leading it) 2198634Schris.emmons@arm.com * @param binary true to create a binary file; false otherwise 22011359Sandreas@sandberg.pp.se * @param no_gz true to disable opening the file as a gzip compressed output 22111359Sandreas@sandberg.pp.se * stream; false otherwise 22211359Sandreas@sandberg.pp.se * @return OutputStream instance representing the created file 2238634Schris.emmons@arm.com */ 22411359Sandreas@sandberg.pp.se OutputStream *create(const std::string &name, 22511359Sandreas@sandberg.pp.se bool binary = false, 22611259Ssascha.bischoff@ARM.com bool no_gz = false); 2271388SN/A 2288634Schris.emmons@arm.com /** 22911359Sandreas@sandberg.pp.se * Open a file in this directory (optionally compressed). 2308634Schris.emmons@arm.com * 23111359Sandreas@sandberg.pp.se * Will open a file as a compressed stream if filename ends in .gz, unless 23211359Sandreas@sandberg.pp.se * explicitly disabled. 2338634Schris.emmons@arm.com * 23411359Sandreas@sandberg.pp.se * @param filename file to open 23511359Sandreas@sandberg.pp.se * @param mode attributes to open file with 23611359Sandreas@sandberg.pp.se * @param recreateable Set to true if the file can be recreated in a new 23711359Sandreas@sandberg.pp.se * location. 23811359Sandreas@sandberg.pp.se * @param no_gz true to disable opening the file as a gzip compressed output 23911359Sandreas@sandberg.pp.se * stream; false otherwise 24011359Sandreas@sandberg.pp.se * @return OutputStream instance representing the opened file 2418634Schris.emmons@arm.com */ 24211359Sandreas@sandberg.pp.se OutputStream *open(const std::string &name, 24311359Sandreas@sandberg.pp.se std::ios_base::openmode mode, 24411359Sandreas@sandberg.pp.se bool recreateable = true, 24511359Sandreas@sandberg.pp.se bool no_gz = false); 2468634Schris.emmons@arm.com 2478634Schris.emmons@arm.com /** 24811359Sandreas@sandberg.pp.se * Closes an output file and free the corresponding OutputFile. 24911359Sandreas@sandberg.pp.se * 25011359Sandreas@sandberg.pp.se * The output file must have been opened by the same 25111359Sandreas@sandberg.pp.se * OutputDirectory instance as the one closing it, or sim will 25211359Sandreas@sandberg.pp.se * fail. 25311359Sandreas@sandberg.pp.se * 25411359Sandreas@sandberg.pp.se * @param file OutputStream instance in this OutputDirectory. 25511359Sandreas@sandberg.pp.se */ 25611359Sandreas@sandberg.pp.se void close(OutputStream *file); 25711359Sandreas@sandberg.pp.se 25811359Sandreas@sandberg.pp.se /** 25911359Sandreas@sandberg.pp.se * Finds stream associated with an open file or stdout/stderr. 26011359Sandreas@sandberg.pp.se * 2618634Schris.emmons@arm.com * @param name of file 2628634Schris.emmons@arm.com * @return stream to specified file or NULL if file does not exist 2638634Schris.emmons@arm.com */ 26411359Sandreas@sandberg.pp.se OutputStream *find(const std::string &name) const; 2658634Schris.emmons@arm.com 26611359Sandreas@sandberg.pp.se OutputStream *findOrCreate(const std::string &name, bool binary = false); 2678634Schris.emmons@arm.com 2688634Schris.emmons@arm.com /** 2698634Schris.emmons@arm.com * Determines whether a file name corresponds to a file in this directory. 2708634Schris.emmons@arm.com * @param name name of file to evaluate 2718634Schris.emmons@arm.com * @return true iff file has been opened in this directory or exists on the 2728634Schris.emmons@arm.com * file system within this directory 2738634Schris.emmons@arm.com */ 2748634Schris.emmons@arm.com bool isFile(const std::string &name) const; 2758634Schris.emmons@arm.com 2768634Schris.emmons@arm.com /** 27711359Sandreas@sandberg.pp.se * Test if a path is absolute. 2788634Schris.emmons@arm.com */ 27911359Sandreas@sandberg.pp.se static inline bool isAbsolute(const std::string &name) { 28011359Sandreas@sandberg.pp.se return name[0] == PATH_SEPARATOR; 2818634Schris.emmons@arm.com } 2828634Schris.emmons@arm.com 2838634Schris.emmons@arm.com /** 2848634Schris.emmons@arm.com * Creates a subdirectory within this directory. 2858634Schris.emmons@arm.com * @param name name of subdirectory 2868634Schris.emmons@arm.com * @return the new subdirectory's name suffixed with a path separator 2878634Schris.emmons@arm.com */ 28811359Sandreas@sandberg.pp.se OutputDirectory *createSubdirectory(const std::string &name); 2898634Schris.emmons@arm.com 2908634Schris.emmons@arm.com /** 2918634Schris.emmons@arm.com * Removes a specified file or subdirectory. 2928634Schris.emmons@arm.com * 2938634Schris.emmons@arm.com * Will cause sim to fail for most errors. However, it will only warn the 2948634Schris.emmons@arm.com * user if a directory could not be removed. This is in place to 2958634Schris.emmons@arm.com * accommodate slow file systems where file deletions within a subdirectory 2968634Schris.emmons@arm.com * may not be recognized quickly enough thereby causing the subsequent call 2978634Schris.emmons@arm.com * to remove the directory to fail (seemingly unempty directory). 2988634Schris.emmons@arm.com * 2998634Schris.emmons@arm.com * @param name name of file or subdirectory to remove; name should not 3008634Schris.emmons@arm.com * be prepended with the name of this directory object 3018634Schris.emmons@arm.com * @param recursive set to true to attempt to recursively delete a 3028634Schris.emmons@arm.com * subdirectory and its contents 3038634Schris.emmons@arm.com */ 3048634Schris.emmons@arm.com void remove(const std::string &name, bool recursive=false); 3051388SN/A}; 3061388SN/A 3071388SN/Aextern OutputDirectory simout; 3081388SN/A 3091388SN/A#endif // __BASE_OUTPUT_HH__ 310