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

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