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
, // 11
108 TTCN_Logger::FUNCTION_UNQUALIFIED
, // 13
109 TTCN_Logger::PARALLEL_UNQUALIFIED
, // 17
110 TTCN_Logger::TESTCASE_UNQUALIFIED
, // 20
111 TTCN_Logger::PORTEVENT_UNQUALIFIED
, // 34
112 TTCN_Logger::STATISTICS_UNQUALIFIED
, // 36
113 TTCN_Logger::TIMEROP_UNQUALIFIED
, // 42
114 TTCN_Logger::USER_UNQUALIFIED
, // 43
115 TTCN_Logger::VERDICTOP_UNQUALIFIED
, // 47
116 TTCN_Logger::WARNING_UNQUALIFIED
, // 48
117 TTCN_Logger::MATCHING_UNQUALIFIED
, // 60
118 TTCN_Logger::DEBUG_UNQUALIFIED
, // 63
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
] = {
227 char* TTCN_Logger::logmatch_buffer
= NULL
;
228 size_t TTCN_Logger::logmatch_buffer_len
= 0;
229 size_t TTCN_Logger::logmatch_buffer_size
= 0;
230 boolean
TTCN_Logger::logmatch_printed
= false;
232 // TODO: Matching related stuff stays here for now. It just appends the
233 // string to the end of the current (active) event.
234 size_t TTCN_Logger::get_logmatch_buffer_len()
236 return logmatch_buffer_len
;
239 void TTCN_Logger::set_logmatch_buffer_len(size_t new_len
)
241 logmatch_buffer_len
= new_len
;
242 logmatch_buffer_size
= MIN_BUFFER_SIZE
;
243 while (logmatch_buffer_size
< new_len
)
244 logmatch_buffer_size
*= 2;
245 logmatch_buffer
= (char *)Realloc(logmatch_buffer
, logmatch_buffer_size
);
246 logmatch_buffer
[new_len
] = '\0';
249 void TTCN_Logger::print_logmatch_buffer()
251 if (logmatch_printed
) TTCN_Logger::log_event_str(" , ");
252 else logmatch_printed
= true;
253 if (logmatch_buffer_size
> 0)
254 TTCN_Logger::log_event_str(logmatch_buffer
);
257 void TTCN_Logger::log_logmatch_info(const char *fmt_str
, ...)
260 va_start(p_var
, fmt_str
);
262 if (fmt_str
== NULL
) fmt_str
= "<NULL format string>";
264 size_t free_space
= logmatch_buffer_size
- logmatch_buffer_len
;
265 // Make a copy of p_var to allow multiple calls of vsnprintf().
267 va_copy(p_var2
, p_var
);
268 int fragment_len
= vsnprintf(logmatch_buffer
+ logmatch_buffer_len
,
269 free_space
, fmt_str
, p_var2
);
271 if (fragment_len
< 0) set_logmatch_buffer_len(logmatch_buffer_size
* 2);
272 else if ((size_t)fragment_len
>= free_space
)
273 set_logmatch_buffer_len(logmatch_buffer_len
+ fragment_len
+ 1);
275 logmatch_buffer_len
+= fragment_len
;
282 /** The "beginning of time" for the logger (seconds and microseconds
285 struct timeval
TTCN_Logger::start_time
;
287 /** The base name of the current executable (no path, no extension) */
288 char *TTCN_Logger::executable_name
= NULL
;
290 /// True to log type (controlpart/altstep/testcase/function/...) and name
291 /// of the entity responsible for the log message, false to suppress it.
292 boolean
TTCN_Logger::log_entity_name
= FALSE
;
294 /// The default log format is the legacy (original) format.
295 TTCN_Logger::data_log_format_t
TTCN_Logger::data_log_format
= LF_LEGACY
;
299 /** @brief Equality operator for component_id_t
301 @param left component identifier
302 @param right component identifier
303 @return true if \p left and \p right refer to the same component
305 @note This functions tests the equality of the component identifiers,
306 not the components themselves. It can't detect that component named "foo" is
307 the same as component number 3.
309 @li If the selectors differ, returns \c false.
310 @li If both selectors are COMPONENT_ID_NAME, compares the names.
311 @li If both selectors are COMPONENT_ID_COMPREF, compares the comp. references.
312 @li If both selectors are COMPONENT_ID_ALL or COMPONENT_ID_SYSTEM,
316 bool operator==(const component_id_t
& left
, const component_id_t
& right
)
318 if (left
.id_selector
!= right
.id_selector
)
321 // The selectors are the same.
322 switch (left
.id_selector
) {
323 case COMPONENT_ID_NAME
:
324 return !strcmp(left
.id_name
, right
.id_name
);
325 case COMPONENT_ID_COMPREF
:
326 return left
.id_compref
== right
.id_compref
;
327 default: // Should be MTC or SYSTEM; identified by the selector.
332 char *TTCN_Logger::mputstr_severity(char *str
, const TTCN_Logger::Severity
& severity
)
335 case TTCN_Logger::ACTION_UNQUALIFIED
:
336 return mputstr(str
, "ACTION");
337 case TTCN_Logger::DEFAULTOP_ACTIVATE
:
338 case TTCN_Logger::DEFAULTOP_DEACTIVATE
:
339 case TTCN_Logger::DEFAULTOP_EXIT
:
340 case TTCN_Logger::DEFAULTOP_UNQUALIFIED
:
341 return mputstr(str
, "DEFAULTOP");
342 case TTCN_Logger::ERROR_UNQUALIFIED
:
343 return mputstr(str
, "ERROR");
344 case TTCN_Logger::EXECUTOR_RUNTIME
:
345 case TTCN_Logger::EXECUTOR_CONFIGDATA
:
346 case TTCN_Logger::EXECUTOR_EXTCOMMAND
:
347 case TTCN_Logger::EXECUTOR_COMPONENT
:
348 case TTCN_Logger::EXECUTOR_LOGOPTIONS
:
349 case TTCN_Logger::EXECUTOR_UNQUALIFIED
:
350 return mputstr(str
, "EXECUTOR");
351 case TTCN_Logger::FUNCTION_RND
:
352 case TTCN_Logger::FUNCTION_UNQUALIFIED
:
353 return mputstr(str
, "FUNCTION");
354 case TTCN_Logger::PARALLEL_PTC
:
355 case TTCN_Logger::PARALLEL_PORTCONN
:
356 case TTCN_Logger::PARALLEL_PORTMAP
:
357 case TTCN_Logger::PARALLEL_UNQUALIFIED
:
358 return mputstr(str
, "PARALLEL");
359 case TTCN_Logger::TESTCASE_START
:
360 case TTCN_Logger::TESTCASE_FINISH
:
361 case TTCN_Logger::TESTCASE_UNQUALIFIED
:
362 return mputstr(str
, "TESTCASE");
363 case TTCN_Logger::PORTEVENT_PQUEUE
:
364 case TTCN_Logger::PORTEVENT_MQUEUE
:
365 case TTCN_Logger::PORTEVENT_STATE
:
366 case TTCN_Logger::PORTEVENT_PMIN
:
367 case TTCN_Logger::PORTEVENT_PMOUT
:
368 case TTCN_Logger::PORTEVENT_PCIN
:
369 case TTCN_Logger::PORTEVENT_PCOUT
:
370 case TTCN_Logger::PORTEVENT_MMRECV
:
371 case TTCN_Logger::PORTEVENT_MMSEND
:
372 case TTCN_Logger::PORTEVENT_MCRECV
:
373 case TTCN_Logger::PORTEVENT_MCSEND
:
374 case TTCN_Logger::PORTEVENT_DUALRECV
:
375 case TTCN_Logger::PORTEVENT_DUALSEND
:
376 case TTCN_Logger::PORTEVENT_UNQUALIFIED
:
377 return mputstr(str
, "PORTEVENT");
378 case TTCN_Logger::STATISTICS_VERDICT
:
379 case TTCN_Logger::STATISTICS_UNQUALIFIED
:
380 return mputstr(str
, "STATISTICS");
381 case TTCN_Logger::TIMEROP_READ
:
382 case TTCN_Logger::TIMEROP_START
:
383 case TTCN_Logger::TIMEROP_GUARD
:
384 case TTCN_Logger::TIMEROP_STOP
:
385 case TTCN_Logger::TIMEROP_TIMEOUT
:
386 case TTCN_Logger::TIMEROP_UNQUALIFIED
:
387 return mputstr(str
, "TIMEROP");
388 case TTCN_Logger::USER_UNQUALIFIED
:
389 return mputstr(str
, "USER");
391 case TTCN_Logger::VERDICTOP_GETVERDICT
:
392 case TTCN_Logger::VERDICTOP_SETVERDICT
:
393 case TTCN_Logger::VERDICTOP_FINAL
:
394 case TTCN_Logger::VERDICTOP_UNQUALIFIED
:
395 return mputstr(str
, "VERDICTOP");
396 case TTCN_Logger::WARNING_UNQUALIFIED
:
397 return mputstr(str
, "WARNING");
398 case TTCN_Logger::MATCHING_DONE
:
399 case TTCN_Logger::MATCHING_TIMEOUT
:
400 case TTCN_Logger::MATCHING_PCSUCCESS
:
401 case TTCN_Logger::MATCHING_PCUNSUCC
:
402 case TTCN_Logger::MATCHING_PMSUCCESS
:
403 case TTCN_Logger::MATCHING_PMUNSUCC
:
404 case TTCN_Logger::MATCHING_MCSUCCESS
:
405 case TTCN_Logger::MATCHING_MCUNSUCC
:
406 case TTCN_Logger::MATCHING_MMSUCCESS
:
407 case TTCN_Logger::MATCHING_MMUNSUCC
:
408 case TTCN_Logger::MATCHING_PROBLEM
:
409 case TTCN_Logger::MATCHING_UNQUALIFIED
:
410 return mputstr(str
, "MATCHING");
411 case TTCN_Logger::DEBUG_ENCDEC
:
412 case TTCN_Logger::DEBUG_TESTPORT
:
413 case TTCN_Logger::DEBUG_UNQUALIFIED
:
414 return mputstr(str
, "DEBUG");
416 return mputstr(str
, "UNKNOWN");
420 char *TTCN_Logger::mputstr_timestamp(char *str
,
421 timestamp_format_t p_timestamp_format
,
422 const struct timeval
*tv
)
424 if (p_timestamp_format
== TIMESTAMP_SECONDS
) {
426 if (tv
->tv_usec
< start_time
.tv_usec
) {
427 diff
.tv_sec
= tv
->tv_sec
- start_time
.tv_sec
- 1;
428 diff
.tv_usec
= tv
->tv_usec
+ (1000000L - start_time
.tv_usec
);
430 diff
.tv_sec
= tv
->tv_sec
- start_time
.tv_sec
;
431 diff
.tv_usec
= tv
->tv_usec
- start_time
.tv_usec
;
433 str
= mputprintf(str
, "%ld.%06ld", (long)diff
.tv_sec
, diff
.tv_usec
);
435 time_t tv_sec
= tv
->tv_sec
;
436 struct tm
*lt
= localtime(&tv_sec
);
437 if (lt
== NULL
) fatal_error("localtime() call failed.");
438 if (p_timestamp_format
== TIMESTAMP_TIME
) {
439 str
= mputprintf(str
, "%02d:%02d:%02d.%06ld",
440 lt
->tm_hour
, lt
->tm_min
, lt
->tm_sec
, tv
->tv_usec
);
442 static const char * const month_names
[] = { "Jan", "Feb", "Mar",
443 "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
444 str
= mputprintf(str
, "%4d/%s/%02d %02d:%02d:%02d.%06ld",
445 lt
->tm_year
+ 1900, month_names
[lt
->tm_mon
],
446 lt
->tm_mday
, lt
->tm_hour
, lt
->tm_min
, lt
->tm_sec
,
453 CHARSTRING
TTCN_Logger::get_timestamp_str(timestamp_format_t p_timestamp_format
)
456 if (gettimeofday(&tv
, NULL
) == -1)
457 fatal_error("gettimeofday() system call failed.");
458 char *str
= mputstr_timestamp(NULL
, p_timestamp_format
, &tv
);
459 CHARSTRING
ret_val(mstrlen(str
), str
);
464 CHARSTRING
TTCN_Logger::get_source_info_str(source_info_format_t
465 p_source_info_format
)
467 if (p_source_info_format
== SINFO_NONE
) return CHARSTRING();
468 char *source_info
= TTCN_Location::print_location(
469 p_source_info_format
== SINFO_STACK
, TRUE
, log_entity_name
);
470 if (source_info
== NULL
) return CHARSTRING('-');
471 CHARSTRING
ret_val(mstrlen(source_info
),source_info
);
476 /** @brief Logs a fatal error and terminates the application.
477 This function doesn't return: it calls \c exit(EXIT_FAILURE);
478 @param err_msg printf-style format string
480 void TTCN_Logger::fatal_error(const char *err_msg
, ...)
482 fputs("Fatal error during logging: ", stderr
);
484 va_start(p_var
, err_msg
);
485 vfprintf(stderr
, err_msg
, p_var
);
488 fputs(" Exiting.\n", stderr
);
492 void TTCN_Logger::initialize_logger()
494 console_log_mask
.component_id
.id_selector
= COMPONENT_ID_ALL
;
495 console_log_mask
.component_id
.id_compref
= ALL_COMPREF
;
496 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
497 console_log_mask
.mask
= Logging_Bits::default_console_mask
;
499 file_log_mask
.component_id
.id_selector
= COMPONENT_ID_ALL
;
500 file_log_mask
.component_id
.id_compref
= ALL_COMPREF
;
501 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
502 file_log_mask
.mask
= Logging_Bits::log_all
;
504 emergency_log_mask
.component_id
.id_selector
= COMPONENT_ID_ALL
;
505 emergency_log_mask
.component_id
.id_compref
= ALL_COMPREF
;
506 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
507 emergency_log_mask
.mask
= Logging_Bits::log_all
;
509 logmatch_buffer
= (char*)Malloc(MIN_BUFFER_SIZE
);
510 logmatch_buffer
[0] = '\0';
511 logmatch_buffer_len
= 0;
512 logmatch_buffer_size
= MIN_BUFFER_SIZE
;
515 void TTCN_Logger::terminate_logger()
517 // Get rid of plug-ins at first.
519 plugins_
->unload_plugins();
524 Free(executable_name
);
525 executable_name
= NULL
;
527 // Clean up the log masks. *_log_masks (which points to the start of
528 // actual_*_log_mask) is borrowed as the "next" pointer.
529 if (COMPONENT_ID_NAME
== console_log_mask
.component_id
.id_selector
) {
530 Free(console_log_mask
.component_id
.id_name
);
533 if (COMPONENT_ID_NAME
== file_log_mask
.component_id
.id_selector
) {
534 Free(file_log_mask
.component_id
.id_name
);
537 if (COMPONENT_ID_NAME
== emergency_log_mask
.component_id
.id_selector
) {
538 Free(emergency_log_mask
.component_id
.id_name
);
541 Free(logmatch_buffer
);
542 logmatch_buffer
= NULL
;
545 bool TTCN_Logger::is_logger_up()
547 if (logmatch_buffer
== NULL
) return FALSE
;
548 return get_logger_plugin_manager()->plugins_ready();
551 void TTCN_Logger::reset_configuration()
553 file_log_mask
.mask
= Logging_Bits::log_all
;
554 console_log_mask
.mask
= Logging_Bits::default_console_mask
;
555 emergency_log_mask
.mask
= Logging_Bits::log_all
;
557 timestamp_format
= TIMESTAMP_TIME
;
558 source_info_format
= SINFO_NONE
;
559 log_event_types
= LOGEVENTTYPES_NO
;
560 log_entity_name
= FALSE
;
562 get_logger_plugin_manager()->reset();
565 void TTCN_Logger::set_executable_name(const char *argv_0
)
567 Free(executable_name
);
568 size_t name_end
= strlen(argv_0
);
569 // Cut the '.exe' suffix from the end (if present).
570 if (name_end
>= 4 && !strncasecmp(argv_0
+ name_end
- 4, ".exe", 4))
572 size_t name_begin
= 0;
573 // Find the last '/' (if present) to cut the leading directory part.
574 for (int i
= name_end
- 1; i
>= 0; i
--) {
575 if (argv_0
[i
] == '/') {
580 int name_len
= name_end
- name_begin
;
582 executable_name
= (char*)Malloc(name_len
+ 1);
583 memcpy(executable_name
, argv_0
+ name_begin
, name_len
);
584 executable_name
[name_len
] = '\0';
585 } else executable_name
= NULL
;
588 bool TTCN_Logger::add_parameter(const logging_setting_t
& logging_param
)
590 return get_logger_plugin_manager()->add_parameter(logging_param
);
593 void TTCN_Logger::set_plugin_parameters(component component_reference
,
594 const char *component_name
)
596 get_logger_plugin_manager()->set_parameters(component_reference
,
600 void TTCN_Logger::load_plugins(component component_reference
,
601 const char *component_name
)
603 get_logger_plugin_manager()->load_plugins(component_reference
,
607 void TTCN_Logger::set_file_name(const char *new_filename_skeleton
,
610 // Pass the file's name to all plug-ins loaded. Not all of them is
611 // interested in this.
612 get_logger_plugin_manager()->
613 set_file_name(new_filename_skeleton
, from_config
);
616 bool TTCN_Logger::set_file_size(component_id_t
const& comp
, int p_size
)
618 return get_logger_plugin_manager()->set_file_size(comp
, p_size
);
621 bool TTCN_Logger::set_file_number(component_id_t
const& comp
, int p_number
)
623 return get_logger_plugin_manager()->set_file_number(comp
, p_number
);
626 bool TTCN_Logger::set_disk_full_action(component_id_t
const& comp
,
627 disk_full_action_t p_disk_full_action
)
629 return get_logger_plugin_manager()
630 ->set_disk_full_action(comp
, p_disk_full_action
);
633 void TTCN_Logger::set_start_time()
635 if (gettimeofday(&start_time
, NULL
) == -1) {
636 fatal_error("gettimeofday() system call failed.");
640 LoggerPluginManager
*TTCN_Logger::get_logger_plugin_manager()
642 if (!plugins_
) plugins_
= new LoggerPluginManager();
647 // These masks can control not only file and console! They're general purpose
648 // event filters, hence their name is not changed. Stay here.
649 void TTCN_Logger::set_file_mask(component_id_t
const& cmpt
, const Logging_Bits
& new_file_mask
)
651 // If FileMask was set with a component-specific value, do not allow
652 // overwriting with a generic value.
653 if (file_log_mask
.component_id
.id_selector
== COMPONENT_ID_COMPREF
654 && cmpt
.id_selector
== COMPONENT_ID_ALL
) return;
655 file_log_mask
.mask
= new_file_mask
;
656 if (cmpt
.id_selector
== COMPONENT_ID_NAME
) { // deep copy needed
657 if (file_log_mask
.component_id
.id_selector
== COMPONENT_ID_NAME
)
658 Free(file_log_mask
.component_id
.id_name
);
659 file_log_mask
.component_id
.id_selector
= COMPONENT_ID_NAME
;
660 file_log_mask
.component_id
.id_name
= mcopystr(cmpt
.id_name
);
661 } else file_log_mask
.component_id
= cmpt
;
664 void TTCN_Logger::set_console_mask(component_id_t
const& cmpt
, const Logging_Bits
& new_console_mask
)
666 // If ConsoleMask was set with a component-specific value, do not allow
667 // overwriting with a generic value.
668 if (console_log_mask
.component_id
.id_selector
== COMPONENT_ID_COMPREF
669 && cmpt
.id_selector
== COMPONENT_ID_ALL
) return;
670 console_log_mask
.mask
= new_console_mask
;
671 if (cmpt
.id_selector
== COMPONENT_ID_NAME
) { // deep copy needed
672 if (console_log_mask
.component_id
.id_selector
== COMPONENT_ID_NAME
)
673 Free(console_log_mask
.component_id
.id_name
);
674 console_log_mask
.component_id
.id_selector
= COMPONENT_ID_NAME
;
675 console_log_mask
.component_id
.id_name
= mcopystr(cmpt
.id_name
);
676 } else console_log_mask
.component_id
= cmpt
;
679 void TTCN_Logger::set_emergency_logging_mask(component_id_t
const& cmpt
, const Logging_Bits
& new_logging_mask
)
681 // If Emergency Logging Mask was set with a component-specific value, do not allow
682 // overwriting with a generic value.
683 if (emergency_log_mask
.component_id
.id_selector
== COMPONENT_ID_COMPREF
684 && cmpt
.id_selector
== COMPONENT_ID_ALL
) return;
685 emergency_log_mask
.mask
= new_logging_mask
;
686 if (cmpt
.id_selector
== COMPONENT_ID_NAME
) { // deep copy needed
687 if (emergency_log_mask
.component_id
.id_selector
== COMPONENT_ID_NAME
)
688 Free(emergency_log_mask
.component_id
.id_name
);
689 emergency_log_mask
.component_id
.id_selector
= COMPONENT_ID_NAME
;
690 emergency_log_mask
.component_id
.id_name
= mcopystr(cmpt
.id_name
);
691 } else emergency_log_mask
.component_id
= cmpt
;
694 void TTCN_Logger::set_emergency_logging_behaviour(emergency_logging_behaviour_t behaviour
)
696 emergency_logging_behaviour
= behaviour
;
699 TTCN_Logger::emergency_logging_behaviour_t
TTCN_Logger::get_emergency_logging_behaviour()
701 return emergency_logging_behaviour
;
704 size_t TTCN_Logger::get_emergency_logging()
706 return emergency_logging
;
709 void TTCN_Logger::set_emergency_logging(size_t size
)
711 emergency_logging
= size
;
714 Logging_Bits
const& TTCN_Logger::get_file_mask()
716 return file_log_mask
.mask
;
719 Logging_Bits
const& TTCN_Logger::get_console_mask()
721 return console_log_mask
.mask
;
724 Logging_Bits
const& TTCN_Logger::get_emergency_logging_mask()
726 return emergency_log_mask
.mask
;
729 void TTCN_Logger::register_plugin(const component_id_t comp
, char *identifier
, char *filename
)
731 get_logger_plugin_manager()->register_plugin(comp
, identifier
, filename
);
734 char *TTCN_Logger::get_logger_settings_str()
736 static const char *timestamp_format_names
[] = {
737 "Time", "DateTime", "Seconds"
739 static const char *logeventtype_names
[] = {
740 "No", "Yes", "Subcategories"
742 static const char *source_info_format_names
[] = {
743 "None", "Single", "Stack"
746 expstring_t filemask_origin
=
747 component_string(file_log_mask
.component_id
);
748 expstring_t consolemask_origin
=
749 component_string(console_log_mask
.component_id
);
750 expstring_t filemask_description
= file_log_mask
.mask
.describe();
751 expstring_t consolemask_description
= console_log_mask
.mask
.describe();
753 // Global options, common stuff for all plug-ins.
754 expstring_t new_log_message
= mprintf("TTCN Logger v%d.%d options: "
755 "TimeStampFormat:=%s; LogEntityName:=%s; LogEventTypes:=%s; "
756 "SourceInfoFormat:=%s; %s.FileMask:=%s; %s.ConsoleMask:=%s;",
757 TTCN_Logger::major_version
, TTCN_Logger::minor_version
,
758 timestamp_format_names
[timestamp_format
],
759 logeventtype_names
[log_entity_name
],
760 logeventtype_names
[log_event_types
],
761 source_info_format_names
[source_info_format
], filemask_origin
,
762 filemask_description
, consolemask_origin
, consolemask_description
);
764 Free(filemask_origin
);
765 Free(consolemask_origin
);
766 Free(filemask_description
);
767 Free(consolemask_description
);
769 return new_log_message
;
772 void TTCN_Logger::write_logger_settings(bool /*opening*/)
774 expstring_t new_log_message
= get_logger_settings_str();
776 // If we get called too early (and become buffered), the logger options
777 // must be updated. By default the initial values are used.
778 get_logger_plugin_manager()->log_log_options(new_log_message
,
779 mstrlen(new_log_message
));
781 Free(new_log_message
);
784 boolean
TTCN_Logger::should_log_to_file(TTCN_Logger::Severity sev
)
786 if (sev
> 0 && sev
< TTCN_Logger::NUMBER_OF_LOGSEVERITIES
) {
787 return file_log_mask
.mask
.bits
[sev
];
792 boolean
TTCN_Logger::should_log_to_console(TTCN_Logger::Severity sev
)
794 // CR_TR00015406: Always log external scripts to the console | MCTR.
795 if (sev
== TTCN_Logger::EXECUTOR_EXTCOMMAND
) return true;
796 if (sev
> 0 && sev
< TTCN_Logger::NUMBER_OF_LOGSEVERITIES
) {
797 return console_log_mask
.mask
.bits
[sev
];
802 boolean
TTCN_Logger::should_log_to_emergency(TTCN_Logger::Severity sev
)
804 if (sev
> 0 && sev
< TTCN_Logger::NUMBER_OF_LOGSEVERITIES
) {
805 return emergency_log_mask
.mask
.bits
[sev
];
810 void TTCN_Logger::set_timestamp_format(timestamp_format_t new_timestamp_format
)
812 timestamp_format
= new_timestamp_format
;
815 void TTCN_Logger::set_source_info_format(source_info_format_t new_source_info_format
)
817 source_info_format
= new_source_info_format
;
820 void TTCN_Logger::set_log_event_types(log_event_types_t new_log_event_types
)
822 log_event_types
= new_log_event_types
;
825 void TTCN_Logger::set_append_file(boolean new_append_file
)
827 get_logger_plugin_manager()->set_append_file(new_append_file
);
830 void TTCN_Logger::set_log_entity_name(boolean new_log_entity_name
)
832 log_entity_name
= new_log_entity_name
;
835 void TTCN_Logger::open_file()
837 get_logger_plugin_manager()->open_file();
840 void TTCN_Logger::close_file()
842 get_logger_plugin_manager()->close_file();
845 void TTCN_Logger::ring_buffer_dump(bool do_close_file
)
847 get_logger_plugin_manager()->ring_buffer_dump(do_close_file
);
850 unsigned int TTCN_Logger::get_mask()
852 TTCN_warning("TTCN_Logger::get_mask() is deprecated, please use "
853 "TTCN_Logger::should_log_to_file() or "
854 "TTCN_Logger::should_log_to_console() instead.");
855 return LOG_ALL_IMPORTANT
| MATCHING_UNQUALIFIED
| DEBUG_UNQUALIFIED
;
858 TTCN_Logger::matching_verbosity_t
TTCN_Logger::get_matching_verbosity()
860 return matching_verbosity
;
863 void TTCN_Logger::set_matching_verbosity(TTCN_Logger::matching_verbosity_t v
)
865 matching_verbosity
= v
;
868 // Called from the generated code and many more places... Stay here. The
869 // existence of the file descriptors etc. is the responsibility of the
871 boolean
TTCN_Logger::log_this_event(TTCN_Logger::Severity event_severity
)
873 //ToDO: emergency logging = true
874 if (should_log_to_file(event_severity
)) return TRUE
;
875 else if (should_log_to_console(event_severity
)) return TRUE
;
876 else if (should_log_to_emergency(event_severity
) && (get_emergency_logging() > 0)) return TRUE
;
880 void TTCN_Logger::log(TTCN_Logger::Severity msg_severity
,
881 const char *fmt_str
, ...)
884 va_start(p_var
, fmt_str
);
885 log_va_list(msg_severity
, fmt_str
, p_var
);
889 void TTCN_Logger::send_event_as_error()
891 char* error_msg
= get_logger_plugin_manager()->get_current_event_str();
895 if (TTCN_Communication::is_mc_connected()) {
896 TTCN_Communication::send_error("%s", error_msg
);
898 fprintf(stderr
, "%s\n", error_msg
);
903 // Part of the external interface. Don't touch.
904 void TTCN_Logger::log_str(TTCN_Logger::Severity msg_severity
,
907 if (!log_this_event(msg_severity
)) return;
909 str_ptr
= "<NULL pointer>";
910 get_logger_plugin_manager()->log_unhandled_event(msg_severity
,
911 str_ptr
, strlen(str_ptr
));
912 logmatch_printed
= false;
915 void TTCN_Logger::log_va_list(TTCN_Logger::Severity msg_severity
,
916 const char *fmt_str
, va_list p_var
)
918 get_logger_plugin_manager()->log_va_list(msg_severity
, fmt_str
, p_var
);
919 logmatch_printed
= false;
922 void TTCN_Logger::begin_event(TTCN_Logger::Severity msg_severity
, boolean log2str
)
924 get_logger_plugin_manager()->begin_event(msg_severity
, log2str
);
927 void TTCN_Logger::end_event()
929 get_logger_plugin_manager()->end_event();
930 // TODO: Find another place for these...
931 logmatch_printed
= false;
934 CHARSTRING
TTCN_Logger::end_event_log2str()
936 CHARSTRING ret_val
= get_logger_plugin_manager()->end_event_log2str();
937 logmatch_printed
= false;
941 void TTCN_Logger::finish_event()
943 get_logger_plugin_manager()->finish_event();
946 void TTCN_Logger::log_event(const char *fmt_str
, ...)
949 va_start(p_var
, fmt_str
);
950 log_event_va_list(fmt_str
, p_var
);
954 void TTCN_Logger::log_event_str(const char *str_ptr
)
956 get_logger_plugin_manager()->log_event_str(str_ptr
);
957 logmatch_printed
= false;
960 void TTCN_Logger::log_event_va_list(const char *fmt_str
, va_list p_var
)
962 get_logger_plugin_manager()->log_event_va_list(fmt_str
, p_var
);
963 logmatch_printed
= false;
966 void TTCN_Logger::log_event_unbound()
968 switch (data_log_format
) {
970 log_event_str("<unbound>");
976 log_event_str("<unknown>");
980 void TTCN_Logger::log_event_uninitialized()
982 switch (data_log_format
) {
984 log_event_str("<uninitialized template>");
990 log_event_str("<unknown>");
994 void TTCN_Logger::log_event_enum(const char* enum_name_str
, int enum_value
)
996 switch (data_log_format
) {
998 TTCN_Logger::log_event("%s (%d)", enum_name_str
, enum_value
);
1001 log_event_str(enum_name_str
);
1004 log_event_str("<unknown>");
1008 void TTCN_Logger::log_char(char c
)
1010 get_logger_plugin_manager()->log_char(c
);
1011 logmatch_printed
= false;
1014 boolean
TTCN_Logger::is_printable(unsigned char c
)
1016 if (!isascii(c
)) return FALSE
;
1017 else if (isprint(c
)) return TRUE
;
1034 void TTCN_Logger::log_char_escaped(unsigned char c
)
1038 log_event_str("\\n");
1041 log_event_str("\\t");
1044 log_event_str("\\v");
1047 log_event_str("\\b");
1050 log_event_str("\\r");
1053 log_event_str("\\f");
1056 log_event_str("\\a");
1059 log_event_str("\\\\");
1062 log_event_str("\\\"");
1065 if (isprint(c
)) log_char(c
);
1066 else log_event("\\%03o", c
);
1071 void TTCN_Logger::log_char_escaped(unsigned char c
, char*& p_buffer
) {
1074 p_buffer
= mputstr(p_buffer
, "\\n");
1077 p_buffer
= mputstr(p_buffer
, "\\t");
1080 p_buffer
= mputstr(p_buffer
, "\\v");
1083 p_buffer
= mputstr(p_buffer
, "\\b");
1086 p_buffer
= mputstr(p_buffer
, "\\r");
1089 p_buffer
= mputstr(p_buffer
, "\\f");
1092 p_buffer
= mputstr(p_buffer
, "\\a");
1095 p_buffer
= mputstr(p_buffer
, "\\\\");
1098 p_buffer
= mputstr(p_buffer
, "\\\"");
1101 if (isprint(c
)) p_buffer
= mputc(p_buffer
, c
);
1103 p_buffer
= mputprintf(p_buffer
, "\\%03o", c
);
1108 static const char hex_digits
[] = { '0', '1', '2', '3', '4', '5', '6', '7',
1109 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1111 void TTCN_Logger::log_hex(unsigned char nibble
)
1113 if (nibble
< 16) log_char(hex_digits
[nibble
]);
1114 else log_event_str("<unknown>");
1117 void TTCN_Logger::log_octet(unsigned char octet
)
1119 log_char(hex_digits
[octet
>> 4]);
1120 log_char(hex_digits
[octet
& 0x0F]);
1123 void TTCN_Logger::OS_error()
1126 const char *error_string
= strerror(errno
);
1127 if (error_string
!= NULL
) log_event(" (%s)", error_string
);
1128 else log_event(" (Unknown error: errno = %d)", errno
);
1133 void TTCN_Logger::log_timer_read(const char *timer_name
,
1136 get_logger_plugin_manager()->log_timer_read(timer_name
, timeout_val
);
1139 void TTCN_Logger::log_timer_start(const char *timer_name
, double start_val
)
1141 get_logger_plugin_manager()->log_timer_start(timer_name
, start_val
);
1144 void TTCN_Logger::log_timer_guard(double start_val
)
1146 get_logger_plugin_manager()->log_timer_guard(start_val
);
1149 void TTCN_Logger::log_timer_stop(const char *timer_name
, double stop_val
)
1151 get_logger_plugin_manager()->log_timer_stop(timer_name
, stop_val
);
1154 void TTCN_Logger::log_timer_timeout(const char *timer_name
,
1157 get_logger_plugin_manager()->log_timer_timeout(timer_name
, timeout_val
);
1160 void TTCN_Logger::log_timer_any_timeout()
1162 get_logger_plugin_manager()->log_timer_any_timeout();
1165 void TTCN_Logger::log_timer_unqualified(const char *message
)
1167 get_logger_plugin_manager()->log_timer_unqualified(message
);
1170 void TTCN_Logger::log_testcase_started(const qualified_name
& testcase_name
)
1172 get_logger_plugin_manager()->log_testcase_started(testcase_name
);
1175 void TTCN_Logger::log_testcase_finished(const qualified_name
& testcase_name
,
1176 verdicttype verdict
,
1179 get_logger_plugin_manager()->log_testcase_finished(testcase_name
, verdict
, reason
);
1182 void TTCN_Logger::log_setverdict(verdicttype new_verdict
, verdicttype old_verdict
,
1183 verdicttype local_verdict
, const char *old_reason
, const char *new_reason
)
1185 get_logger_plugin_manager()->log_setverdict(new_verdict
, old_verdict
,
1186 local_verdict
, old_reason
, new_reason
);
1189 void TTCN_Logger::log_getverdict(verdicttype verdict
)
1191 get_logger_plugin_manager()->log_getverdict(verdict
);
1194 void TTCN_Logger::log_final_verdict(bool is_ptc
, verdicttype ptc_verdict
,
1195 verdicttype local_verdict
, verdicttype new_verdict
,
1196 const char *verdict_reason
, int notification
, int ptc_compref
,
1197 const char *ptc_name
)
1199 get_logger_plugin_manager()->log_final_verdict(is_ptc
, ptc_verdict
,
1200 local_verdict
, new_verdict
, verdict_reason
, notification
, ptc_compref
, ptc_name
);
1203 void TTCN_Logger::log_controlpart_start_stop(const char *module_name
, int finished
)
1205 get_logger_plugin_manager()->log_controlpart_start_stop(module_name
, finished
);
1208 void TTCN_Logger::log_controlpart_errors(unsigned int error_count
)
1210 get_logger_plugin_manager()->log_controlpart_errors(error_count
);
1213 void TTCN_Logger::log_verdict_statistics(size_t none_count
, double none_percent
,
1214 size_t pass_count
, double pass_percent
,
1215 size_t inconc_count
, double inconc_percent
,
1216 size_t fail_count
, double fail_percent
,
1217 size_t error_count
, double error_percent
)
1219 get_logger_plugin_manager()->log_verdict_statistics(none_count
, none_percent
,
1220 pass_count
, pass_percent
,
1221 inconc_count
, inconc_percent
,
1222 fail_count
, fail_percent
,
1223 error_count
, error_percent
);
1226 void TTCN_Logger::log_defaultop_activate(const char *name
, int id
)
1228 get_logger_plugin_manager()->log_defaultop_activate(name
, id
);
1231 void TTCN_Logger::log_defaultop_deactivate(const char *name
, int id
)
1233 get_logger_plugin_manager()->log_defaultop_deactivate(name
, id
);
1236 void TTCN_Logger::log_defaultop_exit(const char *name
, int id
, int x
)
1238 get_logger_plugin_manager()->log_defaultop_exit(name
, id
, x
);
1241 void TTCN_Logger::log_executor_runtime(int reason
)
1243 get_logger_plugin_manager()->log_executor_runtime(reason
);
1246 void TTCN_Logger::log_HC_start(const char *host
)
1248 get_logger_plugin_manager()->log_HC_start(host
);
1251 void TTCN_Logger::log_fd_limits(int fd_limit
, long fd_set_size
)
1253 get_logger_plugin_manager()->log_fd_limits(fd_limit
, fd_set_size
);
1256 void TTCN_Logger::log_testcase_exec(const char *module
, const char *tc
)
1258 get_logger_plugin_manager()->log_testcase_exec(module
, tc
);
1261 void TTCN_Logger::log_module_init(const char *module
, bool finish
)
1263 get_logger_plugin_manager()->log_module_init(module
, finish
);
1266 void TTCN_Logger::log_mtc_created(long pid
)
1268 get_logger_plugin_manager()->log_mtc_created(pid
);
1271 void TTCN_Logger::log_configdata(int reason
, const char *str
)
1273 get_logger_plugin_manager()->log_configdata(reason
, str
);
1276 void TTCN_Logger::log_executor_component(int reason
)
1278 get_logger_plugin_manager()->log_executor_component(reason
);
1281 void TTCN_Logger::log_executor_misc(int reason
, const char *name
,
1282 const char *address
, int port
)
1284 get_logger_plugin_manager()->log_executor_misc(reason
, name
, address
, port
);
1287 void TTCN_Logger::log_extcommand(extcommand_t action
, const char *cmd
)
1289 get_logger_plugin_manager()->log_extcommand(action
, cmd
);
1292 void TTCN_Logger::log_matching_done(const char *type
, int ptc
,
1293 const char *return_type
, int reason
)
1295 get_logger_plugin_manager()->log_matching_done(reason
, type
, ptc
, return_type
);
1298 void TTCN_Logger::log_matching_problem(int reason
, int operation
, boolean check
,
1299 boolean anyport
, const char *port_name
)
1301 get_logger_plugin_manager()->log_matching_problem(reason
, operation
,
1302 check
, anyport
, port_name
);
1305 void TTCN_Logger::log_matching_success(int port_type
, const char *port_name
,
1306 int compref
, const CHARSTRING
& info
)
1308 get_logger_plugin_manager()->log_matching_success(port_type
, port_name
,
1312 void TTCN_Logger::log_matching_failure(int port_type
, const char *port_name
,
1313 int compref
, int reason
, const CHARSTRING
& info
)
1315 get_logger_plugin_manager()->log_matching_failure(port_type
, port_name
,
1316 compref
, reason
, info
);
1319 void TTCN_Logger::log_matching_timeout(const char *timer_name
)
1321 get_logger_plugin_manager()->log_matching_timeout(timer_name
);
1324 void TTCN_Logger::log_portconnmap(int operation
, int src_compref
, const char *src_port
,
1325 int dst_compref
, const char *dst_port
)
1327 get_logger_plugin_manager()->log_portconnmap(operation
, src_compref
, src_port
,
1328 dst_compref
, dst_port
);
1331 void TTCN_Logger::log_par_ptc(int reason
, const char *module
, const char *name
,
1332 int compref
, const char *compname
, const char *tc_loc
, int alive_pid
, int status
)
1334 get_logger_plugin_manager()->log_par_ptc(reason
, module
, name
, compref
,
1335 compname
, tc_loc
, alive_pid
, status
);
1338 void TTCN_Logger::log_port_queue(int operation
, const char *port_name
, int compref
,
1339 int id
, const CHARSTRING
& address
, const CHARSTRING
& param
)
1341 get_logger_plugin_manager()->log_port_queue(operation
, port_name
, compref
,
1342 id
, address
, param
);
1345 void TTCN_Logger::log_port_state(int operation
, const char *port_name
)
1347 get_logger_plugin_manager()->log_port_state(operation
, port_name
);
1350 void TTCN_Logger::log_procport_send(const char *portname
, int operation
, int compref
,
1351 const CHARSTRING
& system
, const CHARSTRING
& param
)
1353 get_logger_plugin_manager()->log_procport_send(portname
, operation
, compref
,
1357 void TTCN_Logger::log_procport_recv(const char *portname
, int operation
,
1358 int compref
, boolean check
, const CHARSTRING
& param
, int id
)
1360 get_logger_plugin_manager()->log_procport_recv(portname
, operation
, compref
,
1364 void TTCN_Logger::log_msgport_send(const char *portname
, int compref
,
1365 const CHARSTRING
& param
)
1367 get_logger_plugin_manager()->log_msgport_send(portname
, compref
, param
);
1370 void TTCN_Logger::log_msgport_recv(const char *portname
, int operation
, int compref
,
1371 const CHARSTRING
& system
, const CHARSTRING
& param
, int id
)
1373 get_logger_plugin_manager()->log_msgport_recv(portname
, operation
, compref
,
1377 void TTCN_Logger::log_dualport_map(boolean incoming
, const char *target_type
,
1378 const CHARSTRING
& value
, int id
)
1380 get_logger_plugin_manager()->log_dualport_map(incoming
, target_type
, value
, id
);
1383 void TTCN_Logger::log_dualport_discard(boolean incoming
, const char *target_type
,
1384 const char *port_name
, boolean unhandled
)
1386 get_logger_plugin_manager()->log_dualport_discard(incoming
, target_type
, port_name
,
1390 void TTCN_Logger::log_port_misc(int reason
, const char *port_name
,
1391 int remote_component
, const char *remote_port
,
1392 const char *ip_address
, int tcp_port
, int new_size
)
1394 get_logger_plugin_manager()->log_port_misc(reason
, port_name
,
1395 remote_component
, remote_port
, ip_address
, tcp_port
, new_size
);
1398 void TTCN_Logger::log_random(int action
, double v
, unsigned long u
)
1400 get_logger_plugin_manager()->log_random(action
, v
, u
);
1403 void TTCN_Logger::clear_parameters() {
1404 get_logger_plugin_manager()->clear_param_list();
1405 get_logger_plugin_manager()->clear_plugin_list();
1408 // The one instance (only for backward compatibility).
1409 TTCN_Logger TTCN_logger
;
1411 // Location related stuff.
1412 TTCN_Location
*TTCN_Location::innermost_location
= NULL
,
1413 *TTCN_Location::outermost_location
= NULL
;
1415 TTCN_Location::TTCN_Location(const char *par_file_name
,
1416 unsigned int par_line_number
, entity_type_t par_entity_type
,
1417 const char *par_entity_name
)
1418 : file_name(par_file_name
), line_number(par_line_number
),
1419 entity_type(par_entity_type
), entity_name(par_entity_name
),
1420 inner_location(NULL
), outer_location(innermost_location
)
1422 if (par_file_name
== NULL
) file_name
= "<unknown file>";
1423 if (par_entity_type
== LOCATION_UNKNOWN
) entity_name
= NULL
;
1424 else if (par_entity_name
== NULL
) entity_name
= "<unknown>";
1425 if (outer_location
!= NULL
) outer_location
->inner_location
= this;
1426 else outermost_location
= this;
1427 innermost_location
= this;
1430 void TTCN_Location::update_lineno(unsigned int new_lineno
)
1432 line_number
= new_lineno
;
1435 TTCN_Location::~TTCN_Location()
1437 if (inner_location
== NULL
) innermost_location
= outer_location
;
1438 else inner_location
->outer_location
= outer_location
;
1439 if (outer_location
== NULL
) outermost_location
= inner_location
;
1440 else outer_location
->inner_location
= inner_location
;
1443 char *TTCN_Location::print_location(boolean print_outers
,
1444 boolean print_innermost
, boolean print_entity_name
)
1446 char *ret_val
= NULL
;
1447 if (innermost_location
!= NULL
) {
1449 for (TTCN_Location
*iter
= outermost_location
;
1450 iter
!= NULL
&& iter
!= innermost_location
;
1451 iter
= iter
->inner_location
)
1452 ret_val
= iter
->append_contents(ret_val
, print_entity_name
);
1454 if (print_innermost
)
1455 ret_val
= innermost_location
->append_contents(ret_val
,
1461 void TTCN_Location::strip_entity_name(char*& par_str
)
1463 if (!par_str
) return;
1464 char *new_str
= NULL
;
1465 bool in_paren
= false;
1466 for (char *str_ptr
= par_str
; *str_ptr
!= '\0' ; str_ptr
++) {
1475 if (!in_paren
) new_str
= mputc(new_str
, *str_ptr
);
1483 char *TTCN_Location::append_contents(char *par_str
,
1484 boolean print_entity_name
) const
1486 if (par_str
!= NULL
) par_str
= mputstr(par_str
, "->");
1487 par_str
= mputprintf(par_str
, "%s:%u", file_name
, line_number
);
1488 if (print_entity_name
) {
1489 switch (entity_type
) {
1490 case LOCATION_CONTROLPART
:
1491 par_str
= mputprintf(par_str
, "(controlpart:%s)", entity_name
);
1493 case LOCATION_TESTCASE
:
1494 par_str
= mputprintf(par_str
, "(testcase:%s)", entity_name
);
1496 case LOCATION_ALTSTEP
:
1497 par_str
= mputprintf(par_str
, "(altstep:%s)", entity_name
);
1499 case LOCATION_FUNCTION
:
1500 par_str
= mputprintf(par_str
, "(function:%s)", entity_name
);
1502 case LOCATION_EXTERNALFUNCTION
:
1503 par_str
= mputprintf(par_str
, "(externalfunction:%s)", entity_name
);
1505 case LOCATION_TEMPLATE
:
1506 par_str
= mputprintf(par_str
, "(template:%s)", entity_name
);
1515 TTCN_Location_Statistics::TTCN_Location_Statistics(const char *par_file_name
,
1516 unsigned int par_line_number
, entity_type_t par_entity_type
,
1517 const char *par_entity_name
): TTCN_Location(par_file_name
, par_line_number
,
1518 par_entity_type
, par_entity_name
)
1520 TCov::hit(file_name
, line_number
, entity_name
);
1523 void TTCN_Location_Statistics::update_lineno(unsigned int new_lineno
)
1525 TTCN_Location::update_lineno(new_lineno
);
1526 TCov::hit(file_name
, line_number
);
1529 void TTCN_Location_Statistics::init_file_lines(const char *file_name
, const int line_nos
[], size_t line_nos_len
)
1531 TCov::init_file_lines(file_name
, line_nos
, line_nos_len
);
1534 void TTCN_Location_Statistics::init_file_functions(const char *file_name
, const char *function_names
[], size_t function_names_len
)
1536 TCov::init_file_functions(file_name
, function_names
, function_names_len
);
1539 TTCN_Location_Statistics::~TTCN_Location_Statistics() { }
1541 expstring_t
component_string(const component_id_t
& comp_id
)
1544 switch( comp_id
.id_selector
) {
1545 case COMPONENT_ID_NAME
:
1546 retval
= mcopystr(comp_id
.id_name
);
1548 case COMPONENT_ID_COMPREF
:
1549 retval
= mprintf("%d", comp_id
.id_compref
);
1551 case COMPONENT_ID_ALL
:
1552 retval
= mcopystr("*");
1554 case COMPONENT_ID_SYSTEM
:
1555 retval
= mcopystr("<System>");
1557 default: // Can't happen.
1558 retval
= mcopystr("Unknown component type !");