Line data Source code
1 : /*
2 : * DUNE DAQ modification notice:
3 : * This file has been modified from the original ATLAS ers source for the DUNE DAQ project.
4 : * Fork baseline commit: 8267df82a4f6fe6bf02c4014923eba19eddc4614 (2020-04-14).
5 : * Renamed since fork: yes (from src/Issue.cxx to src/Issue.cpp).
6 : *
7 : * Original copyright:
8 : * Copyright (C) 2001-2020 CERN for the benefit of the ATLAS collaboration.
9 : * Licensed under the Apache License, Version 2.0.
10 : */
11 :
12 : /*
13 : * Issue.cxx
14 : * ers
15 : *
16 : * Created by Matthias Wiesmann on 26.11.04.
17 : * Modified by Serguei Kolos on 02.08.05.
18 : * Copyright 2004 CERN. All rights reserved.
19 : *
20 : */
21 :
22 : #include <algorithm>
23 : #include <csignal>
24 : #include <ctime>
25 : #include <iomanip>
26 : #include <sstream>
27 : #include <time.h>
28 :
29 : #include <ers/Issue.hpp>
30 : #include <ers/IssueFactory.hpp>
31 : #include <ers/OutputStream.hpp>
32 : #include <ers/StandardStreamOutput.hpp>
33 : #include <ers/ers.hpp>
34 : #include <ers/internal/Util.hpp>
35 :
36 : using namespace ers;
37 :
38 82 : ERS_DECLARE_ISSUE(ers, StdIssue, ERS_EMPTY, ERS_EMPTY)
39 :
40 : namespace {
41 : int
42 3390 : get_default_qualifiers(std::vector<std::string>& qualifiers)
43 : {
44 3390 : static const char* environment = ::getenv("DUNEDAQ_ERS_QUALIFIERS");
45 3390 : if (environment) {
46 0 : ers::tokenize(environment, ",", qualifiers);
47 : }
48 3390 : return 1;
49 : }
50 :
51 : void
52 3390 : add_default_qualifiers(Issue& issue)
53 : {
54 3390 : static std::vector<std::string> qualifiers;
55 : // static int _unused_ = get_default_qualifiers( qualifiers );
56 3390 : get_default_qualifiers(qualifiers);
57 3390 : for (std::vector<std::string>::const_iterator it = qualifiers.begin(); it != qualifiers.end(); ++it) {
58 0 : issue.add_qualifier(*it);
59 : }
60 3390 : }
61 : }
62 :
63 75 : Issue::Issue(const Issue& other)
64 : : std::exception(other)
65 75 : , m_cause(other.m_cause.get() ? other.m_cause->clone() : 0)
66 75 : , m_context(other.m_context->clone())
67 75 : , m_message(other.m_message)
68 75 : , m_qualifiers(other.m_qualifiers)
69 75 : , m_severity(other.m_severity)
70 75 : , m_time(other.m_time)
71 150 : , m_values(other.m_values)
72 : {
73 75 : ;
74 75 : }
75 :
76 : /** This constructor create a new issue with the given message.
77 : * \param context the context of the Issue, e.g where in the code the issue appeared
78 : * \param message the user message associated with this issue
79 : */
80 3359 : Issue::Issue(const Context& context, const std::string& message)
81 3359 : : m_context(context.clone())
82 3359 : , m_message(message)
83 3359 : , m_severity(ers::Error)
84 10077 : , m_time(system_clock::now())
85 : {
86 3359 : add_qualifier(m_context->package_name());
87 3359 : add_default_qualifiers(*this);
88 3359 : }
89 :
90 : /** This constructor takes another exceptions as its cause.
91 : * \param context the context of the Issue, e.g where in the code the issue appeared
92 : * \param cause the other exception that has caused this one
93 : */
94 31 : Issue::Issue(const Context& context, const std::exception& cause)
95 31 : : m_context(context.clone())
96 31 : , m_severity(ers::Error)
97 93 : , m_time(system_clock::now())
98 : {
99 31 : const Issue* issue = dynamic_cast<const Issue*>(&cause);
100 31 : m_cause.reset(issue ? issue->clone() : new StdIssue(ERS_HERE, cause.what()));
101 31 : add_qualifier(m_context->package_name());
102 31 : add_default_qualifiers(*this);
103 31 : }
104 :
105 : /** This constructor takes another exceptions as its cause.
106 : * \param context the context of the Issue, e.g where in the code did the issue appear
107 : * \param message the user message associated with this issue
108 : * \param cause exception that caused the current issue
109 : */
110 0 : Issue::Issue(const Context& context, const std::string& message, const std::exception& cause)
111 0 : : m_context(context.clone())
112 0 : , m_message(message)
113 0 : , m_severity(ers::Error)
114 0 : , m_time(system_clock::now())
115 : {
116 0 : const Issue* issue = dynamic_cast<const Issue*>(&cause);
117 0 : m_cause.reset(issue ? issue->clone() : new StdIssue(ERS_HERE, cause.what()));
118 0 : add_qualifier(m_context->package_name());
119 0 : add_default_qualifiers(*this);
120 0 : }
121 :
122 0 : Issue::Issue(Severity severity,
123 : const system_clock::time_point& time,
124 : const ers::Context& context,
125 : const std::string& message,
126 : const std::vector<std::string>& qualifiers,
127 : const std::map<std::string, std::string>& parameters,
128 0 : const ers::Issue* cause)
129 0 : : m_cause(cause)
130 0 : , m_context(context.clone())
131 0 : , m_message(message)
132 0 : , m_qualifiers(qualifiers)
133 0 : , m_severity(severity)
134 0 : , m_time(time)
135 0 : , m_values(parameters)
136 : {
137 0 : ;
138 0 : }
139 :
140 3465 : ers::Issue::~Issue() noexcept
141 : {
142 3465 : ;
143 3465 : }
144 :
145 : std::time_t
146 1206 : ers::Issue::time_t() const
147 : {
148 1206 : return system_clock::to_time_t(m_time);
149 : }
150 :
151 : void
152 2 : ers::Issue::get_value(const std::string& key, const char*& value) const
153 : {
154 2 : string_map::const_iterator it = m_values.find(key);
155 2 : if (it != m_values.end()) {
156 2 : value = it->second.c_str();
157 : } else {
158 0 : throw ers::NoValue(ERS_HERE, key);
159 : }
160 2 : }
161 :
162 : void
163 0 : ers::Issue::get_value(const std::string& key, std::string& value) const
164 : {
165 0 : string_map::const_iterator it = m_values.find(key);
166 0 : if (it != m_values.end()) {
167 0 : value = it->second;
168 : } else {
169 0 : throw ers::NoValue(ERS_HERE, key);
170 : }
171 0 : }
172 :
173 : /** Add a new qualifier to the qualifiers list of this issue
174 : * \param qualifier the qualifier to add
175 : */
176 : void
177 3390 : Issue::add_qualifier(const std::string& qualifier)
178 : {
179 3390 : if (std::find(m_qualifiers.begin(), m_qualifiers.end(), qualifier) == m_qualifiers.end()) {
180 3390 : m_qualifiers.push_back(qualifier);
181 : }
182 3390 : }
183 :
184 : ers::Severity
185 2283 : Issue::set_severity(ers::Severity severity) const
186 : {
187 2283 : ers::Severity old_severity = m_severity;
188 2283 : m_severity = severity;
189 2283 : return old_severity;
190 : }
191 :
192 : /** Adds the given text to the beginning of the issue's message
193 : * \param msg text to be prepended
194 : */
195 : void
196 2407 : Issue::prepend_message(const std::string& msg)
197 : {
198 2407 : m_message = msg + m_message;
199 2407 : }
200 :
201 : /** Adds the given text strings to the beginning and to the end of the issue's message
202 : * \param begin text to be prepended
203 : * \param begin text to be appended
204 : */
205 : void
206 0 : Issue::wrap_message(const std::string& begin, const std::string& end)
207 : {
208 0 : m_message = begin + m_message + end;
209 0 : }
210 :
211 : namespace ers {
212 :
213 : /** Standard streaming operator - puts the issue in human readable format into the standard out stream.
214 : * \param out the destination out stream
215 : * \param issue the Issue to be printed
216 : */
217 : std::ostream&
218 4 : operator<<(std::ostream& out, const ers::Issue& issue)
219 : {
220 4 : return StandardStreamOutput::print(out, issue, ers::verbosity_level());
221 : }
222 : }
|