1 /******************************************************************************
2 * Copyright (c) 2000-2016 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
18 * Szabo, Janos Zoltan – initial implementation
19 * Zalanyi, Balazs Andor
22 ******************************************************************************/
33 #include <sys/types.h>
35 #include "../common/memory.h"
37 #include "Communication.hh"
38 #include "Component.hh"
39 #include "LoggingBits.hh"
40 #include "LoggerPluginManager.hh"
41 #include "Charstring.hh"
42 #include "LoggingParam.hh"
45 /** work-around for missing va_copy() in GCC */
46 #if defined(__GNUC__) && !defined(va_copy)
48 # define va_copy(dest, src) __va_copy(dest, src)
50 # define va_copy(dest, src) (dest) = (src)
54 #define MIN_BUFFER_SIZE 1024
57 /** @brief Return a string identifying the component
59 If \p comp.id_selector is COMPONENT_ID_NAME, returns \p comp.id_name
61 If \p comp.id_selector is COMPONENT_ID_COMPREF, returns a pointer
62 to a static buffer, containing a string representation of \p comp.id_compref
64 If \p comp.id_selector is COMPONENT_ID_ALL, returns "All".
66 If \p comp.id_selector is COMPONENT_ID_SYSTEM, returns "System".
68 @param comp component identifier
71 expstring_t
component_string(const component_id_t
& comp
);
74 /** @name Private data structures
80 For TTCN_Logger internal use, no user serviceable parts.
82 struct TTCN_Logger::log_mask_struct
84 component_id_t component_id
; /**< Component */
85 Logging_Bits mask
; /**< Settings for logging to console or file */
94 LoggerPluginManager
*TTCN_Logger::plugins_
= NULL
;
96 /* No point in initializing here; will be done in initialize_logger() */
97 TTCN_Logger::log_mask_struct
TTCN_Logger::console_log_mask
;
98 TTCN_Logger::log_mask_struct
TTCN_Logger::file_log_mask
;
99 TTCN_Logger::log_mask_struct
TTCN_Logger::emergency_log_mask
;
101 TTCN_Logger::emergency_logging_behaviour_t
TTCN_Logger::emergency_logging_behaviour
= BUFFER_MASKED
;
102 size_t TTCN_Logger::emergency_logging
;
103 boolean
TTCN_Logger::emergency_logging_for_fail_verdict
= FALSE
;
105 TTCN_Logger::matching_verbosity_t
TTCN_Logger::matching_verbosity
= VERBOSITY_COMPACT
;
107 /** Timestamp format in the log files. */
108 TTCN_Logger::timestamp_format_t
TTCN_Logger::timestamp_format
= TIMESTAMP_TIME
;
110 /** LogSourceInfo/SourceInfoFormat */
111 TTCN_Logger::source_info_format_t
TTCN_Logger::source_info_format
= SINFO_SINGLE
;
114 TTCN_Logger::log_event_types_t
TTCN_Logger::log_event_types
= LOGEVENTTYPES_NO
;
116 // This array should contain all the _UNQUALIFIED severities.
117 const TTCN_Logger::Severity
TTCN_Logger::sev_categories
[] =
119 TTCN_Logger::NOTHING_TO_LOG
, // 0
120 TTCN_Logger::ACTION_UNQUALIFIED
, // 1
121 TTCN_Logger::DEFAULTOP_UNQUALIFIED
, // 5
122 TTCN_Logger::ERROR_UNQUALIFIED
, // 6
123 TTCN_Logger::EXECUTOR_UNQUALIFIED
, // 12
124 TTCN_Logger::FUNCTION_UNQUALIFIED
, // 14
125 TTCN_Logger::PARALLEL_UNQUALIFIED
, // 18
126 TTCN_Logger::TESTCASE_UNQUALIFIED
, // 21
127 TTCN_Logger::PORTEVENT_UNQUALIFIED
, // 35
128 TTCN_Logger::STATISTICS_UNQUALIFIED
, // 37
129 TTCN_Logger::TIMEROP_UNQUALIFIED
, // 43
130 TTCN_Logger::USER_UNQUALIFIED
, // 44
131 TTCN_Logger::VERDICTOP_UNQUALIFIED
, // 48
132 TTCN_Logger::WARNING_UNQUALIFIED
, // 49
133 TTCN_Logger::MATCHING_UNQUALIFIED
, // 61
134 TTCN_Logger::DEBUG_UNQUALIFIED
, // 66
137 const char* TTCN_Logger::severity_category_names
[] =
158 /** Sub-category names for all Severity enum values,
159 * used when TTCN_Logger::log_event_types is set to log sub-categories */
160 const char* TTCN_Logger::severity_subcategory_names
[NUMBER_OF_LOGSEVERITIES
] = {
245 char* TTCN_Logger::logmatch_buffer
= NULL
;
246 size_t TTCN_Logger::logmatch_buffer_len
= 0;
247 size_t TTCN_Logger::logmatch_buffer_size
= 0;
248 boolean
TTCN_Logger::logmatch_printed
= false;
250 // TODO: Matching related stuff stays here for now. It just appends the
251 // string to the end of the current (active) event.
252 size_t TTCN_Logger::get_logmatch_buffer_len()
254 return logmatch_buffer_len
;
257 void TTCN_Logger::set_logmatch_buffer_len(size_t new_len
)
259 logmatch_buffer_len
= new_len
;
260 logmatch_buffer_size
= MIN_BUFFER_SIZE
;
261 while (logmatch_buffer_size
< new_len
)
262 logmatch_buffer_size
*= 2;
263 logmatch_buffer
= (char *)Realloc(logmatch_buffer
, logmatch_buffer_size
);
264 logmatch_buffer
[new_len
] = '\0';
267 void TTCN_Logger::print_logmatch_buffer()
269 if (logmatch_printed
) TTCN_Logger::log_event_str(" , ");
270 else logmatch_printed
= true;
271 if (logmatch_buffer_size
> 0)
272 TTCN_Logger::log_event_str(logmatch_buffer
);
275 void TTCN_Logger::log_logmatch_info(const char *fmt_str
, ...)
278 va_start(p_var
, fmt_str
);
280 if (fmt_str
== NULL
) fmt_str
= "<NULL format string>";
282 size_t free_space
= logmatch_buffer_size
- logmatch_buffer_len
;
283 // Make a copy of p_var to allow multiple calls of vsnprintf().
285 va_copy(p_var2
, p_var
);
286 int fragment_len
= vsnprintf(logmatch_buffer
+ logmatch_buffer_len
,
287 free_space
, fmt_str
, p_var2
);
289 if (fragment_len
< 0) set_logmatch_buffer_len(logmatch_buffer_size
* 2);
290 else if ((size_t)fragment_len
>= free_space
)
291 set_logmatch_buffer_len(logmatch_buffer_len
+ fragment_len
+ 1);
293 logmatch_buffer_len
+= fragment_len
;
300 /** The "beginning of time" for the logger (seconds and microseconds
303 struct timeval
TTCN_Logger::start_time
;
305 /** The base name of the current executable (no path, no extension) */
306 char *TTCN_Logger::executable_name
= NULL
;
308 /// True to log type (controlpart/altstep/testcase/function/...) and name
309 /// of the entity responsible for the log message, false to suppress it.
310 boolean
TTCN_Logger::log_entity_name
= FALSE
;
312 /// The default log format is the legacy (original) format.
313 TTCN_Logger::data_log_format_t
TTCN_Logger::data_log_format
= LF_LEGACY
;
317 /** @brief Equality operator for component_id_t
319 @param left component identifier
320 @param right component identifier
321 @return true if \p left and \p right refer to the same component
323 @note This functions tests the equality of the component identifiers,
324 not the components themselves. It can't detect that component named "foo" is
325 the same as component number 3.
327 @li If the selectors differ, returns \c false.
328 @li If both selectors are COMPONENT_ID_NAME, compares the names.
329 @li If both selectors are COMPONENT_ID_COMPREF, compares the comp. references.
330 @li If both selectors are COMPONENT_ID_ALL or COMPONENT_ID_SYSTEM,
334 bool operator==(const component_id_t
& left
, const component_id_t
& right
)
336 if (left
.id_selector
!= right
.id_selector
)
339 // The selectors are the same.
340 switch (left
.id_selector
) {
341 case COMPONENT_ID_NAME
:
342 return !strcmp(left
.id_name
, right
.id_name
);
343 case COMPONENT_ID_COMPREF
:
344 return left
.id_compref
== right
.id_compref
;
345 default: // Should be MTC or SYSTEM; identified by the selector.
350 char *TTCN_Logger::mputstr_severity(char *str
, const TTCN_Logger::Severity
& severity
)
353 case TTCN_Logger::ACTION_UNQUALIFIED
:
354 return mputstr(str
, "ACTION");
355 case TTCN_Logger::DEFAULTOP_ACTIVATE
:
356 case TTCN_Logger::DEFAULTOP_DEACTIVATE
:
357 case TTCN_Logger::DEFAULTOP_EXIT
:
358 case TTCN_Logger::DEFAULTOP_UNQUALIFIED
:
359 return mputstr(str
, "DEFAULTOP");
360 case TTCN_Logger::ERROR_UNQUALIFIED
:
361 return mputstr(str
, "ERROR");
362 case TTCN_Logger::EXECUTOR_RUNTIME
:
363 case TTCN_Logger::EXECUTOR_CONFIGDATA
:
364 case TTCN_Logger::EXECUTOR_EXTCOMMAND
:
365 case TTCN_Logger::EXECUTOR_COMPONENT
:
366 case TTCN_Logger::EXECUTOR_LOGOPTIONS
:
367 case TTCN_Logger::EXECUTOR_UNQUALIFIED
:
368 return mputstr(str
, "EXECUTOR");
369 case TTCN_Logger::FUNCTION_RND
:
370 case TTCN_Logger::FUNCTION_UNQUALIFIED
:
371 return mputstr(str
, "FUNCTION");
372 case TTCN_Logger::PARALLEL_PTC
:
373 case TTCN_Logger::PARALLEL_PORTCONN
:
374 case TTCN_Logger::PARALLEL_PORTMAP
:
375 case TTCN_Logger::PARALLEL_UNQUALIFIED
:
376 return mputstr(str
, "PARALLEL");
377 case TTCN_Logger::TESTCASE_START
:
378 case TTCN_Logger::TESTCASE_FINISH
:
379 case TTCN_Logger::TESTCASE_UNQUALIFIED
:
380 return mputstr(str
, "TESTCASE");
381 case TTCN_Logger::PORTEVENT_PQUEUE
:
382 case TTCN_Logger::PORTEVENT_MQUEUE
:
383 case TTCN_Logger::PORTEVENT_STATE
:
384 case TTCN_Logger::PORTEVENT_PMIN
:
385 case TTCN_Logger::PORTEVENT_PMOUT
:
386 case TTCN_Logger::PORTEVENT_PCIN
:
387 case TTCN_Logger::PORTEVENT_PCOUT
:
388 case TTCN_Logger::PORTEVENT_MMRECV
:
389 case TTCN_Logger::PORTEVENT_MMSEND
:
390 case TTCN_Logger::PORTEVENT_MCRECV
:
391 case TTCN_Logger::PORTEVENT_MCSEND
:
392 case TTCN_Logger::PORTEVENT_DUALRECV
:
393 case TTCN_Logger::PORTEVENT_DUALSEND
:
394 case TTCN_Logger::PORTEVENT_UNQUALIFIED
:
395 return mputstr(str
, "PORTEVENT");
396 case TTCN_Logger::STATISTICS_VERDICT
:
397 case TTCN_Logger::STATISTICS_UNQUALIFIED
:
398 return mputstr(str
, "STATISTICS");
399 case TTCN_Logger::TIMEROP_READ
:
400 case TTCN_Logger::TIMEROP_START
:
401 case TTCN_Logger::TIMEROP_GUARD
:
402 case TTCN_Logger::TIMEROP_STOP
:
403 case TTCN_Logger::TIMEROP_TIMEOUT
:
404 case TTCN_Logger::TIMEROP_UNQUALIFIED
:
405 return mputstr(str
, "TIMEROP");
406 case TTCN_Logger::USER_UNQUALIFIED
:
407 return mputstr(str
, "USER");
409 case TTCN_Logger::VERDICTOP_GETVERDICT
:
410 case TTCN_Logger::VERDICTOP_SETVERDICT
:
411 case TTCN_Logger::VERDICTOP_FINAL
:
412 case TTCN_Logger::VERDICTOP_UNQUALIFIED
:
413 return mputstr(str
, "VERDICTOP");
414 case TTCN_Logger::WARNING_UNQUALIFIED
:
415 return mputstr(str
, "WARNING");
416 case TTCN_Logger::MATCHING_DONE
:
417 case TTCN_Logger::MATCHING_TIMEOUT
:
418 case TTCN_Logger::MATCHING_PCSUCCESS
:
419 case TTCN_Logger::MATCHING_PCUNSUCC
:
420 case TTCN_Logger::MATCHING_PMSUCCESS
:
421 case TTCN_Logger::MATCHING_PMUNSUCC
:
422 case TTCN_Logger::MATCHING_MCSUCCESS
:
423 case TTCN_Logger::MATCHING_MCUNSUCC
:
424 case TTCN_Logger::MATCHING_MMSUCCESS
:
425 case TTCN_Logger::MATCHING_MMUNSUCC
:
426 case TTCN_Logger::MATCHING_PROBLEM
:
427 case TTCN_Logger::MATCHING_UNQUALIFIED
:
428 return mputstr(str
, "MATCHING");
429 case TTCN_Logger::DEBUG_ENCDEC
:
430 case TTCN_Logger::DEBUG_TESTPORT
:
431 case TTCN_Logger::DEBUG_USER
:
432 case TTCN_Logger::DEBUG_FRAMEWORK
:
433 case TTCN_Logger::DEBUG_UNQUALIFIED
:
434 return mputstr(str
, "DEBUG");
436 return mputstr(str
, "UNKNOWN");
440 char *TTCN_Logger::mputstr_timestamp(char *str
,
441 timestamp_format_t p_timestamp_format
,
442 const struct timeval
*tv
)
444 if (p_timestamp_format
== TIMESTAMP_SECONDS
) {
446 if (tv
->tv_usec
< start_time
.tv_usec
) {
447 diff
.tv_sec
= tv
->tv_sec
- start_time
.tv_sec
- 1;
448 diff
.tv_usec
= tv
->tv_usec
+ (1000000L - start_time
.tv_usec
);
450 diff
.tv_sec
= tv
->tv_sec
- start_time
.tv_sec
;
451 diff
.tv_usec
= tv
->tv_usec
- start_time
.tv_usec
;
453 str
= mputprintf(str
, "%ld.%06ld", (long)diff
.tv_sec
, diff
.tv_usec
);
455 time_t tv_sec
= tv
->tv_sec
;
456 struct tm
*lt
= localtime(&tv_sec
);
457 if (lt
== NULL
) fatal_error("localtime() call failed.");
458 if (p_timestamp_format
== TIMESTAMP_TIME
) {
459 str
= mputprintf(str
, "%02d:%02d:%02d.%06ld",
460 lt
->tm_hour
, lt
->tm_min
, lt
->tm_sec
, tv
->tv_usec
);
462 static const char * const month_names
[] = { "Jan", "Feb", "Mar",
463 "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
464 str
= mputprintf(str
, "%4d/%s/%02d %02d:%02d:%02d.%06ld",
465 lt
->tm_year
+ 1900, month_names
[lt
->tm_mon
],
466 lt
->tm_mday
, lt
->tm_hour
, lt
->tm_min
, lt
->tm_sec
,
473 CHARSTRING
TTCN_Logger::get_timestamp_str(timestamp_format_t p_timestamp_format
)
476 if (gettimeofday(&tv
, NULL
) == -1)
477 fatal_error("gettimeofday() system call failed.");
478 char *str
= mputstr_timestamp(NULL
, p_timestamp_format
, &tv
);
479 CHARSTRING
ret_val(mstrlen(str
), str
);
484 CHARSTRING
TTCN_Logger::get_source_info_str(source_info_format_t
485 p_source_info_format
)
487 if (p_source_info_format
== SINFO_NONE
) return CHARSTRING();
488 char *source_info
= TTCN_Location::print_location(
489 p_source_info_format
== SINFO_STACK
, TRUE
, log_entity_name
);
490 if (source_info
== NULL
) return CHARSTRING('-');
491 CHARSTRING
ret_val(mstrlen(source_info
),source_info
);
496 /** @brief Logs a fatal error and terminates the application.
497 This function doesn't return: it calls \c exit(EXIT_FAILURE);
498 @param err_msg printf-style format string
500 void TTCN_Logger::fatal_error(const char *err_msg
, ...)
502 fputs("Fatal error during logging: ", stderr
);
504 va_start(p_var
, err_msg
);
505 vfprintf(stderr
, err_msg
, p_var
);
508 fputs(" Exiting.\n", stderr
);
512 void TTCN_Logger::initialize_logger()
514 console_log_mask
.component_id
.id_selector
= COMPONENT_ID_ALL
;
515 console_log_mask
.component_id
.id_compref
= ALL_COMPREF
;
516 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
517 console_log_mask
.mask
= Logging_Bits::default_console_mask
;
519 file_log_mask
.component_id
.id_selector
= COMPONENT_ID_ALL
;
520 file_log_mask
.component_id
.id_compref
= ALL_COMPREF
;
521 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
522 file_log_mask
.mask
= Logging_Bits::log_all
;
524 emergency_log_mask
.component_id
.id_selector
= COMPONENT_ID_ALL
;
525 emergency_log_mask
.component_id
.id_compref
= ALL_COMPREF
;
526 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
527 emergency_log_mask
.mask
= Logging_Bits::log_all
;
529 logmatch_buffer
= (char*)Malloc(MIN_BUFFER_SIZE
);
530 logmatch_buffer
[0] = '\0';
531 logmatch_buffer_len
= 0;
532 logmatch_buffer_size
= MIN_BUFFER_SIZE
;
535 void TTCN_Logger::terminate_logger()
537 // Get rid of plug-ins at first.
539 plugins_
->unload_plugins();
544 Free(executable_name
);
545 executable_name
= NULL
;
547 // Clean up the log masks. *_log_masks (which points to the start of
548 // actual_*_log_mask) is borrowed as the "next" pointer.
549 if (COMPONENT_ID_NAME
== console_log_mask
.component_id
.id_selector
) {
550 Free(console_log_mask
.component_id
.id_name
);
553 if (COMPONENT_ID_NAME
== file_log_mask
.component_id
.id_selector
) {
554 Free(file_log_mask
.component_id
.id_name
);
557 if (COMPONENT_ID_NAME
== emergency_log_mask
.component_id
.id_selector
) {
558 Free(emergency_log_mask
.component_id
.id_name
);
561 Free(logmatch_buffer
);
562 logmatch_buffer
= NULL
;
565 bool TTCN_Logger::is_logger_up()
567 if (logmatch_buffer
== NULL
) return FALSE
;
568 return get_logger_plugin_manager()->plugins_ready();
571 void TTCN_Logger::reset_configuration()
573 file_log_mask
.mask
= Logging_Bits::log_all
;
574 console_log_mask
.mask
= Logging_Bits::default_console_mask
;
575 emergency_log_mask
.mask
= Logging_Bits::log_all
;
577 timestamp_format
= TIMESTAMP_TIME
;
578 source_info_format
= SINFO_NONE
;
579 log_event_types
= LOGEVENTTYPES_NO
;
580 log_entity_name
= FALSE
;
582 get_logger_plugin_manager()->reset();
585 void TTCN_Logger::set_executable_name(const char *argv_0
)
587 Free(executable_name
);
588 size_t name_end
= strlen(argv_0
);
589 // Cut the '.exe' suffix from the end (if present).
590 if (name_end
>= 4 && !strncasecmp(argv_0
+ name_end
- 4, ".exe", 4))
592 size_t name_begin
= 0;
593 // Find the last '/' (if present) to cut the leading directory part.
594 for (int i
= name_end
- 1; i
>= 0; i
--) {
595 if (argv_0
[i
] == '/') {
600 int name_len
= name_end
- name_begin
;
602 executable_name
= (char*)Malloc(name_len
+ 1);
603 memcpy(executable_name
, argv_0
+ name_begin
, name_len
);
604 executable_name
[name_len
] = '\0';
605 } else executable_name
= NULL
;
608 bool TTCN_Logger::add_parameter(const logging_setting_t
& logging_param
)
610 return get_logger_plugin_manager()->add_parameter(logging_param
);
613 void TTCN_Logger::set_plugin_parameters(component component_reference
,
614 const char *component_name
)
616 get_logger_plugin_manager()->set_parameters(component_reference
,
620 void TTCN_Logger::load_plugins(component component_reference
,
621 const char *component_name
)
623 get_logger_plugin_manager()->load_plugins(component_reference
,
627 void TTCN_Logger::set_file_name(const char *new_filename_skeleton
,
630 // Pass the file's name to all plug-ins loaded. Not all of them is
631 // interested in this.
632 get_logger_plugin_manager()->
633 set_file_name(new_filename_skeleton
, from_config
);
636 bool TTCN_Logger::set_file_size(component_id_t
const& comp
, int p_size
)
638 return get_logger_plugin_manager()->set_file_size(comp
, p_size
);
641 bool TTCN_Logger::set_file_number(component_id_t
const& comp
, int p_number
)
643 return get_logger_plugin_manager()->set_file_number(comp
, p_number
);
646 bool TTCN_Logger::set_disk_full_action(component_id_t
const& comp
,
647 disk_full_action_t p_disk_full_action
)
649 return get_logger_plugin_manager()
650 ->set_disk_full_action(comp
, p_disk_full_action
);
653 void TTCN_Logger::set_start_time()
655 if (gettimeofday(&start_time
, NULL
) == -1) {
656 fatal_error("gettimeofday() system call failed.");
660 LoggerPluginManager
*TTCN_Logger::get_logger_plugin_manager()
662 if (!plugins_
) plugins_
= new LoggerPluginManager();
667 // These masks can control not only file and console! They're general purpose
668 // event filters, hence their name is not changed. Stay here.
669 void TTCN_Logger::set_file_mask(component_id_t
const& cmpt
, const Logging_Bits
& new_file_mask
)
671 // If FileMask was set with a component-specific value, do not allow
672 // overwriting with a generic value.
673 if (file_log_mask
.component_id
.id_selector
== COMPONENT_ID_COMPREF
674 && cmpt
.id_selector
== COMPONENT_ID_ALL
) return;
675 file_log_mask
.mask
= new_file_mask
;
676 if (cmpt
.id_selector
== COMPONENT_ID_NAME
) { // deep copy needed
677 if (file_log_mask
.component_id
.id_selector
== COMPONENT_ID_NAME
)
678 Free(file_log_mask
.component_id
.id_name
);
679 file_log_mask
.component_id
.id_selector
= COMPONENT_ID_NAME
;
680 file_log_mask
.component_id
.id_name
= mcopystr(cmpt
.id_name
);
681 } else file_log_mask
.component_id
= cmpt
;
684 void TTCN_Logger::set_console_mask(component_id_t
const& cmpt
, const Logging_Bits
& new_console_mask
)
686 // If ConsoleMask was set with a component-specific value, do not allow
687 // overwriting with a generic value.
688 if (console_log_mask
.component_id
.id_selector
== COMPONENT_ID_COMPREF
689 && cmpt
.id_selector
== COMPONENT_ID_ALL
) return;
690 console_log_mask
.mask
= new_console_mask
;
691 if (cmpt
.id_selector
== COMPONENT_ID_NAME
) { // deep copy needed
692 if (console_log_mask
.component_id
.id_selector
== COMPONENT_ID_NAME
)
693 Free(console_log_mask
.component_id
.id_name
);
694 console_log_mask
.component_id
.id_selector
= COMPONENT_ID_NAME
;
695 console_log_mask
.component_id
.id_name
= mcopystr(cmpt
.id_name
);
696 } else console_log_mask
.component_id
= cmpt
;
699 void TTCN_Logger::set_emergency_logging_mask(component_id_t
const& cmpt
, const Logging_Bits
& new_logging_mask
)
701 // If Emergency Logging Mask was set with a component-specific value, do not allow
702 // overwriting with a generic value.
703 if (emergency_log_mask
.component_id
.id_selector
== COMPONENT_ID_COMPREF
704 && cmpt
.id_selector
== COMPONENT_ID_ALL
) return;
705 emergency_log_mask
.mask
= new_logging_mask
;
706 if (cmpt
.id_selector
== COMPONENT_ID_NAME
) { // deep copy needed
707 if (emergency_log_mask
.component_id
.id_selector
== COMPONENT_ID_NAME
)
708 Free(emergency_log_mask
.component_id
.id_name
);
709 emergency_log_mask
.component_id
.id_selector
= COMPONENT_ID_NAME
;
710 emergency_log_mask
.component_id
.id_name
= mcopystr(cmpt
.id_name
);
711 } else emergency_log_mask
.component_id
= cmpt
;
714 void TTCN_Logger::set_emergency_logging_behaviour(emergency_logging_behaviour_t behaviour
)
716 emergency_logging_behaviour
= behaviour
;
719 TTCN_Logger::emergency_logging_behaviour_t
TTCN_Logger::get_emergency_logging_behaviour()
721 return emergency_logging_behaviour
;
724 size_t TTCN_Logger::get_emergency_logging()
726 return emergency_logging
;
729 void TTCN_Logger::set_emergency_logging(size_t size
)
731 emergency_logging
= size
;
734 boolean
TTCN_Logger::get_emergency_logging_for_fail_verdict()
736 return emergency_logging_for_fail_verdict
;
739 void TTCN_Logger::set_emergency_logging_for_fail_verdict(boolean b
)
741 emergency_logging_for_fail_verdict
= b
;
744 Logging_Bits
const& TTCN_Logger::get_file_mask()
746 return file_log_mask
.mask
;
749 Logging_Bits
const& TTCN_Logger::get_console_mask()
751 return console_log_mask
.mask
;
754 Logging_Bits
const& TTCN_Logger::get_emergency_logging_mask()
756 return emergency_log_mask
.mask
;
759 void TTCN_Logger::register_plugin(const component_id_t comp
, char *identifier
, char *filename
)
761 get_logger_plugin_manager()->register_plugin(comp
, identifier
, filename
);
764 char *TTCN_Logger::get_logger_settings_str()
766 static const char *timestamp_format_names
[] = {
767 "Time", "DateTime", "Seconds"
769 static const char *logeventtype_names
[] = {
770 "No", "Yes", "Subcategories"
772 static const char *source_info_format_names
[] = {
773 "None", "Single", "Stack"
776 expstring_t filemask_origin
=
777 component_string(file_log_mask
.component_id
);
778 expstring_t consolemask_origin
=
779 component_string(console_log_mask
.component_id
);
780 expstring_t filemask_description
= file_log_mask
.mask
.describe();
781 expstring_t consolemask_description
= console_log_mask
.mask
.describe();
783 // Global options, common stuff for all plug-ins.
784 expstring_t new_log_message
= mprintf("TTCN Logger v%d.%d options: "
785 "TimeStampFormat:=%s; LogEntityName:=%s; LogEventTypes:=%s; "
786 "SourceInfoFormat:=%s; %s.FileMask:=%s; %s.ConsoleMask:=%s;",
787 TTCN_Logger::major_version
, TTCN_Logger::minor_version
,
788 timestamp_format_names
[timestamp_format
],
789 logeventtype_names
[log_entity_name
],
790 logeventtype_names
[log_event_types
],
791 source_info_format_names
[source_info_format
], filemask_origin
,
792 filemask_description
, consolemask_origin
, consolemask_description
);
794 Free(filemask_origin
);
795 Free(consolemask_origin
);
796 Free(filemask_description
);
797 Free(consolemask_description
);
799 return new_log_message
;
802 void TTCN_Logger::write_logger_settings(bool /*opening*/)
804 expstring_t new_log_message
= get_logger_settings_str();
806 // If we get called too early (and become buffered), the logger options
807 // must be updated. By default the initial values are used.
808 get_logger_plugin_manager()->log_log_options(new_log_message
,
809 mstrlen(new_log_message
));
811 Free(new_log_message
);
814 boolean
TTCN_Logger::should_log_to_file(TTCN_Logger::Severity sev
)
816 if (sev
> 0 && sev
< TTCN_Logger::NUMBER_OF_LOGSEVERITIES
) {
817 return file_log_mask
.mask
.bits
[sev
];
822 boolean
TTCN_Logger::should_log_to_console(TTCN_Logger::Severity sev
)
824 // CR_TR00015406: Always log external scripts to the console | MCTR.
825 if (sev
== TTCN_Logger::EXECUTOR_EXTCOMMAND
) return true;
826 if (sev
> 0 && sev
< TTCN_Logger::NUMBER_OF_LOGSEVERITIES
) {
827 return console_log_mask
.mask
.bits
[sev
];
832 boolean
TTCN_Logger::should_log_to_emergency(TTCN_Logger::Severity sev
)
834 if (sev
> 0 && sev
< TTCN_Logger::NUMBER_OF_LOGSEVERITIES
) {
835 return emergency_log_mask
.mask
.bits
[sev
];
840 void TTCN_Logger::set_timestamp_format(timestamp_format_t new_timestamp_format
)
842 timestamp_format
= new_timestamp_format
;
845 void TTCN_Logger::set_source_info_format(source_info_format_t new_source_info_format
)
847 source_info_format
= new_source_info_format
;
850 void TTCN_Logger::set_log_event_types(log_event_types_t new_log_event_types
)
852 log_event_types
= new_log_event_types
;
855 void TTCN_Logger::set_append_file(boolean new_append_file
)
857 get_logger_plugin_manager()->set_append_file(new_append_file
);
860 void TTCN_Logger::set_log_entity_name(boolean new_log_entity_name
)
862 log_entity_name
= new_log_entity_name
;
865 void TTCN_Logger::open_file()
867 get_logger_plugin_manager()->open_file();
870 void TTCN_Logger::close_file()
872 get_logger_plugin_manager()->close_file();
875 void TTCN_Logger::ring_buffer_dump(bool do_close_file
)
877 get_logger_plugin_manager()->ring_buffer_dump(do_close_file
);
880 unsigned int TTCN_Logger::get_mask()
882 TTCN_warning("TTCN_Logger::get_mask() is deprecated, please use "
883 "TTCN_Logger::should_log_to_file() or "
884 "TTCN_Logger::should_log_to_console() instead.");
885 return LOG_ALL_IMPORTANT
| MATCHING_UNQUALIFIED
| DEBUG_UNQUALIFIED
;
888 TTCN_Logger::matching_verbosity_t
TTCN_Logger::get_matching_verbosity()
890 return matching_verbosity
;
893 void TTCN_Logger::set_matching_verbosity(TTCN_Logger::matching_verbosity_t v
)
895 matching_verbosity
= v
;
898 // Called from the generated code and many more places... Stay here. The
899 // existence of the file descriptors etc. is the responsibility of the
901 boolean
TTCN_Logger::log_this_event(TTCN_Logger::Severity event_severity
)
903 //ToDO: emergency logging = true
904 if (should_log_to_file(event_severity
)) return TRUE
;
905 else if (should_log_to_console(event_severity
)) return TRUE
;
906 else if (should_log_to_emergency(event_severity
) && (get_emergency_logging() > 0)) return TRUE
;
910 void TTCN_Logger::log(TTCN_Logger::Severity msg_severity
,
911 const char *fmt_str
, ...)
914 va_start(p_var
, fmt_str
);
915 log_va_list(msg_severity
, fmt_str
, p_var
);
919 void TTCN_Logger::send_event_as_error()
921 char* error_msg
= get_logger_plugin_manager()->get_current_event_str();
925 if (TTCN_Communication::is_mc_connected()) {
926 TTCN_Communication::send_error("%s", error_msg
);
928 fprintf(stderr
, "%s\n", error_msg
);
933 // Part of the external interface. Don't touch.
934 void TTCN_Logger::log_str(TTCN_Logger::Severity msg_severity
,
937 if (!log_this_event(msg_severity
)) return;
939 str_ptr
= "<NULL pointer>";
940 get_logger_plugin_manager()->log_unhandled_event(msg_severity
,
941 str_ptr
, strlen(str_ptr
));
942 logmatch_printed
= false;
945 void TTCN_Logger::log_va_list(TTCN_Logger::Severity msg_severity
,
946 const char *fmt_str
, va_list p_var
)
948 get_logger_plugin_manager()->log_va_list(msg_severity
, fmt_str
, p_var
);
949 logmatch_printed
= false;
952 void TTCN_Logger::begin_event(TTCN_Logger::Severity msg_severity
, boolean log2str
)
954 get_logger_plugin_manager()->begin_event(msg_severity
, log2str
);
957 void TTCN_Logger::end_event()
959 get_logger_plugin_manager()->end_event();
960 // TODO: Find another place for these...
961 logmatch_printed
= false;
964 CHARSTRING
TTCN_Logger::end_event_log2str()
966 CHARSTRING ret_val
= get_logger_plugin_manager()->end_event_log2str();
967 logmatch_printed
= false;
971 void TTCN_Logger::finish_event()
973 get_logger_plugin_manager()->finish_event();
976 void TTCN_Logger::log_event(const char *fmt_str
, ...)
979 va_start(p_var
, fmt_str
);
980 log_event_va_list(fmt_str
, p_var
);
984 void TTCN_Logger::log_event_str(const char *str_ptr
)
986 get_logger_plugin_manager()->log_event_str(str_ptr
);
987 logmatch_printed
= false;
990 void TTCN_Logger::log_event_va_list(const char *fmt_str
, va_list p_var
)
992 get_logger_plugin_manager()->log_event_va_list(fmt_str
, p_var
);
993 logmatch_printed
= false;
996 void TTCN_Logger::log_event_unbound()
998 switch (data_log_format
) {
1000 log_event_str("<unbound>");
1006 log_event_str("<unknown>");
1010 void TTCN_Logger::log_event_uninitialized()
1012 switch (data_log_format
) {
1014 log_event_str("<uninitialized template>");
1020 log_event_str("<unknown>");
1024 void TTCN_Logger::log_event_enum(const char* enum_name_str
, int enum_value
)
1026 switch (data_log_format
) {
1028 TTCN_Logger::log_event("%s (%d)", enum_name_str
, enum_value
);
1031 log_event_str(enum_name_str
);
1034 log_event_str("<unknown>");
1038 void TTCN_Logger::log_char(char c
)
1040 get_logger_plugin_manager()->log_char(c
);
1041 logmatch_printed
= false;
1044 boolean
TTCN_Logger::is_printable(unsigned char c
)
1046 if (!isascii(c
)) return FALSE
;
1047 else if (isprint(c
)) return TRUE
;
1064 void TTCN_Logger::log_char_escaped(unsigned char c
)
1068 log_event_str("\\n");
1071 log_event_str("\\t");
1074 log_event_str("\\v");
1077 log_event_str("\\b");
1080 log_event_str("\\r");
1083 log_event_str("\\f");
1086 log_event_str("\\a");
1089 log_event_str("\\\\");
1092 log_event_str("\\\"");
1095 if (isprint(c
)) log_char(c
);
1096 else log_event("\\%03o", c
);
1101 void TTCN_Logger::log_char_escaped(unsigned char c
, char*& p_buffer
) {
1104 p_buffer
= mputstr(p_buffer
, "\\n");
1107 p_buffer
= mputstr(p_buffer
, "\\t");
1110 p_buffer
= mputstr(p_buffer
, "\\v");
1113 p_buffer
= mputstr(p_buffer
, "\\b");
1116 p_buffer
= mputstr(p_buffer
, "\\r");
1119 p_buffer
= mputstr(p_buffer
, "\\f");
1122 p_buffer
= mputstr(p_buffer
, "\\a");
1125 p_buffer
= mputstr(p_buffer
, "\\\\");
1128 p_buffer
= mputstr(p_buffer
, "\\\"");
1131 if (isprint(c
)) p_buffer
= mputc(p_buffer
, c
);
1133 p_buffer
= mputprintf(p_buffer
, "\\%03o", c
);
1138 static const char hex_digits
[] = { '0', '1', '2', '3', '4', '5', '6', '7',
1139 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1141 void TTCN_Logger::log_hex(unsigned char nibble
)
1143 if (nibble
< 16) log_char(hex_digits
[nibble
]);
1144 else log_event_str("<unknown>");
1147 void TTCN_Logger::log_octet(unsigned char octet
)
1149 log_char(hex_digits
[octet
>> 4]);
1150 log_char(hex_digits
[octet
& 0x0F]);
1153 void TTCN_Logger::OS_error()
1156 const char *error_string
= strerror(errno
);
1157 if (error_string
!= NULL
) log_event(" (%s)", error_string
);
1158 else log_event(" (Unknown error: errno = %d)", errno
);
1163 void TTCN_Logger::log_timer_read(const char *timer_name
,
1166 get_logger_plugin_manager()->log_timer_read(timer_name
, timeout_val
);
1169 void TTCN_Logger::log_timer_start(const char *timer_name
, double start_val
)
1171 get_logger_plugin_manager()->log_timer_start(timer_name
, start_val
);
1174 void TTCN_Logger::log_timer_guard(double start_val
)
1176 get_logger_plugin_manager()->log_timer_guard(start_val
);
1179 void TTCN_Logger::log_timer_stop(const char *timer_name
, double stop_val
)
1181 get_logger_plugin_manager()->log_timer_stop(timer_name
, stop_val
);
1184 void TTCN_Logger::log_timer_timeout(const char *timer_name
,
1187 get_logger_plugin_manager()->log_timer_timeout(timer_name
, timeout_val
);
1190 void TTCN_Logger::log_timer_any_timeout()
1192 get_logger_plugin_manager()->log_timer_any_timeout();
1195 void TTCN_Logger::log_timer_unqualified(const char *message
)
1197 get_logger_plugin_manager()->log_timer_unqualified(message
);
1200 void TTCN_Logger::log_testcase_started(const qualified_name
& testcase_name
)
1202 get_logger_plugin_manager()->log_testcase_started(testcase_name
);
1205 void TTCN_Logger::log_testcase_finished(const qualified_name
& testcase_name
,
1206 verdicttype verdict
,
1209 get_logger_plugin_manager()->log_testcase_finished(testcase_name
, verdict
, reason
);
1212 void TTCN_Logger::log_setverdict(verdicttype new_verdict
, verdicttype old_verdict
,
1213 verdicttype local_verdict
, const char *old_reason
, const char *new_reason
)
1215 get_logger_plugin_manager()->log_setverdict(new_verdict
, old_verdict
,
1216 local_verdict
, old_reason
, new_reason
);
1219 void TTCN_Logger::log_getverdict(verdicttype verdict
)
1221 get_logger_plugin_manager()->log_getverdict(verdict
);
1224 void TTCN_Logger::log_final_verdict(bool is_ptc
, verdicttype ptc_verdict
,
1225 verdicttype local_verdict
, verdicttype new_verdict
,
1226 const char *verdict_reason
, int notification
, int ptc_compref
,
1227 const char *ptc_name
)
1229 get_logger_plugin_manager()->log_final_verdict(is_ptc
, ptc_verdict
,
1230 local_verdict
, new_verdict
, verdict_reason
, notification
, ptc_compref
, ptc_name
);
1233 void TTCN_Logger::log_controlpart_start_stop(const char *module_name
, int finished
)
1235 get_logger_plugin_manager()->log_controlpart_start_stop(module_name
, finished
);
1238 void TTCN_Logger::log_controlpart_errors(unsigned int error_count
)
1240 get_logger_plugin_manager()->log_controlpart_errors(error_count
);
1243 void TTCN_Logger::log_verdict_statistics(size_t none_count
, double none_percent
,
1244 size_t pass_count
, double pass_percent
,
1245 size_t inconc_count
, double inconc_percent
,
1246 size_t fail_count
, double fail_percent
,
1247 size_t error_count
, double error_percent
)
1249 get_logger_plugin_manager()->log_verdict_statistics(none_count
, none_percent
,
1250 pass_count
, pass_percent
,
1251 inconc_count
, inconc_percent
,
1252 fail_count
, fail_percent
,
1253 error_count
, error_percent
);
1256 void TTCN_Logger::log_defaultop_activate(const char *name
, int id
)
1258 get_logger_plugin_manager()->log_defaultop_activate(name
, id
);
1261 void TTCN_Logger::log_defaultop_deactivate(const char *name
, int id
)
1263 get_logger_plugin_manager()->log_defaultop_deactivate(name
, id
);
1266 void TTCN_Logger::log_defaultop_exit(const char *name
, int id
, int x
)
1268 get_logger_plugin_manager()->log_defaultop_exit(name
, id
, x
);
1271 void TTCN_Logger::log_executor_runtime(int reason
)
1273 get_logger_plugin_manager()->log_executor_runtime(reason
);
1276 void TTCN_Logger::log_HC_start(const char *host
)
1278 get_logger_plugin_manager()->log_HC_start(host
);
1281 void TTCN_Logger::log_fd_limits(int fd_limit
, long fd_set_size
)
1283 get_logger_plugin_manager()->log_fd_limits(fd_limit
, fd_set_size
);
1286 void TTCN_Logger::log_testcase_exec(const char *module
, const char *tc
)
1288 get_logger_plugin_manager()->log_testcase_exec(module
, tc
);
1291 void TTCN_Logger::log_module_init(const char *module
, bool finish
)
1293 get_logger_plugin_manager()->log_module_init(module
, finish
);
1296 void TTCN_Logger::log_mtc_created(long pid
)
1298 get_logger_plugin_manager()->log_mtc_created(pid
);
1301 void TTCN_Logger::log_configdata(int reason
, const char *str
)
1303 get_logger_plugin_manager()->log_configdata(reason
, str
);
1306 void TTCN_Logger::log_executor_component(int reason
)
1308 get_logger_plugin_manager()->log_executor_component(reason
);
1311 void TTCN_Logger::log_executor_misc(int reason
, const char *name
,
1312 const char *address
, int port
)
1314 get_logger_plugin_manager()->log_executor_misc(reason
, name
, address
, port
);
1317 void TTCN_Logger::log_extcommand(extcommand_t action
, const char *cmd
)
1319 get_logger_plugin_manager()->log_extcommand(action
, cmd
);
1322 void TTCN_Logger::log_matching_done(const char *type
, int ptc
,
1323 const char *return_type
, int reason
)
1325 get_logger_plugin_manager()->log_matching_done(reason
, type
, ptc
, return_type
);
1328 void TTCN_Logger::log_matching_problem(int reason
, int operation
, boolean check
,
1329 boolean anyport
, const char *port_name
)
1331 get_logger_plugin_manager()->log_matching_problem(reason
, operation
,
1332 check
, anyport
, port_name
);
1335 void TTCN_Logger::log_matching_success(int port_type
, const char *port_name
,
1336 int compref
, const CHARSTRING
& info
)
1338 get_logger_plugin_manager()->log_matching_success(port_type
, port_name
,
1342 void TTCN_Logger::log_matching_failure(int port_type
, const char *port_name
,
1343 int compref
, int reason
, const CHARSTRING
& info
)
1345 get_logger_plugin_manager()->log_matching_failure(port_type
, port_name
,
1346 compref
, reason
, info
);
1349 void TTCN_Logger::log_matching_timeout(const char *timer_name
)
1351 get_logger_plugin_manager()->log_matching_timeout(timer_name
);
1354 void TTCN_Logger::log_portconnmap(int operation
, int src_compref
, const char *src_port
,
1355 int dst_compref
, const char *dst_port
)
1357 get_logger_plugin_manager()->log_portconnmap(operation
, src_compref
, src_port
,
1358 dst_compref
, dst_port
);
1361 void TTCN_Logger::log_par_ptc(int reason
, const char *module
, const char *name
,
1362 int compref
, const char *compname
, const char *tc_loc
, int alive_pid
, int status
)
1364 get_logger_plugin_manager()->log_par_ptc(reason
, module
, name
, compref
,
1365 compname
, tc_loc
, alive_pid
, status
);
1368 void TTCN_Logger::log_port_queue(int operation
, const char *port_name
, int compref
,
1369 int id
, const CHARSTRING
& address
, const CHARSTRING
& param
)
1371 get_logger_plugin_manager()->log_port_queue(operation
, port_name
, compref
,
1372 id
, address
, param
);
1375 void TTCN_Logger::log_port_state(int operation
, const char *port_name
)
1377 get_logger_plugin_manager()->log_port_state(operation
, port_name
);
1380 void TTCN_Logger::log_procport_send(const char *portname
, int operation
, int compref
,
1381 const CHARSTRING
& system
, const CHARSTRING
& param
)
1383 get_logger_plugin_manager()->log_procport_send(portname
, operation
, compref
,
1387 void TTCN_Logger::log_procport_recv(const char *portname
, int operation
,
1388 int compref
, boolean check
, const CHARSTRING
& param
, int id
)
1390 get_logger_plugin_manager()->log_procport_recv(portname
, operation
, compref
,
1394 void TTCN_Logger::log_msgport_send(const char *portname
, int compref
,
1395 const CHARSTRING
& param
)
1397 get_logger_plugin_manager()->log_msgport_send(portname
, compref
, param
);
1400 void TTCN_Logger::log_msgport_recv(const char *portname
, int operation
, int compref
,
1401 const CHARSTRING
& system
, const CHARSTRING
& param
, int id
)
1403 get_logger_plugin_manager()->log_msgport_recv(portname
, operation
, compref
,
1407 void TTCN_Logger::log_dualport_map(boolean incoming
, const char *target_type
,
1408 const CHARSTRING
& value
, int id
)
1410 get_logger_plugin_manager()->log_dualport_map(incoming
, target_type
, value
, id
);
1413 void TTCN_Logger::log_dualport_discard(boolean incoming
, const char *target_type
,
1414 const char *port_name
, boolean unhandled
)
1416 get_logger_plugin_manager()->log_dualport_discard(incoming
, target_type
, port_name
,
1420 void TTCN_Logger::log_port_misc(int reason
, const char *port_name
,
1421 int remote_component
, const char *remote_port
,
1422 const char *ip_address
, int tcp_port
, int new_size
)
1424 get_logger_plugin_manager()->log_port_misc(reason
, port_name
,
1425 remote_component
, remote_port
, ip_address
, tcp_port
, new_size
);
1428 void TTCN_Logger::log_random(int action
, double v
, unsigned long u
)
1430 get_logger_plugin_manager()->log_random(action
, v
, u
);
1433 void TTCN_Logger::clear_parameters() {
1434 get_logger_plugin_manager()->clear_param_list();
1435 get_logger_plugin_manager()->clear_plugin_list();
1438 // The one instance (only for backward compatibility).
1439 TTCN_Logger TTCN_logger
;
1441 // Location related stuff.
1442 TTCN_Location
*TTCN_Location::innermost_location
= NULL
,
1443 *TTCN_Location::outermost_location
= NULL
;
1445 TTCN_Location::TTCN_Location(const char *par_file_name
,
1446 unsigned int par_line_number
, entity_type_t par_entity_type
,
1447 const char *par_entity_name
)
1448 : file_name(par_file_name
), line_number(par_line_number
),
1449 entity_type(par_entity_type
), entity_name(par_entity_name
),
1450 inner_location(NULL
), outer_location(innermost_location
)
1452 if (par_file_name
== NULL
) file_name
= "<unknown file>";
1453 if (par_entity_type
== LOCATION_UNKNOWN
) entity_name
= NULL
;
1454 else if (par_entity_name
== NULL
) entity_name
= "<unknown>";
1455 if (outer_location
!= NULL
) outer_location
->inner_location
= this;
1456 else outermost_location
= this;
1457 innermost_location
= this;
1460 void TTCN_Location::update_lineno(unsigned int new_lineno
)
1462 line_number
= new_lineno
;
1465 TTCN_Location::~TTCN_Location()
1467 if (inner_location
== NULL
) innermost_location
= outer_location
;
1468 else inner_location
->outer_location
= outer_location
;
1469 if (outer_location
== NULL
) outermost_location
= inner_location
;
1470 else outer_location
->inner_location
= inner_location
;
1473 char *TTCN_Location::print_location(boolean print_outers
,
1474 boolean print_innermost
, boolean print_entity_name
)
1476 char *ret_val
= NULL
;
1477 if (innermost_location
!= NULL
) {
1479 for (TTCN_Location
*iter
= outermost_location
;
1480 iter
!= NULL
&& iter
!= innermost_location
;
1481 iter
= iter
->inner_location
)
1482 ret_val
= iter
->append_contents(ret_val
, print_entity_name
);
1484 if (print_innermost
)
1485 ret_val
= innermost_location
->append_contents(ret_val
,
1491 void TTCN_Location::strip_entity_name(char*& par_str
)
1493 if (!par_str
) return;
1494 char *new_str
= NULL
;
1495 bool in_paren
= false;
1496 for (char *str_ptr
= par_str
; *str_ptr
!= '\0' ; str_ptr
++) {
1505 if (!in_paren
) new_str
= mputc(new_str
, *str_ptr
);
1513 unsigned int TTCN_Location::get_line_number()
1515 if (innermost_location
!= NULL
) {
1516 return innermost_location
->line_number
;
1521 char *TTCN_Location::append_contents(char *par_str
,
1522 boolean print_entity_name
) const
1524 if (par_str
!= NULL
) par_str
= mputstr(par_str
, "->");
1525 par_str
= mputprintf(par_str
, "%s:%u", file_name
, line_number
);
1526 if (print_entity_name
) {
1527 switch (entity_type
) {
1528 case LOCATION_CONTROLPART
:
1529 par_str
= mputprintf(par_str
, "(controlpart:%s)", entity_name
);
1531 case LOCATION_TESTCASE
:
1532 par_str
= mputprintf(par_str
, "(testcase:%s)", entity_name
);
1534 case LOCATION_ALTSTEP
:
1535 par_str
= mputprintf(par_str
, "(altstep:%s)", entity_name
);
1537 case LOCATION_FUNCTION
:
1538 par_str
= mputprintf(par_str
, "(function:%s)", entity_name
);
1540 case LOCATION_EXTERNALFUNCTION
:
1541 par_str
= mputprintf(par_str
, "(externalfunction:%s)", entity_name
);
1543 case LOCATION_TEMPLATE
:
1544 par_str
= mputprintf(par_str
, "(template:%s)", entity_name
);
1553 TTCN_Location_Statistics::TTCN_Location_Statistics(const char *par_file_name
,
1554 unsigned int par_line_number
, entity_type_t par_entity_type
,
1555 const char *par_entity_name
): TTCN_Location(par_file_name
, par_line_number
,
1556 par_entity_type
, par_entity_name
)
1558 TCov::hit(file_name
, line_number
, entity_name
);
1561 void TTCN_Location_Statistics::update_lineno(unsigned int new_lineno
)
1563 TTCN_Location::update_lineno(new_lineno
);
1564 TCov::hit(file_name
, line_number
);
1567 void TTCN_Location_Statistics::init_file_lines(const char *file_name
, const int line_nos
[], size_t line_nos_len
)
1569 TCov::init_file_lines(file_name
, line_nos
, line_nos_len
);
1572 void TTCN_Location_Statistics::init_file_functions(const char *file_name
, const char *function_names
[], size_t function_names_len
)
1574 TCov::init_file_functions(file_name
, function_names
, function_names_len
);
1577 TTCN_Location_Statistics::~TTCN_Location_Statistics() { }
1579 expstring_t
component_string(const component_id_t
& comp_id
)
1582 switch( comp_id
.id_selector
) {
1583 case COMPONENT_ID_NAME
:
1584 retval
= mcopystr(comp_id
.id_name
);
1586 case COMPONENT_ID_COMPREF
:
1587 retval
= mprintf("%d", comp_id
.id_compref
);
1589 case COMPONENT_ID_ALL
:
1590 retval
= mcopystr("*");
1592 case COMPONENT_ID_SYSTEM
:
1593 retval
= mcopystr("<System>");
1595 default: // Can't happen.
1596 retval
= mcopystr("Unknown component type !");