1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_report.cpp -- Run-time logging and reporting facilities
23
24  Interface design by SystemC Verification Working Group.
25  Implementation by Alex Riesen, Synopsys Inc.
26  Original implementation by Martin Janssen, Synopsys Inc.
27  Reference implementation by Cadence Design Systems, Inc., 2002-09-23:
28  Norris Ip, Dean Shea, John Rose, Jasvinder Singh, William Paulsen,
29  John Pierce, Rachida Kebichi, Ted Elkind, David Bailey.
30
31  CHANGE LOG AT END OF FILE
32 *****************************************************************************/
33
34
35#include <stdlib.h>
36#include <string.h>
37
38#include "sysc/kernel/sc_process.h"
39#include "sysc/kernel/sc_simcontext_int.h"
40#include "sysc/utils/sc_stop_here.h"
41#include "sysc/utils/sc_report.h"
42#include "sysc/utils/sc_utils_ids.h"
43#include <algorithm> // std::swap
44
45namespace sc_core {
46
47
48static void sc_deprecated_report_ids(const char* method)
49{
50    static bool warn_report_ids_deprecated=true;
51    if ( warn_report_ids_deprecated )
52    {
53        std::string message;
54	message = "integer report ids are deprecated, use string values: ";
55	message += method;
56        warn_report_ids_deprecated=false;
57	SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_, message.c_str());
58    }
59}
60
61static char empty_str[] = "";
62static inline char * empty_dup(const char * p)
63{
64    if ( p && *p )
65    {
66        char* result;
67        result = (char*)malloc(strlen(p)+1);
68        strcpy(result, p);
69        return result;
70    }
71    else
72    {
73        return empty_str;
74    }
75}
76
77sc_report::sc_report()
78: severity(SC_INFO),
79  md(0),
80  msg(empty_dup(0)),
81  file(empty_dup(0)),
82  line(0),
83  timestamp(new sc_time(sc_time_stamp())),
84  process(0),
85  m_verbosity_level(SC_MEDIUM),
86  m_what(empty_dup(0))
87{
88}
89
90sc_report::sc_report(sc_severity severity_,
91		     const sc_msg_def* md_,
92		     const char* msg_,
93		     const char* file_,
94		     int line_,
95		     int verbosity_level)
96: severity(severity_),
97  md(md_),
98  msg(empty_dup(msg_)),
99  file(empty_dup(file_)),
100  line(line_),
101  timestamp(new sc_time(sc_time_stamp())),
102  process(sc_get_current_process_b()),
103  m_verbosity_level(verbosity_level),
104  m_what( empty_dup( sc_report_compose_message(*this).c_str() ) )
105{
106}
107
108sc_report::sc_report(const sc_report& other)
109: std::exception(other),
110  severity(other.severity),
111  md(other.md),
112  msg(empty_dup(other.msg)),
113  file(empty_dup(other.file)),
114  line(other.line),
115  timestamp(new sc_time(*other.timestamp)),
116  process(other.process),
117  m_verbosity_level(other.m_verbosity_level),
118  m_what(empty_dup(other.m_what))
119{
120}
121
122sc_report & sc_report::operator=(const sc_report& other)
123{
124    sc_report copy(other);
125    swap( copy );
126    return *this;
127}
128
129void
130sc_report::swap( sc_report & that )
131{
132    using std::swap;
133    swap( severity,          that.severity );
134    swap( md,                that.md );
135    swap( msg,               that.msg );
136    swap( file,              that.file );
137    swap( line,              that.line );
138    swap( timestamp,         that.timestamp );
139    swap( process,           that.process );
140    swap( m_verbosity_level, that.m_verbosity_level );
141    swap( m_what,            that.m_what );
142}
143
144sc_report::~sc_report() throw()
145{
146    if ( file != empty_str )
147	free(file);
148    if ( msg != empty_str )
149	free(msg);
150    delete timestamp;
151    if ( m_what != empty_str )
152    free(m_what);
153}
154
155const char * sc_report::get_msg_type() const
156{
157    return md->msg_type;
158}
159
160//
161// backward compatibility with 2.0+
162//
163
164static bool warnings_are_errors = false;
165static const char unknown_id[] = "unknown id";
166
167void sc_report_handler::report(sc_severity severity_,
168			       int         id_,
169			       const char* msg_,
170			       const char* file_,
171			       int         line_ )
172{
173    sc_msg_def * md = sc_report_handler::mdlookup(id_);
174
175    if ( !md )
176    {
177	md = sc_report_handler::add_msg_type(unknown_id);
178	md->id = id_;
179    }
180
181    if ( severity_ == SC_WARNING && warnings_are_errors )
182	severity_ = SC_ERROR;
183
184    sc_actions actions = execute(md, severity_);
185    sc_report rep(severity_, md, msg_, file_, line_);
186
187    if ( actions & SC_CACHE_REPORT )
188	cache_report(rep);
189
190    if ( severity_ == SC_ERROR )
191	actions |= SC_THROW;
192    else if ( severity_ == SC_FATAL )
193	actions |= SC_ABORT;
194
195    handler(rep, actions);
196}
197
198void sc_report::register_id( int id, const char* msg )
199{
200    sc_deprecated_report_ids("sc_report::register_id()");
201    if( id < 0 ) {
202	SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_,
203			 "invalid report id" );
204    }
205    if( msg == 0 ) {
206	SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_,
207			 "invalid report message" );
208    }
209    sc_msg_def * md = sc_report_handler::mdlookup(id);
210
211    if ( !md )
212	md = sc_report_handler::add_msg_type(msg);
213
214    if ( !md ) {
215	SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_,
216			 "report_map insertion error" );
217    }
218
219    if( md->id != -1 ) {
220	if( strcmp( msg, md->msg_type ) != 0 ) {
221	    SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_,
222			     "report id already exists" );
223	}
224	return;
225    }
226    md->id = id;
227}
228
229const char* sc_report::get_message( int id )
230{
231    sc_deprecated_report_ids("sc_report::get_message()");
232    sc_msg_def* md = sc_report_handler::mdlookup(id);
233
234    return md ? md->msg_type: unknown_id;
235}
236
237bool sc_report::is_suppressed( int id )
238{
239    sc_deprecated_report_ids("sc_report::is_suppressed()");
240    sc_msg_def* md = sc_report_handler::mdlookup(id);
241
242    return md ? md->actions == SC_DO_NOTHING: false; // only do-nothing set
243}
244
245void sc_report::suppress_id(int id_, bool suppress)
246{
247    sc_deprecated_report_ids("sc_report::suppress_id()");
248    sc_msg_def* md = sc_report_handler::mdlookup(id_);
249
250    if ( md )
251	md->actions = suppress ? SC_DO_NOTHING: SC_UNSPECIFIED;
252}
253
254void sc_report::suppress_infos(bool suppress)
255{
256    sc_deprecated_report_ids("sc_report::supress_infos");
257    sc_report_handler::sev_actions[SC_INFO] =
258	suppress ? SC_DO_NOTHING: SC_DEFAULT_INFO_ACTIONS;
259}
260
261void sc_report::suppress_warnings(bool suppress)
262{
263    sc_deprecated_report_ids("sc_report::suppress_warnings");
264    sc_report_handler::sev_actions[SC_WARNING] =
265	suppress ? SC_DO_NOTHING: SC_DEFAULT_WARNING_ACTIONS;
266}
267
268void sc_report::make_warnings_errors(bool flag)
269{
270    sc_deprecated_report_ids("sc_report::make_warnings_errors");
271    warnings_are_errors = flag;
272}
273
274int sc_report::get_id() const
275{
276    return md->id;
277}
278
279} // namespace sc_core
280
281// $Log: sc_report.cpp,v $
282// Revision 1.8  2011/08/29 18:04:32  acg
283//  Philipp A. Hartmann: miscellaneous clean ups.
284//
285// Revision 1.7  2011/08/26 20:43:01  acg
286//  Andy Goodrich:
287//    (1) Replaced strdup with new and strcpy to eliminate issue with the
288//        Greenhills compiler.
289//    (2) Moved modification log to the end of the file to eliminate line
290//        skew when check-ins are done.
291//
292// Revision 1.6  2011/08/24 22:05:56  acg
293//  Torsten Maehne: initialization changes to remove warnings.
294//
295// Revision 1.5  2011/05/05 17:46:04  acg
296//  Philip A. Hartmann: changes in "swap" support.
297//
298// Revision 1.4  2011/03/23 16:16:48  acg
299//  Andy Goodrich: finish message verbosity support.
300//
301// Revision 1.3  2011/02/18 20:38:44  acg
302//  Andy Goodrich: Updated Copyright notice.
303//
304// Revision 1.2  2011/02/01 23:02:05  acg
305//  Andy Goodrich: IEEE 1666 2011 changes.
306//
307// Revision 1.1.1.1  2006/12/15 20:20:06  acg
308// SystemC 2.3
309//
310// Revision 1.7  2006/03/21 00:00:37  acg
311//   Andy Goodrich: changed name of sc_get_current_process_base() to be
312//   sc_get_current_process_b() since its returning an sc_process_b instance.
313//
314// Revision 1.6  2006/01/25 00:31:27  acg
315//  Andy Goodrich: Changed over to use a standard message id of
316//  SC_ID_IEEE_1666_DEPRECATION for all deprecation messages.
317//
318// Revision 1.5  2006/01/24 22:02:30  acg
319//  Andy Goodrich: switch deprecated features warnings to use a single message
320//  id, SC_ID_IEEE_1666_DEPRECATION_.
321//
322// Revision 1.4  2006/01/24 20:53:41  acg
323// Andy Goodrich: added warnings indicating that use of integer ids in reports
324// is deprecated. Added tracing/sc_trace_ids.h to message list.
325//
326// Revision 1.3  2006/01/13 18:53:11  acg
327// Andy Goodrich: Added $Log command so that CVS comments are reproduced in
328// the source.
329
330// taf
331