output.cc revision 4840
11388SN/A/*
21388SN/A * Copyright (c) 2005 The Regents of The University of Michigan
31388SN/A * All rights reserved.
41388SN/A *
51388SN/A * Redistribution and use in source and binary forms, with or without
61388SN/A * modification, are permitted provided that the following conditions are
71388SN/A * met: redistributions of source code must retain the above copyright
81388SN/A * notice, this list of conditions and the following disclaimer;
91388SN/A * redistributions in binary form must reproduce the above copyright
101388SN/A * notice, this list of conditions and the following disclaimer in the
111388SN/A * documentation and/or other materials provided with the distribution;
121388SN/A * neither the name of the copyright holders nor the names of its
131388SN/A * contributors may be used to endorse or promote products derived from
141388SN/A * this software without specific prior written permission.
151388SN/A *
161388SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171388SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181388SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191388SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201388SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211388SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221388SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231388SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241388SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251388SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261388SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
291388SN/A */
301388SN/A
311388SN/A#include <errno.h>
321388SN/A#include <limits.h>
331388SN/A#include <stdlib.h>
341388SN/A#include <sys/stat.h>
351388SN/A#include <sys/types.h>
361388SN/A
371388SN/A#include <fstream>
381388SN/A
391388SN/A#include "base/misc.hh"
401388SN/A#include "base/output.hh"
411388SN/A
421388SN/Ausing namespace std;
431388SN/A
441388SN/AOutputDirectory simout;
451388SN/A
461388SN/A/**
471388SN/A *
481388SN/A */
491388SN/AOutputDirectory::OutputDirectory()
501388SN/A{}
511388SN/A
521388SN/AOutputDirectory::~OutputDirectory()
531388SN/A{}
541388SN/A
551388SN/Avoid
561388SN/AOutputDirectory::setDirectory(const string &d)
571388SN/A{
581388SN/A    if (!dir.empty())
591388SN/A        panic("Output directory already set!\n");
601388SN/A
611388SN/A    dir = d;
621388SN/A
631388SN/A    if (dir != ".") {
641388SN/A        if (mkdir(dir.c_str(), 0777) < 0 && errno != EEXIST)
651388SN/A            panic("couldn't make output dir %s: %s\n",
661388SN/A                  dir, strerror(errno));
671388SN/A    }
681388SN/A
691388SN/A    // guarantee that directory ends with a '/'
701388SN/A    if (dir[dir.size() - 1] != '/')
711388SN/A        dir += "/";
721388SN/A}
731388SN/A
741388SN/Aconst string &
751388SN/AOutputDirectory::directory()
761388SN/A{
771388SN/A    if (dir.empty())
781388SN/A        panic("Output directory not set!");
791388SN/A
801388SN/A    return dir;
811388SN/A}
821388SN/A
831388SN/Astring
841388SN/AOutputDirectory::resolve(const string &name)
851388SN/A{
861388SN/A    return (name[0] != '/') ? dir + name : name;
871388SN/A}
881388SN/A
891388SN/Aostream *
904840Ssaidi@eecs.umich.eduOutputDirectory::create(const string &name, bool binary)
911388SN/A{
921388SN/A    if (name == "cerr" || name == "stderr")
931388SN/A        return &cerr;
941388SN/A
951388SN/A    if (name == "cout" || name == "stdout")
961388SN/A        return &cout;
971388SN/A
984840Ssaidi@eecs.umich.edu    ofstream *file = new ofstream(resolve(name).c_str(),
994840Ssaidi@eecs.umich.edu            ios::trunc | binary ?  ios::binary : (ios::openmode)0);
1001388SN/A    if (!file->is_open())
1011388SN/A        panic("Cannot open file %s", name);
1021388SN/A
1031388SN/A    return file;
1041388SN/A}
1051388SN/A
1061388SN/Aostream *
1071388SN/AOutputDirectory::find(const string &name)
1081388SN/A{
1091388SN/A    if (name == "cerr" || name == "stderr")
1101388SN/A        return &cerr;
1111388SN/A
1121388SN/A    if (name == "cout" || name == "stdout")
1131388SN/A        return &cout;
1141388SN/A
1151388SN/A    string filename = resolve(name);
1161388SN/A    map_t::iterator i = files.find(filename);
1171388SN/A    if (i != files.end())
1181388SN/A        return (*i).second;
1191388SN/A
1201388SN/A    ofstream *file = new ofstream(filename.c_str(), ios::trunc);
1211388SN/A    if (!file->is_open())
1221388SN/A        panic("Cannot open file %s", filename);
1231388SN/A
1241388SN/A    files[filename] = file;
1251388SN/A    return file;
1261388SN/A}
1271388SN/A
1281388SN/Abool
1291388SN/AOutputDirectory::isFile(const std::ostream *os)
1301388SN/A{
1311388SN/A    return os && os != &cerr && os != &cout;
1321388SN/A}
133