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_handler.cpp -
23 
24   Original Author: Alex Riesen, Synopsys, Inc.
25   see also sc_report.cpp
26 
27   CHANGE LOG AT END OF FILE
28  *****************************************************************************/
29 
30 #include <cstdio>
31 #include <cstdlib>
32 #include <cstring>
33 #include <fstream>
34 
35 #include "sysc/kernel/sc_process.h"
36 #include "sysc/kernel/sc_simcontext_int.h"
37 #include "sysc/utils/sc_stop_here.h"
38 #include "sysc/utils/sc_report_handler.h"
39 #include "sysc/utils/sc_report.h"
40 
41 namespace std {}
42 
43 namespace sc_core {
44 
45 int sc_report_handler::verbosity_level = SC_MEDIUM;
46 
47 // not documented, but available
sc_report_compose_message(const sc_report & rep)48 const std::string sc_report_compose_message(const sc_report& rep)
49 {
50     static const char * severity_names[] = {
51 	"Info", "Warning", "Error", "Fatal"
52     };
53     std::string str;
54 
55     str += severity_names[rep.get_severity()];
56     str += ": ";
57 
58     if ( rep.get_id() >= 0 ) // backward compatibility with 2.0+
59     {
60 	char idstr[64];
61 	std::sprintf(idstr, "(%c%d) ",
62 		"IWEF"[rep.get_severity()], rep.get_id());
63 	str += idstr;
64     }
65     str += rep.get_msg_type();
66 
67     if( *rep.get_msg() )
68     {
69 	str += ": ";
70 	str += rep.get_msg();
71     }
72     if( rep.get_severity() > SC_INFO )
73     {
74         char line_number_str[16];
75 	str += "\nIn file: ";
76 	str += rep.get_file_name();
77 	str += ":";
78 	std::sprintf(line_number_str, "%d", rep.get_line_number());
79 	str += line_number_str;
80 	sc_simcontext* simc = sc_get_curr_simcontext();
81 
82 	if( simc && sc_is_running() )
83 	{
84 	    const char* proc_name = rep.get_process_name();
85 
86 	    if( proc_name )
87 	    {
88 		str += "\nIn process: ";
89 		str += proc_name;
90 		str += " @ ";
91 		str += rep.get_time().to_string();
92 	    }
93 	}
94     }
95 
96     return str;
97 }
98 
99 //
100 // Private class to handle log files
101 //
102 class sc_log_file_handle
103 {
104 protected:
105 	// not CopyConstructible
106 	sc_log_file_handle(sc_log_file_handle const &);
107 
108 	// not CopyAssignable
109 	void operator=(sc_log_file_handle const &);
110 
111 public:
112 	sc_log_file_handle();
113 	sc_log_file_handle(const char *);
114 	void update_file_name(const char *);
115 	bool release();
116 	::std::ofstream& operator*();
117 
118 private:
119 	std::string log_file_name;
120 	::std::ofstream log_stream;
121 };
122 
sc_log_file_handle()123 sc_log_file_handle::sc_log_file_handle()
124 {}
125 
sc_log_file_handle(const char * fname)126 sc_log_file_handle::sc_log_file_handle(const char * fname)
127 : log_file_name(fname)
128 , log_stream(fname)
129 {}
130 
131 void
update_file_name(const char * fname)132 sc_log_file_handle::update_file_name(const char * fname)
133 {
134 	if (!fname)
135 	{
136 		release();
137 	}
138 	else //fname != NULL
139 	{
140 		if (log_file_name.empty())
141 		{
142 			if (log_stream.is_open()) //should be closed already
143 				log_stream.close();
144 			log_file_name = fname;
145 			log_stream.open(fname);
146 		}
147 		else // log_file_name not empty
148 		{
149 			// filename changed?
150 			if (log_file_name != fname)
151 			{
152 				// new filename
153 				release();
154 				log_file_name = fname;
155 				log_stream.open(fname);
156 			}
157 			else
158 			{
159 				// nothing to do
160 			}
161 		}
162 	}
163 }
164 
165 bool
release()166 sc_log_file_handle::release()
167 {
168 	if (log_stream.is_open())
169 	{
170 		log_stream.close();
171 		log_file_name.clear();
172 		return false;
173 	}
174 	return true;
175 }
176 
177 ::std::ofstream&
operator *()178 sc_log_file_handle::operator*()
179 { return log_stream;	}
180 
181 static sc_log_file_handle log_stream;
182 
183 
184 //
185 // The official handler of the exception reporting
186 //
187 
default_handler(const sc_report & rep,const sc_actions & actions)188 void sc_report_handler::default_handler(const sc_report& rep,
189 					const sc_actions& actions)
190 {
191     if ( actions & SC_DISPLAY )
192 	::std::cout << ::std::endl << sc_report_compose_message(rep) <<
193 		::std::endl;
194 
195     if ( (actions & SC_LOG) && get_log_file_name() )
196     {
197 		log_stream.update_file_name(get_log_file_name());
198 
199 	*log_stream << rep.get_time() << ": "
200 	    << sc_report_compose_message(rep) << ::std::endl;
201     }
202     if ( actions & SC_STOP )
203     {
204 	sc_stop_here(rep.get_msg_type(), rep.get_severity());
205 	sc_stop();
206     }
207     if ( actions & SC_INTERRUPT )
208 	sc_interrupt_here(rep.get_msg_type(), rep.get_severity());
209 
210     if ( actions & SC_ABORT )
211         sc_abort();
212 
213     if ( actions & SC_THROW ) {
214         sc_process_b* proc_p = sc_get_current_process_b();
215         if( proc_p && proc_p->is_unwinding() )
216             proc_p->clear_unwinding();
217         throw rep;
218     }
219 }
220 
221 // not documented, but available
sc_report_close_default_log()222 bool sc_report_close_default_log()
223 {
224     bool ret = log_stream.release();
225     sc_report_handler::set_log_file_name(NULL);
226 
227     return ret;
228 }
229 
get_count(sc_severity severity_)230 int sc_report_handler::get_count(sc_severity severity_)
231 {
232    return sev_call_count[severity_];
233 }
234 
get_count(const char * msg_type_)235 int sc_report_handler::get_count(const char* msg_type_)
236 {
237     sc_msg_def * md = mdlookup(msg_type_);
238 
239     if ( !md )
240         md = add_msg_type(msg_type_);
241 
242     return md->call_count;
243 }
244 
get_count(const char * msg_type_,sc_severity severity_)245 int sc_report_handler::get_count(const char* msg_type_, sc_severity severity_)
246 {
247     sc_msg_def * md = mdlookup(msg_type_);
248 
249     if ( !md )
250         md = add_msg_type(msg_type_);
251 
252     return md->sev_call_count[severity_];
253 }
254 
255 
256 //
257 // CLASS: sc_report_handler
258 // implementation
259 //
260 
mdlookup(const char * msg_type_)261 sc_msg_def * sc_report_handler::mdlookup(const char * msg_type_)
262 {
263     if( !msg_type_ ) // if msg_type is NULL, report unknown error
264         msg_type_ = SC_ID_UNKNOWN_ERROR_;
265 
266     for ( msg_def_items * item = messages; item; item = item->next )
267     {
268 	for ( int i = 0; i < item->count; ++i )
269 	    if ( !strcmp(msg_type_, item->md[i].msg_type) )
270 		return item->md + i;
271     }
272     return 0;
273 }
274 
275 // The calculation of actions to be executed
execute(sc_msg_def * md,sc_severity severity_)276 sc_actions sc_report_handler::execute(sc_msg_def* md, sc_severity severity_)
277 {
278     sc_actions actions = md->sev_actions[severity_]; // high prio
279 
280     if ( SC_UNSPECIFIED == actions ) // middle prio
281 	actions = md->actions;
282 
283     if ( SC_UNSPECIFIED == actions ) // the lowest prio
284 	actions = sev_actions[severity_];
285 
286     actions &= ~suppress_mask; // higher than the high prio
287     actions |= force_mask; // higher than above, and the limit is the highest
288 
289     unsigned * limit = 0;
290     unsigned * call_count = 0;
291 
292     // just increment counters and check for overflow
293     if ( md->sev_call_count[severity_] < UINT_MAX )
294 	md->sev_call_count[severity_]++;
295     if ( md->call_count < UINT_MAX )
296 	md->call_count++;
297     if ( sev_call_count[severity_] < UINT_MAX )
298 	sev_call_count[severity_]++;
299 
300     if ( md->limit_mask & (1 << (severity_ + 1)) )
301     {
302 	limit = md->sev_limit + severity_;
303 	call_count = md->sev_call_count + severity_;
304     }
305     if ( !limit && (md->limit_mask & 1) )
306     {
307 	limit = &md->limit;
308 	call_count = &md->call_count;
309     }
310     if ( !limit )
311     {
312 	limit = sev_limit + severity_;
313 	call_count = sev_call_count + severity_;
314     }
315     if ( *limit == 0 )
316     {
317 	// stop limit disabled
318     }
319     else if ( *limit != UINT_MAX )
320     {
321 	if ( *call_count >= *limit )
322 	    actions |= SC_STOP; // force sc_stop()
323     }
324     return actions;
325 }
326 
report(sc_severity severity_,const char * msg_type_,const char * msg_,int verbosity_,const char * file_,int line_)327 void sc_report_handler::report( sc_severity severity_,
328                                 const char* msg_type_,
329 				const char* msg_,
330 				int verbosity_,
331 				const char* file_,
332 				int line_ )
333 {
334     sc_msg_def * md = mdlookup(msg_type_);
335 
336     // If the severity of the report is SC_INFO and the specified verbosity
337     // level is greater than the maximum verbosity level of the simulator then
338     // return without any action.
339 
340     if ( (severity_ == SC_INFO) && (verbosity_ > verbosity_level) ) return;
341 
342     // Process the report:
343 
344     if ( !md )
345 	md = add_msg_type(msg_type_);
346 
347     sc_actions actions = execute(md, severity_);
348     sc_report rep(severity_, md, msg_, file_, line_, verbosity_);
349 
350     if ( actions & SC_CACHE_REPORT )
351 	cache_report(rep);
352 
353     handler(rep, actions);
354 }
355 
report(sc_severity severity_,const char * msg_type_,const char * msg_,const char * file_,int line_)356 void sc_report_handler::report(sc_severity severity_,
357 			       const char * msg_type_,
358 			       const char * msg_,
359 			       const char * file_,
360 			       int line_)
361 {
362     sc_msg_def * md = mdlookup(msg_type_);
363 
364     // If the severity of the report is SC_INFO and the maximum verbosity
365     // level is less than SC_MEDIUM return without any action.
366 
367     if ( (severity_ == SC_INFO) && (SC_MEDIUM > verbosity_level) ) return;
368 
369     // Process the report:
370 
371 
372     if ( !md )
373 	md = add_msg_type(msg_type_);
374 
375     sc_actions actions = execute(md, severity_);
376     sc_report rep(severity_, md, msg_, file_, line_);
377 
378     if ( actions & SC_CACHE_REPORT )
379 	cache_report(rep);
380 
381     handler(rep, actions);
382 }
383 
384 // The following method is never called by the simulator.
385 
initialize()386 void sc_report_handler::initialize()
387 {
388 #if 0 // actually, i do not know whether we have to reset these.
389     suppress();
390     force();
391     set_actions(SC_INFO,    SC_DEFAULT_INFO_ACTIONS);
392     set_actions(SC_WARNING, SC_DEFAULT_WARNING_ACTIONS);
393     set_actions(SC_ERROR,   SC_DEFAULT_ERROR_ACTIONS);
394     set_actions(SC_FATAL,   SC_DEFAULT_FATAL_ACTIONS);
395 #endif
396 
397     sev_call_count[SC_INFO]    = 0;
398     sev_call_count[SC_WARNING] = 0;
399     sev_call_count[SC_ERROR]   = 0;
400     sev_call_count[SC_FATAL]   = 0;
401 
402     msg_def_items * items = messages;
403 
404     while ( items != &msg_terminator )
405     {
406 	for ( int i = 0; i < items->count; ++i )
407 	{
408 	    items->md[i].call_count = 0;
409 	    items->md[i].sev_call_count[SC_INFO]    = 0;
410 	    items->md[i].sev_call_count[SC_WARNING] = 0;
411 	    items->md[i].sev_call_count[SC_ERROR]   = 0;
412 	    items->md[i].sev_call_count[SC_FATAL]   = 0;
413 	}
414 	items = items->next;
415     }
416 
417     // PROCESS ANY ENVIRONMENTAL OVERRIDES:
418 
419     const char* deprecation_warn = std::getenv("SC_DEPRECATION_WARNINGS");
420     if ( (deprecation_warn!=0) && !strcmp(deprecation_warn,"DISABLE") )
421     {
422         set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING);
423     }
424 }
425 
426 // free the sc_msg_def's allocated by add_msg_type
427 // (or implicit msg_type registration: set_actions, abort_after)
428 // clear last_global_report.
release()429 void sc_report_handler::release()
430 {
431     delete last_global_report;
432     last_global_report = 0;
433     sc_report_close_default_log();
434 
435     msg_def_items * items = messages, * newitems = &msg_terminator;
436     messages = &msg_terminator;
437 
438     while ( items != &msg_terminator )
439     {
440 	for ( int i = 0; i < items->count; ++i )
441 	    if ( items->md[i].msg_type == items->md[i].msg_type_data )
442 		free(items->md[i].msg_type_data);
443 
444 	msg_def_items * prev = items;
445 	items = items->next;
446 
447 	if ( prev->allocated )
448 	{
449 	    delete [] prev->md;
450 	    delete prev;
451 	}
452 	else
453 	{
454 	    prev->next = newitems;
455 	    newitems = prev;
456 	}
457     }
458     messages = newitems;
459 }
460 
add_msg_type(const char * msg_type_)461 sc_msg_def * sc_report_handler::add_msg_type(const char * msg_type_)
462 {
463     sc_msg_def * md = mdlookup(msg_type_);
464     int          msg_type_len;
465 
466     if ( md )
467 	return md;
468 
469     msg_def_items * items = new msg_def_items;
470 
471     if ( !items )
472 	return 0;
473 
474     items->count = 1;
475     items->md = new sc_msg_def[items->count];
476 
477     if ( !items->md )
478     {
479 	delete items;
480 	return 0;
481     }
482     memset(items->md, 0, sizeof(sc_msg_def) * items->count);
483     msg_type_len = strlen(msg_type_);
484     if ( msg_type_len > 0 )
485     {
486 	items->md->msg_type_data = (char*) malloc(msg_type_len+1);
487 	strcpy( items->md->msg_type_data, msg_type_ );
488 	items->md->id = -1; // backward compatibility with 2.0+
489     }
490     else
491     {
492 	delete [] items->md;
493 	delete items;
494 	return 0;
495     }
496     items->md->msg_type = items->md->msg_type_data;
497     add_static_msg_types(items);
498     items->allocated = true;
499 
500     return items->md;
501 }
502 
add_static_msg_types(msg_def_items * items)503 void sc_report_handler::add_static_msg_types(msg_def_items * items)
504 {
505     items->allocated = false;
506     items->next = messages;
507     messages = items;
508 }
509 
set_actions(sc_severity severity_,sc_actions actions_)510 sc_actions sc_report_handler::set_actions(sc_severity severity_,
511 					  sc_actions actions_)
512 {
513     sc_actions old = sev_actions[severity_];
514     sev_actions[severity_] = actions_;
515     return old;
516 }
517 
set_actions(const char * msg_type_,sc_actions actions_)518 sc_actions sc_report_handler::set_actions(const char * msg_type_,
519 					  sc_actions actions_)
520 {
521     sc_msg_def * md = mdlookup(msg_type_);
522 
523     if ( !md )
524 	md = add_msg_type(msg_type_);
525 
526     sc_actions old = md->actions;
527     md->actions = actions_;
528 
529     return old;
530 }
531 
set_actions(const char * msg_type_,sc_severity severity_,sc_actions actions_)532 sc_actions sc_report_handler::set_actions(const char * msg_type_,
533 					  sc_severity severity_,
534 					  sc_actions actions_)
535 {
536     sc_msg_def * md = mdlookup(msg_type_);
537 
538     if ( !md )
539 	md = add_msg_type(msg_type_);
540 
541     sc_actions old = md->sev_actions[severity_];
542     md->sev_actions[severity_] = actions_;
543 
544     return old;
545 }
546 
stop_after(sc_severity severity_,int limit)547 int sc_report_handler::stop_after(sc_severity severity_, int limit)
548 {
549     int old = sev_limit[severity_];
550 
551     sev_limit[severity_] = limit < 0 ? UINT_MAX: (unsigned) limit;
552 
553     return old;
554 }
555 
stop_after(const char * msg_type_,int limit)556 int sc_report_handler::stop_after(const char * msg_type_, int limit)
557 {
558     sc_msg_def * md = mdlookup(msg_type_);
559 
560     if ( !md )
561 	md = add_msg_type(msg_type_);
562 
563     int old = md->limit_mask & 1 ? md->limit: UINT_MAX;
564 
565     if ( limit < 0 )
566 	md->limit_mask &= ~1;
567     else
568     {
569 	md->limit_mask |= 1;
570 	md->limit = limit;
571     }
572     return old;
573 }
574 
stop_after(const char * msg_type_,sc_severity severity_,int limit)575 int sc_report_handler::stop_after(const char * msg_type_,
576 				  sc_severity severity_,
577 				  int limit)
578 {
579     sc_msg_def * md = mdlookup(msg_type_);
580 
581     if ( !md )
582 	md = add_msg_type(msg_type_);
583 
584     int mask = 1 << (severity_ + 1);
585     int old = md->limit_mask & mask ?  md->sev_limit[severity_]: UINT_MAX;
586 
587     if ( limit < 0 )
588 	md->limit_mask &= ~mask;
589     else
590     {
591 	md->limit_mask |= mask;
592 	md->sev_limit[severity_] = limit;
593     }
594     return old;
595 }
596 
suppress(sc_actions mask)597 sc_actions sc_report_handler::suppress(sc_actions mask)
598 {
599     sc_actions old = suppress_mask;
600     suppress_mask = mask;
601     return old;
602 }
603 
suppress()604 sc_actions sc_report_handler::suppress()
605 {
606     return suppress(0);
607 }
608 
force(sc_actions mask)609 sc_actions sc_report_handler::force(sc_actions mask)
610 {
611     sc_actions old = force_mask;
612     force_mask = mask;
613     return old;
614 }
615 
force()616 sc_actions sc_report_handler::force()
617 {
618     return force(0);
619 }
620 
621 sc_report_handler_proc
set_handler(sc_report_handler_proc handler_)622 sc_report_handler::set_handler(sc_report_handler_proc handler_)
623 {
624     sc_report_handler_proc old = handler;
625     handler = handler_ ? handler_: &sc_report_handler::default_handler;
626     return old;
627 }
628 
629 sc_report_handler_proc
get_handler()630 sc_report_handler::get_handler()
631 {
632     return handler;
633 }
634 
get_cached_report()635 sc_report* sc_report_handler::get_cached_report()
636 {
637     sc_process_b * proc = sc_get_current_process_b();
638 
639     if ( proc )
640 	return proc->get_last_report();
641 
642     return last_global_report;
643 }
644 
clear_cached_report()645 void sc_report_handler::clear_cached_report()
646 {
647     sc_process_b * proc = sc_get_current_process_b();
648 
649     if ( proc )
650 	proc->set_last_report(0);
651     else
652     {
653 	delete last_global_report;
654 	last_global_report = 0;
655     }
656 }
657 
get_new_action_id()658 sc_actions sc_report_handler::get_new_action_id()
659 {
660     for ( sc_actions p = 1; p; p <<= 1 )
661     {
662 	if ( !(p & available_actions) ) // free
663 	{
664 	    available_actions |= p;
665 	    return p;
666 	}
667     }
668     return SC_UNSPECIFIED;
669 }
670 
set_log_file_name(const char * name_)671 bool sc_report_handler::set_log_file_name(const char* name_)
672 {
673     if ( !name_ )
674     {
675 	free(log_file_name);
676 	log_file_name = 0;
677 	return false;
678     }
679     if ( log_file_name )
680 	return false;
681 
682     log_file_name = (char*)malloc(strlen(name_)+1);
683     strcpy(log_file_name, name_);
684     return true;
685 }
686 
get_log_file_name()687 const char * sc_report_handler::get_log_file_name()
688 {
689     return log_file_name;
690 }
691 
cache_report(const sc_report & rep)692 void sc_report_handler::cache_report(const sc_report& rep)
693 {
694     sc_process_b * proc = sc_get_current_process_b();
695     if ( proc )
696 	proc->set_last_report(new sc_report(rep));
697     else
698     {
699 	delete last_global_report;
700 	last_global_report = new sc_report(rep);
701     }
702 }
703 
704 //
705 // backward compatibility with 2.0+
706 //
707 
mdlookup(int id)708 sc_msg_def * sc_report_handler::mdlookup(int id)
709 {
710     for ( msg_def_items * item = messages; item; item = item->next )
711     {
712 	for ( int i = 0; i < item->count; ++i )
713 	    if ( id == item->md[i].id )
714 		return item->md + i;
715     }
716     return 0;
717 }
718 
get_verbosity_level()719 int sc_report_handler::get_verbosity_level() { return verbosity_level; }
720 
set_verbosity_level(int level)721 int sc_report_handler::set_verbosity_level( int level )
722 {
723     int result = verbosity_level;
724     verbosity_level = level;
725     return result;
726 }
727 
728 //
729 // CLASS: sc_report_handler
730 // static variables
731 //
732 
733 sc_actions sc_report_handler::suppress_mask = 0;
734 sc_actions sc_report_handler::force_mask = 0;
735 
736 sc_actions sc_report_handler::sev_actions[SC_MAX_SEVERITY] =
737 {
738     /* info  */ SC_DEFAULT_INFO_ACTIONS,
739     /* warn  */ SC_DEFAULT_WARNING_ACTIONS,
740     /* error */ SC_DEFAULT_ERROR_ACTIONS,
741     /* fatal */ SC_DEFAULT_FATAL_ACTIONS
742 };
743 
744 // Note that SC_FATAL has a limit of 1 by default
745 
746 sc_actions sc_report_handler::sev_limit[SC_MAX_SEVERITY] =
747 {
748     UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX
749 };
750 sc_actions sc_report_handler::sev_call_count[SC_MAX_SEVERITY] = { 0, 0, 0, 0 };
751 
752 sc_report* sc_report_handler::last_global_report = NULL;
753 sc_actions sc_report_handler::available_actions =
754     SC_DO_NOTHING |
755     SC_THROW |
756     SC_LOG |
757     SC_DISPLAY |
758     SC_CACHE_REPORT |
759     SC_INTERRUPT |
760     SC_STOP |
761     SC_ABORT;
762 
763 sc_report_handler_proc sc_report_handler::handler =
764     &sc_report_handler::default_handler;
765 
766 char * sc_report_handler::log_file_name = 0;
767 
768 sc_report_handler::msg_def_items * sc_report_handler::messages =
769     &sc_report_handler::msg_terminator;
770 
771 
772 sc_actions sc_report_handler::catch_actions = SC_DEFAULT_CATCH_ACTIONS;
773 
set_catch_actions(sc_actions act)774 sc_actions sc_report_handler::set_catch_actions(sc_actions act)
775 {
776     //sc_assert( !(act | SC_THROW) ); // allow SC_THROW?
777     sc_actions old = catch_actions;
778     catch_actions = act;
779     return old;
780 }
781 
get_catch_actions()782 sc_actions sc_report_handler::get_catch_actions()
783 {
784     return catch_actions;
785 }
786 
787 //
788 // predefined messages
789 //
790 
791 SC_API const char SC_ID_REGISTER_ID_FAILED_[] = "register_id failed";
792 SC_API const char SC_ID_UNKNOWN_ERROR_[]      = "unknown error";
793 SC_API const char SC_ID_WITHOUT_MESSAGE_[]    = "";
794 SC_API const char SC_ID_NOT_IMPLEMENTED_[]    = "not implemented";
795 SC_API const char SC_ID_INTERNAL_ERROR_[]     = "internal error";
796 SC_API const char SC_ID_ASSERTION_FAILED_[]   = "assertion failed";
797 SC_API const char SC_ID_OUT_OF_BOUNDS_[]      = "out of bounds";
798 SC_API const char SC_ID_ABORT_[]              = "simulation aborted";
799 
800 #define DEFINE_MSG(id,n)                                                     \
801     {                                                                        \
802 	(id),                                                                \
803 	0u, {0u}, /* actions */                                              \
804 	0u, {0u}, 0u, /* limits */                                           \
805 	0u, {0u}, NULL, /* call counters */                                  \
806 	n                                                                    \
807     }
808 
809 static sc_msg_def default_msgs[] = {
810     DEFINE_MSG(SC_ID_REGISTER_ID_FAILED_, 800),
811     DEFINE_MSG(SC_ID_UNKNOWN_ERROR_, 0),
812     DEFINE_MSG(SC_ID_WITHOUT_MESSAGE_, 1),
813     DEFINE_MSG(SC_ID_NOT_IMPLEMENTED_, 2),
814     DEFINE_MSG(SC_ID_INTERNAL_ERROR_, 3),
815     DEFINE_MSG(SC_ID_ASSERTION_FAILED_, 4),
816     DEFINE_MSG(SC_ID_OUT_OF_BOUNDS_, 5),
817 
818     DEFINE_MSG(SC_ID_ABORT_, 99)
819 };
820 
821 sc_report_handler::msg_def_items sc_report_handler::msg_terminator =
822 {
823     default_msgs,
824     sizeof(default_msgs)/sizeof(*default_msgs),
825     false,
826     NULL
827 };
828 
829 
830 void
sc_abort()831 sc_abort()
832 {
833     SC_REPORT_INFO(SC_ID_ABORT_, 0);
834     abort();
835 }
836 
837 
838 void
sc_assertion_failed(const char * msg,const char * file,int line)839 sc_assertion_failed(const char* msg, const char* file, int line)
840 {
841     sc_report_handler::report( SC_FATAL, SC_ID_ASSERTION_FAILED_
842                              , msg, file, line );
843     sc_abort();
844 }
845 
846 } // namespace sc_core
847 
848 // $Log: sc_report_handler.cpp,v $
849 // Revision 1.9  2011/08/29 18:04:32  acg
850 //  Philipp A. Hartmann: miscellaneous clean ups.
851 //
852 // Revision 1.8  2011/08/26 20:46:19  acg
853 //  Andy Goodrich: moved the modification log to the end of the file to
854 //  eliminate source line number skew when check-ins are done.
855 //
856 // Revision 1.7  2011/08/07 19:08:08  acg
857 //  Andy Goodrich: moved logs to end of file so line number synching works
858 //  better between versions.
859 //
860 // Revision 1.6  2011/08/07 18:56:03  acg
861 //  Philipp A. Hartmann: added cast to ? : to eliminate clang warning message.
862 //
863 // Revision 1.5  2011/03/23 16:16:49  acg
864 //  Andy Goodrich: finish message verbosity support.
865 //
866 // Revision 1.4  2011/02/18 20:38:44  acg
867 //  Andy Goodrich: Updated Copyright notice.
868 //
869 // Revision 1.3  2011/02/11 13:25:55  acg
870 //  Andy Goodrich: Philipp's changes for sc_unwind_exception.
871 //
872 // Revision 1.2  2011/02/01 23:02:05  acg
873 //  Andy Goodrich: IEEE 1666 2011 changes.
874 //
875 // Revision 1.1.1.1  2006/12/15 20:20:06  acg
876 // SystemC 2.3
877 //
878 // Revision 1.7  2006/05/26 20:35:52  acg
879 //  Andy Goodrich: removed debug message that should not have been left in.
880 //
881 // Revision 1.6  2006/03/21 00:00:37  acg
882 //   Andy Goodrich: changed name of sc_get_current_process_base() to be
883 //   sc_get_current_process_b() since its returning an sc_process_b instance.
884 //
885 // Revision 1.5  2006/01/31 21:42:07  acg
886 //  Andy Goodrich: Added checks for SC_DEPRECATED_WARNINGS being defined as
887 //  DISABLED. If so, we turn off the /IEEE_Std_1666/deprecated message group.
888 //
889 // Revision 1.4  2006/01/26 21:08:17  acg
890 //  Andy Goodrich: conversion to use sc_is_running instead of deprecated
891 //  sc_simcontext::is_running()
892 //
893 // Revision 1.3  2006/01/13 18:53:11  acg
894 // Andy Goodrich: Added $Log command so that CVS comments are reproduced in
895 // the source.
896 
897 // Taf!
898