GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/options/open_ostream.cpp Lines: 2 31 6.5 %
Date: 2021-03-23 Branches: 3 76 3.9 %

Line Exec Source
1
/*********************                                                        */
2
/*! \file open_ostream.cpp
3
 ** \verbatim
4
 ** Top contributors (to current version):
5
 **   Morgan Deters, Tim King
6
 ** This file is part of the CVC4 project.
7
 ** Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 ** in the top-level source directory and their institutional affiliations.
9
 ** All rights reserved.  See the file COPYING in the top-level source
10
 ** directory for licensing information.\endverbatim
11
 **
12
 ** \brief [[ Add one-line brief description here ]]
13
 **
14
 ** [[ Add lengthier description here ]]
15
 ** \todo document this file
16
 **/
17
18
#include "options/open_ostream.h"
19
20
21
#include <cerrno>
22
#include <iostream>
23
#include <ostream>
24
#include <sstream>
25
#include <string>
26
#include <utility>
27
28
#include "lib/strtok_r.h"
29
#include "options/parser_options.h"
30
31
namespace CVC4 {
32
33
OstreamOpener::OstreamOpener(const char* channelName)
34
    : d_channelName(channelName)
35
    , d_specialCases()
36
{}
37
38
void OstreamOpener::addSpecialCase(const std::string& name, std::ostream* out){
39
  d_specialCases[name] = out;
40
}
41
42
43
44
std::pair< bool, std::ostream* > OstreamOpener::open(const std::string& optarg) const
45
{
46
  if(optarg == "") {
47
    std::stringstream ss;
48
    ss << "Bad file name setting for " << d_channelName;
49
    throw OptionException(ss.str());
50
  }
51
  if(d_specialCases.find(optarg) != d_specialCases.end()){
52
    return std::make_pair(false, (*d_specialCases.find(optarg)).second);
53
5688
  } else if(!options::filesystemAccess()) {
54
    throw OptionException(std::string("Filesystem access not permitted"));
55
  } else {
56
    errno = 0;
57
    std::ostream* outStream;
58
    outStream = new std::ofstream(optarg.c_str(),
59
                                    std::ofstream::out | std::ofstream::trunc);
60
    if(outStream == NULL || !*outStream) {
61
      std::stringstream ss;
62
      ss << "Cannot open " << d_channelName << " file: `"
63
         << optarg << "': " << cvc4_errno_failreason();
64
      throw OptionException(ss.str());
65
    }
66
    return make_pair(true, outStream);
67
  }
68
}
69
70
std::string cvc4_errno_failreason() {
71
#if HAVE_STRERROR_R
72
#if STRERROR_R_CHAR_P
73
  if(errno != 0) {
74
    // GNU version of strerror_r: *might* use the given buffer,
75
    // or might not.  It returns a pointer to buf, or not.
76
    char buf[80];
77
    return std::string(strerror_r(errno, buf, sizeof buf));
78
  } else {
79
    return "unknown reason";
80
  }
81
#else /* STRERROR_R_CHAR_P */
82
  if(errno != 0) {
83
    // XSI version of strerror_r: always uses the given buffer.
84
    // Returns an error code.
85
    char buf[80];
86
    if(strerror_r(errno, buf, sizeof buf) == 0) {
87
      return std::string(buf);
88
    } else {
89
      // some error occurred while getting the error string
90
      return "unknown reason";
91
    }
92
  } else {
93
    return "unknown reason";
94
  }
95
#endif /* STRERROR_R_CHAR_P */
96
#else /* HAVE_STRERROR_R */
97
  return "unknown reason";
98
#endif /* HAVE_STRERROR_R */
99
}
100
101
32373
}/* CVC4 namespace */