1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
18 #include <sys/types.h>
20 #include "../common/memory.h"
22 #include "Communication.hh"
23 #include "Component.hh"
24 #include "LoggingBits.hh"
25 #include "LoggerPluginManager.hh"
26 #include "Charstring.hh"
27 #include "LoggingParam.hh"
30 /** work-around for missing va_copy() in GCC */
31 #if defined(__GNUC__) && !defined(va_copy)
33 # define va_copy(dest, src) __va_copy(dest, src)
35 # define va_copy(dest, src) (dest) = (src)
39 #define MIN_BUFFER_SIZE 1024
42 /** @brief Return a string identifying the component
44 If \p comp.id_selector is COMPONENT_ID_NAME, returns \p comp.id_name
46 If \p comp.id_selector is COMPONENT_ID_COMPREF, returns a pointer
47 to a static buffer, containing a string representation of \p comp.id_compref
49 If \p comp.id_selector is COMPONENT_ID_ALL, returns "All".
51 If \p comp.id_selector is COMPONENT_ID_SYSTEM, returns "System".
53 @param comp component identifier
56 expstring_t
component_string(const component_id_t
& comp
);
59 /** @name Private data structures
65 For TTCN_Logger internal use, no user serviceable parts.
67 struct TTCN_Logger::log_mask_struct
69 component_id_t component_id
; /**< Component */
70 Logging_Bits mask
; /**< Settings for logging to console or file */
79 LoggerPluginManager
*TTCN_Logger::plugins_
= NULL
;
81 /* No point in initializing here; will be done in initialize_logger() */
82 TTCN_Logger::log_mask_struct
TTCN_Logger::console_log_mask
;
83 TTCN_Logger::log_mask_struct
TTCN_Logger::file_log_mask
;
84 TTCN_Logger::log_mask_struct
TTCN_Logger::emergency_log_mask
;
86 TTCN_Logger::emergency_logging_behaviour_t
TTCN_Logger::emergency_logging_behaviour
= BUFFER_MASKED
;
87 size_t TTCN_Logger::emergency_logging
;
89 TTCN_Logger::matching_verbosity_t
TTCN_Logger::matching_verbosity
= VERBOSITY_COMPACT
;
91 /** Timestamp format in the log files. */
92 TTCN_Logger::timestamp_format_t
TTCN_Logger::timestamp_format
= TIMESTAMP_TIME
;
94 /** LogSourceInfo/SourceInfoFormat */
95 TTCN_Logger::source_info_format_t
TTCN_Logger::source_info_format
= SINFO_SINGLE
;
98 TTCN_Logger::log_event_types_t
TTCN_Logger::log_event_types
= LOGEVENTTYPES_NO
;
100 // This array should contain all the _UNQUALIFIED severities.
101 const TTCN_Logger::Severity
TTCN_Logger::sev_categories
[] =
103 TTCN_Logger::NOTHING_TO_LOG
, // 0
104 TTCN_Logger::ACTION_UNQUALIFIED
, // 1
105 TTCN_Logger::DEFAULTOP_UNQUALIFIED
, // 5
106 TTCN_Logger::ERROR_UNQUALIFIED
, // 6
107 TTCN_Logger::EXECUTOR_UNQUALIFIED
, // 12
108 TTCN_Logger::FUNCTION_UNQUALIFIED
, // 14
109 TTCN_Logger::PARALLEL_UNQUALIFIED
, // 18
110 TTCN_Logger::TESTCASE_UNQUALIFIED
, // 21
111 TTCN_Logger::PORTEVENT_UNQUALIFIED
, // 35
112 TTCN_Logger::STATISTICS_UNQUALIFIED
, // 37
113 TTCN_Logger::TIMEROP_UNQUALIFIED
, // 43
114 TTCN_Logger::USER_UNQUALIFIED
, // 44
115 TTCN_Logger::VERDICTOP_UNQUALIFIED
, // 48
116 TTCN_Logger::WARNING_UNQUALIFIED
, // 49
117 TTCN_Logger::MATCHING_UNQUALIFIED
, // 61
118 TTCN_Logger::DEBUG_UNQUALIFIED
, // 66
121 const char* TTCN_Logger::severity_category_names
[] =
142 /** Sub-category names for all Severity enum values,
143 * used when TTCN_Logger::log_event_types is set to log sub-categories */
144 const char* TTCN_Logger::severity_subcategory_names
[NUMBER_OF_LOGSEVERITIES
] = {
229 char* TTCN_Logger::logmatch_buffer
= NULL
;
230 size_t TTCN_Logger::logmatch_buffer_len
= 0;
231 size_t TTCN_Logger::logmatch_buffer_size
= 0;
232 boolean
TTCN_Logger::logmatch_printed
= false;
234 // TODO: Matching related stuff stays here for now. It just appends the
235 // string to the end of the current (active) event.
236 size_t TTCN_Logger::get_logmatch_buffer_len()
238 return logmatch_buffer_len
;
241 void TTCN_Logger::set_logmatch_buffer_len(size_t new_len
)
243 logmatch_buffer_len
= new_len
;
244 logmatch_buffer_size
= MIN_BUFFER_SIZE
;
245 while (logmatch_buffer_size
< new_len
)
246 logmatch_buffer_size
*= 2;
247 logmatch_buffer
= (char *)Realloc(logmatch_buffer
, logmatch_buffer_size
);
248 logmatch_buffer
[new_len
] = '\0';
251 void TTCN_Logger::print_logmatch_buffer()
253 if (logmatch_printed
) TTCN_Logger::log_event_str(" , ");
254 else logmatch_printed
= true;
255 if (logmatch_buffer_size
> 0)
256 TTCN_Logger::log_event_str(logmatch_buffer
);
259 void TTCN_Logger::log_logmatch_info(const char *fmt_str
, ...)
262 va_start(p_var
, fmt_str
);
264 if (fmt_str
== NULL
) fmt_str
= "<NULL format string>";
266 size_t free_space
= logmatch_buffer_size
- logmatch_buffer_len
;
267 // Make a copy of p_var to allow multiple calls of vsnprintf().
269 va_copy(p_var2
, p_var
);
270 int fragment_len
= vsnprintf(logmatch_buffer
+ logmatch_buffer_len
,
271 free_space
, fmt_str
, p_var2
);
273 if (fragment_len
< 0) set_logmatch_buffer_len(logmatch_buffer_size
* 2);
274 else if ((size_t)fragment_len
>= free_space
)
275 set_logmatch_buffer_len(logmatch_buffer_len
+ fragment_len
+ 1);
277 logmatch_buffer_len
+= fragment_len
;
284 /** The "beginning of time" for the logger (seconds and microseconds
287 struct timeval
TTCN_Logger::start_time
;
289 /** The base name of the current executable (no path, no extension) */
290 char *TTCN_Logger::executable_name
= NULL
;
292 /// True to log type (controlpart/altstep/testcase/function/...) and name
293 /// of the entity responsible for the log message, false to suppress it.
294 boolean
TTCN_Logger::log_entity_name
= FALSE
;
296 /// The default log format is the legacy (original) format.
297 TTCN_Logger::data_log_format_t
TTCN_Logger::data_log_format
= LF_LEGACY
;
301 /** @brief Equality operator for component_id_t
303 @param left component identifier
304 @param right component identifier
305 @return true if \p left and \p right refer to the same component
307 @note This functions tests the equality of the component identifiers,
308 not the components themselves. It can't detect that component named "foo" is
309 the same as component number 3.
311 @li If the selectors differ, returns \c false.
312 @li If both selectors are COMPONENT_ID_NAME, compares the names.
313 @li If both selectors are COMPONENT_ID_COMPREF, compares the comp. references.
314 @li If both selectors are COMPONENT_ID_ALL or COMPONENT_ID_SYSTEM,
318 bool operator==(const component_id_t
& left
, const component_id_t
& right
)
320 if (left
.id_selector
!= right
.id_selector
)
323 // The selectors are the same.
324 switch (left
.id_selector
) {
325 case COMPONENT_ID_NAME
:
326 return !strcmp(left
.id_name
, right
.id_name
);
327 case COMPONENT_ID_COMPREF
:
328 return left
.id_compref
== right
.id_compref
;
329 default: // Should be MTC or SYSTEM; identified by the selector.
334 char *TTCN_Logger::mputstr_severity(char *str
, const TTCN_Logger::Severity
& severity
)
337 case TTCN_Logger::ACTION_UNQUALIFIED
:
338 return mputstr(str
, "ACTION");
339 case TTCN_Logger::DEFAULTOP_ACTIVATE
:
340 case TTCN_Logger::DEFAULTOP_DEACTIVATE
:
341 case TTCN_Logger::DEFAULTOP_EXIT
:
342 case TTCN_Logger::DEFAULTOP_UNQUALIFIED
:
343 return mputstr(str
, "DEFAULTOP");
344 case TTCN_Logger::ERROR_UNQUALIFIED
:
345 return mputstr(str
, "ERROR");
346 case TTCN_Logger::EXECUTOR_RUNTIME
:
347 case TTCN_Logger::EXECUTOR_CONFIGDATA
:
348 case TTCN_Logger::EXECUTOR_EXTCOMMAND
:
349 case TTCN_Logger::EXECUTOR_COMPONENT
:
350 case TTCN_Logger::EXECUTOR_LOGOPTIONS
:
351 case TTCN_Logger::EXECUTOR_UNQUALIFIED
:
352 return mputstr(str
, "EXECUTOR");
353 case TTCN_Logger::FUNCTION_RND
:
354 case TTCN_Logger::FUNCTION_UNQUALIFIED
:
355 return mputstr(str
, "FUNCTION");
356 case TTCN_Logger::PARALLEL_PTC
:
357 case TTCN_Logger::PARALLEL_PORTCONN
:
358 case TTCN_Logger::PARALLEL_PORTMAP
:
359 case TTCN_Logger::PARALLEL_UNQUALIFIED
:
360 return mputstr(str
, "PARALLEL");
361 case TTCN_Logger::TESTCASE_START
:
362 case TTCN_Logger::TESTCASE_FINISH
:
363 case TTCN_Logger::TESTCASE_UNQUALIFIED
:
364 return mputstr(str
, "TESTCASE");
365 case TTCN_Logger::PORTEVENT_PQUEUE
:
366 case TTCN_Logger::PORTEVENT_MQUEUE
:
367 case TTCN_Logger::PORTEVENT_STATE
:
368 case TTCN_Logger::PORTEVENT_PMIN
:
369 case TTCN_Logger::PORTEVENT_PMOUT
:
370 case TTCN_Logger::PORTEVENT_PCIN
:
371 case TTCN_Logger::PORTEVENT_PCOUT
:
372 case TTCN_Logger::PORTEVENT_MMRECV
:
373 case TTCN_Logger::PORTEVENT_MMSEND
:
374 case TTCN_Logger::PORTEVENT_MCRECV
:
375 case TTCN_Logger::PORTEVENT_MCSEND
:
376 case TTCN_Logger::PORTEVENT_DUALRECV
:
377 case TTCN_Logger::PORTEVENT_DUALSEND
:
378 case TTCN_Logger::PORTEVENT_UNQUALIFIED
:
379 return mputstr(str
, "PORTEVENT");
380 case TTCN_Logger::STATISTICS_VERDICT
:
381 case TTCN_Logger::STATISTICS_UNQUALIFIED
:
382 return mputstr(str
, "STATISTICS");
383 case TTCN_Logger::TIMEROP_READ
:
384 case TTCN_Logger::TIMEROP_START
:
385 case TTCN_Logger::TIMEROP_GUARD
:
386 case TTCN_Logger::TIMEROP_STOP
:
387 case TTCN_Logger::TIMEROP_TIMEOUT
:
388 case TTCN_Logger::TIMEROP_UNQUALIFIED
:
389 return mputstr(str
, "TIMEROP");
390 case TTCN_Logger::USER_UNQUALIFIED
:
391 return mputstr(str
, "USER");
393 case TTCN_Logger::VERDICTOP_GETVERDICT
:
394 case TTCN_Logger::VERDICTOP_SETVERDICT
:
395 case TTCN_Logger::VERDICTOP_FINAL
:
396 case TTCN_Logger::VERDICTOP_UNQUALIFIED
:
397 return mputstr(str
, "VERDICTOP");
398 case TTCN_Logger::WARNING_UNQUALIFIED
:
399 return mputstr(str
, "WARNING");
400 case TTCN_Logger::MATCHING_DONE
:
401 case TTCN_Logger::MATCHING_TIMEOUT
:
402 case TTCN_Logger::MATCHING_PCSUCCESS
:
403 case TTCN_Logger::MATCHING_PCUNSUCC
:
404 case TTCN_Logger::MATCHING_PMSUCCESS
:
405 case TTCN_Logger::MATCHING_PMUNSUCC
:
406 case TTCN_Logger::MATCHING_MCSUCCESS
:
407 case TTCN_Logger::MATCHING_MCUNSUCC
:
408 case TTCN_Logger::MATCHING_MMSUCCESS
:
409 case TTCN_Logger::MATCHING_MMUNSUCC
:
410 case TTCN_Logger::MATCHING_PROBLEM
:
411 case TTCN_Logger::MATCHING_UNQUALIFIED
:
412 return mputstr(str
, "MATCHING");
413 case TTCN_Logger::DEBUG_ENCDEC
:
414 case TTCN_Logger::DEBUG_TESTPORT
:
415 case TTCN_Logger::DEBUG_USER
:
416 case TTCN_Logger::DEBUG_FRAMEWORK
:
417 case TTCN_Logger::DEBUG_UNQUALIFIED
:
418 return mputstr(str
, "DEBUG");
420 return mputstr(str
, "UNKNOWN");
424 char *TTCN_Logger::mputstr_timestamp(char *str
,
425 timestamp_format_t p_timestamp_format
,
426 const struct timeval
*tv
)
428 if (p_timestamp_format
== TIMESTAMP_SECONDS
) {
430 if (tv
->tv_usec
< start_time
.tv_usec
) {
431 diff
.tv_sec
= tv
->tv_sec
- start_time
.tv_sec
- 1;
432 diff
.tv_usec
= tv
->tv_usec
+ (1000000L - start_time
.tv_usec
);
434 diff
.tv_sec
= tv
->tv_sec
- start_time
.tv_sec
;
435 diff
.tv_usec
= tv
->tv_usec
- start_time
.tv_usec
;
437 str
= mputprintf(str
, "%ld.%06ld", (long)diff
.tv_sec
, diff
.tv_usec
);
439 time_t tv_sec
= tv
->tv_sec
;
440 struct tm
*lt
= localtime(&tv_sec
);
441 if (lt
== NULL
) fatal_error("localtime() call failed.");
442 if (p_timestamp_format
== TIMESTAMP_TIME
) {
443 str
= mputprintf(str
, "%02d:%02d:%02d.%06ld",
444 lt
->tm_hour
, lt
->tm_min
, lt
->tm_sec
, tv
->tv_usec
);
446 static const char * const month_names
[] = { "Jan", "Feb", "Mar",
447 "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
448 str
= mputprintf(str
, "%4d/%s/%02d %02d:%02d:%02d.%06ld",
449 lt
->tm_year
+ 1900, month_names
[lt
->tm_mon
],
450 lt
->tm_mday
, lt
->tm_hour
, lt
->tm_min
, lt
->tm_sec
,
457 CHARSTRING
TTCN_Logger::get_timestamp_str(timestamp_format_t p_timestamp_format
)
460 if (gettimeofday(&tv
, NULL
) == -1)
461 fatal_error("gettimeofday() system call failed.");
462 char *str
= mputstr_timestamp(NULL
, p_timestamp_format
, &tv
);
463 CHARSTRING
ret_val(mstrlen(str
), str
);
468 CHARSTRING
TTCN_Logger::get_source_info_str(source_info_format_t
469 p_source_info_format
)
471 if (p_source_info_format
== SINFO_NONE
) return CHARSTRING();
472 char *source_info
= TTCN_Location::print_location(
473 p_source_info_format
== SINFO_STACK
, TRUE
, log_entity_name
);
474 if (source_info
== NULL
) return CHARSTRING('-');
475 CHARSTRING
ret_val(mstrlen(source_info
),source_info
);
480 /** @brief Logs a fatal error and terminates the application.
481 This function doesn't return: it calls \c exit(EXIT_FAILURE);
482 @param err_msg printf-style format string
484 void TTCN_Logger::fatal_error(const char *err_msg
, ...)
486 fputs("Fatal error during logging: ", stderr
);
488 va_start(p_var
, err_msg
);
489 vfprintf(stderr
, err_msg
, p_var
);
492 fputs(" Exiting.\n", stderr
);
496 void TTCN_Logger::initialize_logger()
498 console_log_mask
.component_id
.id_selector
= COMPONENT_ID_ALL
;
499 console_log_mask
.component_id
.id_compref
= ALL_COMPREF
;
500 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
501 console_log_mask
.mask
= Logging_Bits::default_console_mask
;
503 file_log_mask
.component_id
.id_selector
= COMPONENT_ID_ALL
;
504 file_log_mask
.component_id
.id_compref
= ALL_COMPREF
;
505 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
506 file_log_mask
.mask
= Logging_Bits::log_all
;
508 emergency_log_mask
.component_id
.id_selector
= COMPONENT_ID_ALL
;
509 emergency_log_mask
.component_id
.id_compref
= ALL_COMPREF
;
510 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
511 emergency_log_mask
.mask
= Logging_Bits::log_all
;
513 logmatch_buffer
= (char*)Malloc(MIN_BUFFER_SIZE
);
514 logmatch_buffer
[0] = '\0';
515 logmatch_buffer_len
= 0;
516 logmatch_buffer_size
= MIN_BUFFER_SIZE
;
519 void TTCN_Logger::terminate_logger()
521 // Get rid of plug-ins at first.
523 plugins_
->unload_plugins();
528 Free(executable_name
);
529 executable_name
= NULL
;
531 // Clean up the log masks. *_log_masks (which points to the start of
532 // actual_*_log_mask) is borrowed as the "next" pointer.
533 if (COMPONENT_ID_NAME
== console_log_mask
.component_id
.id_selector
) {
534 Free(console_log_mask
.component_id
.id_name
);
537 if (COMPONENT_ID_NAME
== file_log_mask
.component_id
.id_selector
) {
538 Free(file_log_mask
.component_id
.id_name
);
541 if (COMPONENT_ID_NAME
== emergency_log_mask
.component_id
.id_selector
) {
542 Free(emergency_log_mask
.component_id
.id_name
);
545 Free(logmatch_buffer
);
546 logmatch_buffer
= NULL
;
549 bool TTCN_Logger::is_logger_up()
551 if (logmatch_buffer
== NULL
) return FALSE
;
552 return get_logger_plugin_manager()->plugins_ready();
555 void TTCN_Logger::reset_configuration()
557 file_log_mask
.mask
= Logging_Bits::log_all
;
558 console_log_mask
.mask
= Logging_Bits::default_console_mask
;
559 emergency_log_mask
.mask
= Logging_Bits::log_all
;
561 timestamp_format
= TIMESTAMP_TIME
;
562 source_info_format
= SINFO_NONE
;
563 log_event_types
= LOGEVENTTYPES_NO
;
564 log_entity_name
= FALSE
;
566 get_logger_plugin_manager()->reset();
569 void TTCN_Logger::set_executable_name(const char *argv_0
)
571 Free(executable_name
);
572 size_t name_end
= strlen(argv_0
);
573 // Cut the '.exe' suffix from the end (if present).
574 if (name_end
>= 4 && !strncasecmp(argv_0
+ name_end
- 4, ".exe", 4))
576 size_t name_begin
= 0;
577 // Find the last '/' (if present) to cut the leading directory part.
578 for (int i
= name_end
- 1; i
>= 0; i
--) {
579 if (argv_0
[i
] == '/') {
584 int name_len
= name_end
- name_begin
;
586 executable_name
= (char*)Malloc(name_len
+ 1);
587 memcpy(executable_name
, argv_0
+ name_begin
, name_len
);
588 executable_name
[name_len
] = '\0';
589 } else executable_name
= NULL
;
592 bool TTCN_Logger::add_parameter(const logging_setting_t
& logging_param
)
594 return get_logger_plugin_manager()->add_parameter(logging_param
);
597 void TTCN_Logger::set_plugin_parameters(component component_reference
,
598 const char *component_name
)
600 get_logger_plugin_manager()->set_parameters(component_reference
,
604 void TTCN_Logger::load_plugins(component component_reference
,
605 const char *component_name
)
607 get_logger_plugin_manager()->load_plugins(component_reference
,
611 void TTCN_Logger::set_file_name(const char *new_filename_skeleton
,
614 // Pass the file's name to all plug-ins loaded. Not all of them is
615 // interested in this.
616 get_logger_plugin_manager()->
617 set_file_name(new_filename_skeleton
, from_config
);
620 bool TTCN_Logger::set_file_size(component_id_t
const& comp
, int p_size
)
622 return get_logger_plugin_manager()->set_file_size(comp
, p_size
);
625 bool TTCN_Logger::set_file_number(component_id_t
const& comp
, int p_number
)
627 return get_logger_plugin_manager()->set_file_number(comp
, p_number
);
630 bool TTCN_Logger::set_disk_full_action(component_id_t
const& comp
,
631 disk_full_action_t p_disk_full_action
)
633 return get_logger_plugin_manager()
634 ->set_disk_full_action(comp
, p_disk_full_action
);
637 void TTCN_Logger::set_start_time()
639 if (gettimeofday(&start_time
, NULL
) == -1) {
640 fatal_error("gettimeofday() system call failed.");
644 LoggerPluginManager
*TTCN_Logger::get_logger_plugin_manager()
646 if (!plugins_
) plugins_
= new LoggerPluginManager();
651 // These masks can control not only file and console! They're general purpose
652 // event filters, hence their name is not changed. Stay here.
653 void TTCN_Logger::set_file_mask(component_id_t
const& cmpt
, const Logging_Bits
& new_file_mask
)
655 // If FileMask was set with a component-specific value, do not allow
656 // overwriting with a generic value.
657 if (file_log_mask
.component_id
.id_selector
== COMPONENT_ID_COMPREF
658 && cmpt
.id_selector
== COMPONENT_ID_ALL
) return;
659 file_log_mask
.mask
= new_file_mask
;
660 if (cmpt
.id_selector
== COMPONENT_ID_NAME
) { // deep copy needed
661 if (file_log_mask
.component_id
.id_selector
== COMPONENT_ID_NAME
)
662 Free(file_log_mask
.component_id
.id_name
);
663 file_log_mask
.component_id
.id_selector
= COMPONENT_ID_NAME
;
664 file_log_mask
.component_id
.id_name
= mcopystr(cmpt
.id_name
);
665 } else file_log_mask
.component_id
= cmpt
;
668 void TTCN_Logger::set_console_mask(component_id_t
const& cmpt
, const Logging_Bits
& new_console_mask
)
670 // If ConsoleMask was set with a component-specific value, do not allow
671 // overwriting with a generic value.
672 if (console_log_mask
.component_id
.id_selector
== COMPONENT_ID_COMPREF
673 && cmpt
.id_selector
== COMPONENT_ID_ALL
) return;
674 console_log_mask
.mask
= new_console_mask
;
675 if (cmpt
.id_selector
== COMPONENT_ID_NAME
) { // deep copy needed
676 if (console_log_mask
.component_id
.id_selector
== COMPONENT_ID_NAME
)
677 Free(console_log_mask
.component_id
.id_name
);
678 console_log_mask
.component_id
.id_selector
= COMPONENT_ID_NAME
;
679 console_log_mask
.component_id
.id_name
= mcopystr(cmpt
.id_name
);
680 } else console_log_mask
.component_id
= cmpt
;
683 void TTCN_Logger::set_emergency_logging_mask(component_id_t
const& cmpt
, const Logging_Bits
& new_logging_mask
)
685 // If Emergency Logging Mask was set with a component-specific value, do not allow
686 // overwriting with a generic value.
687 if (emergency_log_mask
.component_id
.id_selector
== COMPONENT_ID_COMPREF
688 && cmpt
.id_selector
== COMPONENT_ID_ALL
) return;
689 emergency_log_mask
.mask
= new_logging_mask
;
690 if (cmpt
.id_selector
== COMPONENT_ID_NAME
) { // deep copy needed
691 if (emergency_log_mask
.component_id
.id_selector
== COMPONENT_ID_NAME
)
692 Free(emergency_log_mask
.component_id
.id_name
);
693 emergency_log_mask
.component_id
.id_selector
= COMPONENT_ID_NAME
;
694 emergency_log_mask
.component_id
.id_name
= mcopystr(cmpt
.id_name
);
695 } else emergency_log_mask
.component_id
= cmpt
;
698 void TTCN_Logger::set_emergency_logging_behaviour(emergency_logging_behaviour_t behaviour
)
700 emergency_logging_behaviour
= behaviour
;
703 TTCN_Logger::emergency_logging_behaviour_t
TTCN_Logger::get_emergency_logging_behaviour()
705 return emergency_logging_behaviour
;
708 size_t TTCN_Logger::get_emergency_logging()
710 return emergency_logging
;
713 void TTCN_Logger::set_emergency_logging(size_t size
)
715 emergency_logging
= size
;
718 Logging_Bits
const& TTCN_Logger::get_file_mask()
720 return file_log_mask
.mask
;
723 Logging_Bits
const& TTCN_Logger::get_console_mask()
725 return console_log_mask
.mask
;
728 Logging_Bits
const& TTCN_Logger::get_emergency_logging_mask()
730 return emergency_log_mask
.mask
;
733 void TTCN_Logger::register_plugin(const component_id_t comp
, char *identifier
, char *filename
)
735 get_logger_plugin_manager()->register_plugin(comp
, identifier
, filename
);
738 char *TTCN_Logger::get_logger_settings_str()
740 static const char *timestamp_format_names
[] = {
741 "Time", "DateTime", "Seconds"
743 static const char *logeventtype_names
[] = {
744 "No", "Yes", "Subcategories"
746 static const char *source_info_format_names
[] = {
747 "None", "Single", "Stack"
750 expstring_t filemask_origin
=
751 component_string(file_log_mask
.component_id
);
752 expstring_t consolemask_origin
=
753 component_string(console_log_mask
.component_id
);
754 expstring_t filemask_description
= file_log_mask
.mask
.describe();
755 expstring_t consolemask_description
= console_log_mask
.mask
.describe();
757 // Global options, common stuff for all plug-ins.
758 expstring_t new_log_message
= mprintf("TTCN Logger v%d.%d options: "
759 "TimeStampFormat:=%s; LogEntityName:=%s; LogEventTypes:=%s; "
760 "SourceInfoFormat:=%s; %s.FileMask:=%s; %s.ConsoleMask:=%s;",
761 TTCN_Logger::major_version
, TTCN_Logger::minor_version
,
762 timestamp_format_names
[timestamp_format
],
763 logeventtype_names
[log_entity_name
],
764 logeventtype_names
[log_event_types
],
765 source_info_format_names
[source_info_format
], filemask_origin
,
766 filemask_description
, consolemask_origin
, consolemask_description
);
768 Free(filemask_origin
);
769 Free(consolemask_origin
);
770 Free(filemask_description
);
771 Free(consolemask_description
);
773 return new_log_message
;
776 void TTCN_Logger::write_logger_settings(bool /*opening*/)
778 expstring_t new_log_message
= get_logger_settings_str();
780 // If we get called too early (and become buffered), the logger options
781 // must be updated. By default the initial values are used.
782 get_logger_plugin_manager()->log_log_options(new_log_message
,
783 mstrlen(new_log_message
));
785 Free(new_log_message
);
788 boolean
TTCN_Logger::should_log_to_file(TTCN_Logger::Severity sev
)
790 if (sev
> 0 && sev
< TTCN_Logger::NUMBER_OF_LOGSEVERITIES
) {
791 return file_log_mask
.mask
.bits
[sev
];
796 boolean
TTCN_Logger::should_log_to_console(TTCN_Logger::Severity sev
)
798 // CR_TR00015406: Always log external scripts to the console | MCTR.
799 if (sev
== TTCN_Logger::EXECUTOR_EXTCOMMAND
) return true;
800 if (sev
> 0 && sev
< TTCN_Logger::NUMBER_OF_LOGSEVERITIES
) {
801 return console_log_mask
.mask
.bits
[sev
];
806 boolean
TTCN_Logger::should_log_to_emergency(TTCN_Logger::Severity sev
)
808 if (sev
> 0 && sev
< TTCN_Logger::NUMBER_OF_LOGSEVERITIES
) {
809 return emergency_log_mask
.mask
.bits
[sev
];
814 void TTCN_Logger::set_timestamp_format(timestamp_format_t new_timestamp_format
)
816 timestamp_format
= new_timestamp_format
;
819 void TTCN_Logger::set_source_info_format(source_info_format_t new_source_info_format
)
821 source_info_format
= new_source_info_format
;
824 void TTCN_Logger::set_log_event_types(log_event_types_t new_log_event_types
)
826 log_event_types
= new_log_event_types
;
829 void TTCN_Logger::set_append_file(boolean new_append_file
)
831 get_logger_plugin_manager()->set_append_file(new_append_file
);
834 void TTCN_Logger::set_log_entity_name(boolean new_log_entity_name
)
836 log_entity_name
= new_log_entity_name
;
839 void TTCN_Logger::open_file()
841 get_logger_plugin_manager()->open_file();
844 void TTCN_Logger::close_file()
846 get_logger_plugin_manager()->close_file();
849 void TTCN_Logger::ring_buffer_dump(bool do_close_file
)
851 get_logger_plugin_manager()->ring_buffer_dump(do_close_file
);
854 unsigned int TTCN_Logger::get_mask()
856 TTCN_warning("TTCN_Logger::get_mask() is deprecated, please use "
857 "TTCN_Logger::should_log_to_file() or "
858 "TTCN_Logger::should_log_to_console() instead.");
859 return LOG_ALL_IMPORTANT
| MATCHING_UNQUALIFIED
| DEBUG_UNQUALIFIED
;
862 TTCN_Logger::matching_verbosity_t
TTCN_Logger::get_matching_verbosity()
864 return matching_verbosity
;
867 void TTCN_Logger::set_matching_verbosity(TTCN_Logger::matching_verbosity_t v
)
869 matching_verbosity
= v
;
872 // Called from the generated code and many more places... Stay here. The
873 // existence of the file descriptors etc. is the responsibility of the
875 boolean
TTCN_Logger::log_this_event(TTCN_Logger::Severity event_severity
)
877 //ToDO: emergency logging = true
878 if (should_log_to_file(event_severity
)) return TRUE
;
879 else if (should_log_to_console(event_severity
)) return TRUE
;
880 else if (should_log_to_emergency(event_severity
) && (get_emergency_logging() > 0)) return TRUE
;
884 void TTCN_Logger::log(TTCN_Logger::Severity msg_severity
,
885 const char *fmt_str
, ...)
888 va_start(p_var
, fmt_str
);
889 log_va_list(msg_severity
, fmt_str
, p_var
);
893 void TTCN_Logger::send_event_as_error()
895 char* error_msg
= get_logger_plugin_manager()->get_current_event_str();
899 if (TTCN_Communication::is_mc_connected()) {
900 TTCN_Communication::send_error("%s", error_msg
);
902 fprintf(stderr
, "%s\n", error_msg
);
907 // Part of the external interface. Don't touch.
908 void TTCN_Logger::log_str(TTCN_Logger::Severity msg_severity
,
911 if (!log_this_event(msg_severity
)) return;
913 str_ptr
= "<NULL pointer>";
914 get_logger_plugin_manager()->log_unhandled_event(msg_severity
,
915 str_ptr
, strlen(str_ptr
));
916 logmatch_printed
= false;
919 void TTCN_Logger::log_va_list(TTCN_Logger::Severity msg_severity
,
920 const char *fmt_str
, va_list p_var
)
922 get_logger_plugin_manager()->log_va_list(msg_severity
, fmt_str
, p_var
);
923 logmatch_printed
= false;
926 void TTCN_Logger::begin_event(TTCN_Logger::Severity msg_severity
, boolean log2str
)
928 get_logger_plugin_manager()->begin_event(msg_severity
, log2str
);
931 void TTCN_Logger::end_event()
933 get_logger_plugin_manager()->end_event();
934 // TODO: Find another place for these...
935 logmatch_printed
= false;
938 CHARSTRING
TTCN_Logger::end_event_log2str()
940 CHARSTRING ret_val
= get_logger_plugin_manager()->end_event_log2str();
941 logmatch_printed
= false;
945 void TTCN_Logger::finish_event()
947 get_logger_plugin_manager()->finish_event();
950 void TTCN_Logger::log_event(const char *fmt_str
, ...)
953 va_start(p_var
, fmt_str
);
954 log_event_va_list(fmt_str
, p_var
);
958 void TTCN_Logger::log_event_str(const char *str_ptr
)
960 get_logger_plugin_manager()->log_event_str(str_ptr
);
961 logmatch_printed
= false;
964 void TTCN_Logger::log_event_va_list(const char *fmt_str
, va_list p_var
)
966 get_logger_plugin_manager()->log_event_va_list(fmt_str
, p_var
);
967 logmatch_printed
= false;
970 void TTCN_Logger::log_event_unbound()
972 switch (data_log_format
) {
974 log_event_str("<unbound>");
980 log_event_str("<unknown>");
984 void TTCN_Logger::log_event_uninitialized()
986 switch (data_log_format
) {
988 log_event_str("<uninitialized template>");
994 log_event_str("<unknown>");
998 void TTCN_Logger::log_event_enum(const char* enum_name_str
, int enum_value
)
1000 switch (data_log_format
) {
1002 TTCN_Logger::log_event("%s (%d)", enum_name_str
, enum_value
);
1005 log_event_str(enum_name_str
);
1008 log_event_str("<unknown>");
1012 void TTCN_Logger::log_char(char c
)
1014 get_logger_plugin_manager()->log_char(c
);
1015 logmatch_printed
= false;
1018 boolean
TTCN_Logger::is_printable(unsigned char c
)
1020 if (!isascii(c
)) return FALSE
;
1021 else if (isprint(c
)) return TRUE
;
1038 void TTCN_Logger::log_char_escaped(unsigned char c
)
1042 log_event_str("\\n");
1045 log_event_str("\\t");
1048 log_event_str("\\v");
1051 log_event_str("\\b");
1054 log_event_str("\\r");
1057 log_event_str("\\f");
1060 log_event_str("\\a");
1063 log_event_str("\\\\");
1066 log_event_str("\\\"");
1069 if (isprint(c
)) log_char(c
);
1070 else log_event("\\%03o", c
);
1075 void TTCN_Logger::log_char_escaped(unsigned char c
, char*& p_buffer
) {
1078 p_buffer
= mputstr(p_buffer
, "\\n");
1081 p_buffer
= mputstr(p_buffer
, "\\t");
1084 p_buffer
= mputstr(p_buffer
, "\\v");
1087 p_buffer
= mputstr(p_buffer
, "\\b");
1090 p_buffer
= mputstr(p_buffer
, "\\r");
1093 p_buffer
= mputstr(p_buffer
, "\\f");
1096 p_buffer
= mputstr(p_buffer
, "\\a");
1099 p_buffer
= mputstr(p_buffer
, "\\\\");
1102 p_buffer
= mputstr(p_buffer
, "\\\"");
1105 if (isprint(c
)) p_buffer
= mputc(p_buffer
, c
);
1107 p_buffer
= mputprintf(p_buffer
, "\\%03o", c
);
1112 static const char hex_digits
[] = { '0', '1', '2', '3', '4', '5', '6', '7',
1113 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1115 void TTCN_Logger::log_hex(unsigned char nibble
)
1117 if (nibble
< 16) log_char(hex_digits
[nibble
]);
1118 else log_event_str("<unknown>");
1121 void TTCN_Logger::log_octet(unsigned char octet
)
1123 log_char(hex_digits
[octet
>> 4]);
1124 log_char(hex_digits
[octet
& 0x0F]);
1127 void TTCN_Logger::OS_error()
1130 const char *error_string
= strerror(errno
);
1131 if (error_string
!= NULL
) log_event(" (%s)", error_string
);
1132 else log_event(" (Unknown error: errno = %d)", errno
);
1137 void TTCN_Logger::log_timer_read(const char *timer_name
,
1140 get_logger_plugin_manager()->log_timer_read(timer_name
, timeout_val
);
1143 void TTCN_Logger::log_timer_start(const char *timer_name
, double start_val
)
1145 get_logger_plugin_manager()->log_timer_start(timer_name
, start_val
);
1148 void TTCN_Logger::log_timer_guard(double start_val
)
1150 get_logger_plugin_manager()->log_timer_guard(start_val
);
1153 void TTCN_Logger::log_timer_stop(const char *timer_name
, double stop_val
)
1155 get_logger_plugin_manager()->log_timer_stop(timer_name
, stop_val
);
1158 void TTCN_Logger::log_timer_timeout(const char *timer_name
,
1161 get_logger_plugin_manager()->log_timer_timeout(timer_name
, timeout_val
);
1164 void TTCN_Logger::log_timer_any_timeout()
1166 get_logger_plugin_manager()->log_timer_any_timeout();
1169 void TTCN_Logger::log_timer_unqualified(const char *message
)
1171 get_logger_plugin_manager()->log_timer_unqualified(message
);
1174 void TTCN_Logger::log_testcase_started(const qualified_name
& testcase_name
)
1176 get_logger_plugin_manager()->log_testcase_started(testcase_name
);
1179 void TTCN_Logger::log_testcase_finished(const qualified_name
& testcase_name
,
1180 verdicttype verdict
,
1183 get_logger_plugin_manager()->log_testcase_finished(testcase_name
, verdict
, reason
);
1186 void TTCN_Logger::log_setverdict(verdicttype new_verdict
, verdicttype old_verdict
,
1187 verdicttype local_verdict
, const char *old_reason
, const char *new_reason
)
1189 get_logger_plugin_manager()->log_setverdict(new_verdict
, old_verdict
,
1190 local_verdict
, old_reason
, new_reason
);
1193 void TTCN_Logger::log_getverdict(verdicttype verdict
)
1195 get_logger_plugin_manager()->log_getverdict(verdict
);
1198 void TTCN_Logger::log_final_verdict(bool is_ptc
, verdicttype ptc_verdict
,
1199 verdicttype local_verdict
, verdicttype new_verdict
,
1200 const char *verdict_reason
, int notification
, int ptc_compref
,
1201 const char *ptc_name
)
1203 get_logger_plugin_manager()->log_final_verdict(is_ptc
, ptc_verdict
,
1204 local_verdict
, new_verdict
, verdict_reason
, notification
, ptc_compref
, ptc_name
);
1207 void TTCN_Logger::log_controlpart_start_stop(const char *module_name
, int finished
)
1209 get_logger_plugin_manager()->log_controlpart_start_stop(module_name
, finished
);
1212 void TTCN_Logger::log_controlpart_errors(unsigned int error_count
)
1214 get_logger_plugin_manager()->log_controlpart_errors(error_count
);
1217 void TTCN_Logger::log_verdict_statistics(size_t none_count
, double none_percent
,
1218 size_t pass_count
, double pass_percent
,
1219 size_t inconc_count
, double inconc_percent
,
1220 size_t fail_count
, double fail_percent
,
1221 size_t error_count
, double error_percent
)
1223 get_logger_plugin_manager()->log_verdict_statistics(none_count
, none_percent
,
1224 pass_count
, pass_percent
,
1225 inconc_count
, inconc_percent
,
1226 fail_count
, fail_percent
,
1227 error_count
, error_percent
);
1230 void TTCN_Logger::log_defaultop_activate(const char *name
, int id
)
1232 get_logger_plugin_manager()->log_defaultop_activate(name
, id
);
1235 void TTCN_Logger::log_defaultop_deactivate(const char *name
, int id
)
1237 get_logger_plugin_manager()->log_defaultop_deactivate(name
, id
);
1240 void TTCN_Logger::log_defaultop_exit(const char *name
, int id
, int x
)
1242 get_logger_plugin_manager()->log_defaultop_exit(name
, id
, x
);
1245 void TTCN_Logger::log_executor_runtime(int reason
)
1247 get_logger_plugin_manager()->log_executor_runtime(reason
);
1250 void TTCN_Logger::log_HC_start(const char *host
)
1252 get_logger_plugin_manager()->log_HC_start(host
);
1255 void TTCN_Logger::log_fd_limits(int fd_limit
, long fd_set_size
)
1257 get_logger_plugin_manager()->log_fd_limits(fd_limit
, fd_set_size
);
1260 void TTCN_Logger::log_testcase_exec(const char *module
, const char *tc
)
1262 get_logger_plugin_manager()->log_testcase_exec(module
, tc
);
1265 void TTCN_Logger::log_module_init(const char *module
, bool finish
)
1267 get_logger_plugin_manager()->log_module_init(module
, finish
);
1270 void TTCN_Logger::log_mtc_created(long pid
)
1272 get_logger_plugin_manager()->log_mtc_created(pid
);
1275 void TTCN_Logger::log_configdata(int reason
, const char *str
)
1277 get_logger_plugin_manager()->log_configdata(reason
, str
);
1280 void TTCN_Logger::log_executor_component(int reason
)
1282 get_logger_plugin_manager()->log_executor_component(reason
);
1285 void TTCN_Logger::log_executor_misc(int reason
, const char *name
,
1286 const char *address
, int port
)
1288 get_logger_plugin_manager()->log_executor_misc(reason
, name
, address
, port
);
1291 void TTCN_Logger::log_extcommand(extcommand_t action
, const char *cmd
)
1293 get_logger_plugin_manager()->log_extcommand(action
, cmd
);
1296 void TTCN_Logger::log_matching_done(const char *type
, int ptc
,
1297 const char *return_type
, int reason
)
1299 get_logger_plugin_manager()->log_matching_done(reason
, type
, ptc
, return_type
);
1302 void TTCN_Logger::log_matching_problem(int reason
, int operation
, boolean check
,
1303 boolean anyport
, const char *port_name
)
1305 get_logger_plugin_manager()->log_matching_problem(reason
, operation
,
1306 check
, anyport
, port_name
);
1309 void TTCN_Logger::log_matching_success(int port_type
, const char *port_name
,
1310 int compref
, const CHARSTRING
& info
)
1312 get_logger_plugin_manager()->log_matching_success(port_type
, port_name
,
1316 void TTCN_Logger::log_matching_failure(int port_type
, const char *port_name
,
1317 int compref
, int reason
, const CHARSTRING
& info
)
1319 get_logger_plugin_manager()->log_matching_failure(port_type
, port_name
,
1320 compref
, reason
, info
);
1323 void TTCN_Logger::log_matching_timeout(const char *timer_name
)
1325 get_logger_plugin_manager()->log_matching_timeout(timer_name
);
1328 void TTCN_Logger::log_portconnmap(int operation
, int src_compref
, const char *src_port
,
1329 int dst_compref
, const char *dst_port
)
1331 get_logger_plugin_manager()->log_portconnmap(operation
, src_compref
, src_port
,
1332 dst_compref
, dst_port
);
1335 void TTCN_Logger::log_par_ptc(int reason
, const char *module
, const char *name
,
1336 int compref
, const char *compname
, const char *tc_loc
, int alive_pid
, int status
)
1338 get_logger_plugin_manager()->log_par_ptc(reason
, module
, name
, compref
,
1339 compname
, tc_loc
, alive_pid
, status
);
1342 void TTCN_Logger::log_port_queue(int operation
, const char *port_name
, int compref
,
1343 int id
, const CHARSTRING
& address
, const CHARSTRING
& param
)
1345 get_logger_plugin_manager()->log_port_queue(operation
, port_name
, compref
,
1346 id
, address
, param
);
1349 void TTCN_Logger::log_port_state(int operation
, const char *port_name
)
1351 get_logger_plugin_manager()->log_port_state(operation
, port_name
);
1354 void TTCN_Logger::log_procport_send(const char *portname
, int operation
, int compref
,
1355 const CHARSTRING
& system
, const CHARSTRING
& param
)
1357 get_logger_plugin_manager()->log_procport_send(portname
, operation
, compref
,
1361 void TTCN_Logger::log_procport_recv(const char *portname
, int operation
,
1362 int compref
, boolean check
, const CHARSTRING
& param
, int id
)
1364 get_logger_plugin_manager()->log_procport_recv(portname
, operation
, compref
,
1368 void TTCN_Logger::log_msgport_send(const char *portname
, int compref
,
1369 const CHARSTRING
& param
)
1371 get_logger_plugin_manager()->log_msgport_send(portname
, compref
, param
);
1374 void TTCN_Logger::log_msgport_recv(const char *portname
, int operation
, int compref
,
1375 const CHARSTRING
& system
, const CHARSTRING
& param
, int id
)
1377 get_logger_plugin_manager()->log_msgport_recv(portname
, operation
, compref
,
1381 void TTCN_Logger::log_dualport_map(boolean incoming
, const char *target_type
,
1382 const CHARSTRING
& value
, int id
)
1384 get_logger_plugin_manager()->log_dualport_map(incoming
, target_type
, value
, id
);
1387 void TTCN_Logger::log_dualport_discard(boolean incoming
, const char *target_type
,
1388 const char *port_name
, boolean unhandled
)
1390 get_logger_plugin_manager()->log_dualport_discard(incoming
, target_type
, port_name
,
1394 void TTCN_Logger::log_port_misc(int reason
, const char *port_name
,
1395 int remote_component
, const char *remote_port
,
1396 const char *ip_address
, int tcp_port
, int new_size
)
1398 get_logger_plugin_manager()->log_port_misc(reason
, port_name
,
1399 remote_component
, remote_port
, ip_address
, tcp_port
, new_size
);
1402 void TTCN_Logger::log_random(int action
, double v
, unsigned long u
)
1404 get_logger_plugin_manager()->log_random(action
, v
, u
);
1407 void TTCN_Logger::clear_parameters() {
1408 get_logger_plugin_manager()->clear_param_list();
1409 get_logger_plugin_manager()->clear_plugin_list();
1412 // The one instance (only for backward compatibility).
1413 TTCN_Logger TTCN_logger
;
1415 // Location related stuff.
1416 TTCN_Location
*TTCN_Location::innermost_location
= NULL
,
1417 *TTCN_Location::outermost_location
= NULL
;
1419 TTCN_Location::TTCN_Location(const char *par_file_name
,
1420 unsigned int par_line_number
, entity_type_t par_entity_type
,
1421 const char *par_entity_name
)
1422 : file_name(par_file_name
), line_number(par_line_number
),
1423 entity_type(par_entity_type
), entity_name(par_entity_name
),
1424 inner_location(NULL
), outer_location(innermost_location
)
1426 if (par_file_name
== NULL
) file_name
= "<unknown file>";
1427 if (par_entity_type
== LOCATION_UNKNOWN
) entity_name
= NULL
;
1428 else if (par_entity_name
== NULL
) entity_name
= "<unknown>";
1429 if (outer_location
!= NULL
) outer_location
->inner_location
= this;
1430 else outermost_location
= this;
1431 innermost_location
= this;
1434 void TTCN_Location::update_lineno(unsigned int new_lineno
)
1436 line_number
= new_lineno
;
1439 TTCN_Location::~TTCN_Location()
1441 if (inner_location
== NULL
) innermost_location
= outer_location
;
1442 else inner_location
->outer_location
= outer_location
;
1443 if (outer_location
== NULL
) outermost_location
= inner_location
;
1444 else outer_location
->inner_location
= inner_location
;
1447 char *TTCN_Location::print_location(boolean print_outers
,
1448 boolean print_innermost
, boolean print_entity_name
)
1450 char *ret_val
= NULL
;
1451 if (innermost_location
!= NULL
) {
1453 for (TTCN_Location
*iter
= outermost_location
;
1454 iter
!= NULL
&& iter
!= innermost_location
;
1455 iter
= iter
->inner_location
)
1456 ret_val
= iter
->append_contents(ret_val
, print_entity_name
);
1458 if (print_innermost
)
1459 ret_val
= innermost_location
->append_contents(ret_val
,
1465 void TTCN_Location::strip_entity_name(char*& par_str
)
1467 if (!par_str
) return;
1468 char *new_str
= NULL
;
1469 bool in_paren
= false;
1470 for (char *str_ptr
= par_str
; *str_ptr
!= '\0' ; str_ptr
++) {
1479 if (!in_paren
) new_str
= mputc(new_str
, *str_ptr
);
1487 char *TTCN_Location::append_contents(char *par_str
,
1488 boolean print_entity_name
) const
1490 if (par_str
!= NULL
) par_str
= mputstr(par_str
, "->");
1491 par_str
= mputprintf(par_str
, "%s:%u", file_name
, line_number
);
1492 if (print_entity_name
) {
1493 switch (entity_type
) {
1494 case LOCATION_CONTROLPART
:
1495 par_str
= mputprintf(par_str
, "(controlpart:%s)", entity_name
);
1497 case LOCATION_TESTCASE
:
1498 par_str
= mputprintf(par_str
, "(testcase:%s)", entity_name
);
1500 case LOCATION_ALTSTEP
:
1501 par_str
= mputprintf(par_str
, "(altstep:%s)", entity_name
);
1503 case LOCATION_FUNCTION
:
1504 par_str
= mputprintf(par_str
, "(function:%s)", entity_name
);
1506 case LOCATION_EXTERNALFUNCTION
:
1507 par_str
= mputprintf(par_str
, "(externalfunction:%s)", entity_name
);
1509 case LOCATION_TEMPLATE
:
1510 par_str
= mputprintf(par_str
, "(template:%s)", entity_name
);
1519 TTCN_Location_Statistics::TTCN_Location_Statistics(const char *par_file_name
,
1520 unsigned int par_line_number
, entity_type_t par_entity_type
,
1521 const char *par_entity_name
): TTCN_Location(par_file_name
, par_line_number
,
1522 par_entity_type
, par_entity_name
)
1524 TCov::hit(file_name
, line_number
, entity_name
);
1527 void TTCN_Location_Statistics::update_lineno(unsigned int new_lineno
)
1529 TTCN_Location::update_lineno(new_lineno
);
1530 TCov::hit(file_name
, line_number
);
1533 void TTCN_Location_Statistics::init_file_lines(const char *file_name
, const int line_nos
[], size_t line_nos_len
)
1535 TCov::init_file_lines(file_name
, line_nos
, line_nos_len
);
1538 void TTCN_Location_Statistics::init_file_functions(const char *file_name
, const char *function_names
[], size_t function_names_len
)
1540 TCov::init_file_functions(file_name
, function_names
, function_names_len
);
1543 TTCN_Location_Statistics::~TTCN_Location_Statistics() { }
1545 expstring_t
component_string(const component_id_t
& comp_id
)
1548 switch( comp_id
.id_selector
) {
1549 case COMPONENT_ID_NAME
:
1550 retval
= mcopystr(comp_id
.id_name
);
1552 case COMPONENT_ID_COMPREF
:
1553 retval
= mprintf("%d", comp_id
.id_compref
);
1555 case COMPONENT_ID_ALL
:
1556 retval
= mcopystr("*");
1558 case COMPONENT_ID_SYSTEM
:
1559 retval
= mcopystr("<System>");
1561 default: // Can't happen.
1562 retval
= mcopystr("Unknown component type !");