Sync with 5.4.2
[deliverable/titan.core.git] / core / Logger.cc
CommitLineData
970ed795 1///////////////////////////////////////////////////////////////////////////////
3abe9331 2// Copyright (c) 2000-2015 Ericsson Telecom AB
970ed795
EL
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///////////////////////////////////////////////////////////////////////////////
8#include <stdio.h>
9#include <string.h>
10#include <ctype.h>
11#include <stdarg.h>
12#include <stdlib.h>
13#include <errno.h>
14#include <unistd.h>
15#include <netdb.h>
16#include <time.h>
17#include <sys/time.h>
18#include <sys/types.h>
19
20#include "../common/memory.h"
21#include "Logger.hh"
22#include "Communication.hh"
23#include "Component.hh"
24#include "LoggingBits.hh"
25#include "LoggerPluginManager.hh"
26#include "Charstring.hh"
27#include "LoggingParam.hh"
28#include "TCov.hh"
29
30/** work-around for missing va_copy() in GCC */
31#if defined(__GNUC__) && !defined(va_copy)
32# ifdef __va_copy
33# define va_copy(dest, src) __va_copy(dest, src)
34# else
35# define va_copy(dest, src) (dest) = (src)
36# endif
37#endif
38
39#define MIN_BUFFER_SIZE 1024
40
41
42/** @brief Return a string identifying the component
43
44If \p comp.id_selector is COMPONENT_ID_NAME, returns \p comp.id_name
45
46If \p comp.id_selector is COMPONENT_ID_COMPREF, returns a pointer
47to a static buffer, containing a string representation of \p comp.id_compref
48
49If \p comp.id_selector is COMPONENT_ID_ALL, returns "All".
50
51If \p comp.id_selector is COMPONENT_ID_SYSTEM, returns "System".
52
53@param comp component identifier
54@return string
55*/
56expstring_t component_string(const component_id_t& comp);
57
58
59/** @name Private data structures
60 @{
61*/
62
63/** Log mask
64
65For TTCN_Logger internal use, no user serviceable parts.
66*/
67struct TTCN_Logger::log_mask_struct
68{
69 component_id_t component_id; /**< Component */
70 Logging_Bits mask; /**< Settings for logging to console or file */
71};
72
73/** @} */
74
75class LogEventType;
76
77/* Static members */
78
79LoggerPluginManager *TTCN_Logger::plugins_ = NULL;
80
81/* No point in initializing here; will be done in initialize_logger() */
82TTCN_Logger::log_mask_struct TTCN_Logger::console_log_mask;
83TTCN_Logger::log_mask_struct TTCN_Logger::file_log_mask;
84TTCN_Logger::log_mask_struct TTCN_Logger::emergency_log_mask;
85
86TTCN_Logger::emergency_logging_behaviour_t TTCN_Logger::emergency_logging_behaviour = BUFFER_MASKED;
87size_t TTCN_Logger::emergency_logging;
88
89TTCN_Logger::matching_verbosity_t TTCN_Logger::matching_verbosity = VERBOSITY_COMPACT;
90
91/** Timestamp format in the log files. */
92TTCN_Logger::timestamp_format_t TTCN_Logger::timestamp_format = TIMESTAMP_TIME;
93
94/** LogSourceInfo/SourceInfoFormat */
95TTCN_Logger::source_info_format_t TTCN_Logger::source_info_format = SINFO_SINGLE;
96
97/** LogEventTypes */
98TTCN_Logger::log_event_types_t TTCN_Logger::log_event_types = LOGEVENTTYPES_NO;
99
100// This array should contain all the _UNQUALIFIED severities.
101const TTCN_Logger::Severity TTCN_Logger::sev_categories[] =
102{
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
3f84031e 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
970ed795
EL
119};
120
121const char* TTCN_Logger::severity_category_names[] =
122{
123 NULL,
124 "ACTION",
125 "DEFAULTOP",
126 "ERROR",
127 "EXECUTOR",
128 "FUNCTION",
129 "PARALLEL",
130 "TESTCASE",
131 "PORTEVENT",
132 "STATISTICS",
133 "TIMEROP",
134 "USER",
135 "VERDICTOP",
136 "WARNING",
137 "MATCHING",
138 "DEBUG",
139};
140
141
142/** Sub-category names for all Severity enum values,
143 * used when TTCN_Logger::log_event_types is set to log sub-categories */
144const char* TTCN_Logger::severity_subcategory_names[NUMBER_OF_LOGSEVERITIES] = {
145 "",
146 // ACTION:
147 "UNQUALIFIED",
148 // DEFAULTOP:
149 "ACTIVATE",
150 "DEACTIVATE",
151 "EXIT",
152 "UNQUALIFIED",
153 // ERROR:
154 "UNQUALIFIED",
155 // EXECUTOR:
156 "RUNTIME",
157 "CONFIGDATA",
158 "EXTCOMMAND",
159 "COMPONENT",
160 "LOGOPTIONS",
161 "UNQUALIFIED",
162 // FUNCTION:
163 "RND",
164 "UNQUALIFIED",
165 // PARALLEL:
166 "PTC",
167 "PORTCONN",
168 "PORTMAP",
169 "UNQUALIFIED",
170 // TESTCASE:
171 "START",
172 "FINISH",
173 "UNQUALIFIED",
174 // PORTEVENT:
175 "PQUEUE",
176 "MQUEUE",
177 "STATE",
178 "PMIN",
179 "PMOUT",
180 "PCIN",
181 "PCOUT",
182 "MMRECV",
183 "MMSEND",
184 "MCRECV",
185 "MCSEND",
186 "DUALRECV",
187 "DUALSEND",
188 "UNQUALIFIED",
189 // STATISTICS:
190 "VERDICT",
191 "UNQUALIFIED",
192 // TIMEROP:
193 "READ",
194 "START",
195 "GUARD",
196 "STOP",
197 "TIMEOUT",
198 "UNQUALIFIED",
199 // USER:
200 "UNQUALIFIED",
201 // VERDICTOP:
202 "GETVERDICT",
203 "SETVERDICT",
204 "FINAL",
205 "UNQUALIFIED",
206 // WARNING:
207 "UNQUALIFIED",
208 // MATCHING:
209 "DONE",
210 "TIMEOUT",
211 "PCSUCCESS",
212 "PCUNSUCC",
213 "PMSUCCESS",
214 "PMUNSUCC",
215 "MCSUCCESS",
216 "MCUNSUCC",
217 "MMSUCCESS",
218 "MMUNSUCC",
219 "PROBLEM",
220 "UNQUALIFIED",
221 // DEBUG:
222 "ENCDEC",
223 "TESTPORT",
3f84031e 224 "USER",
225 "FRAMEWORK",
970ed795
EL
226 "UNQUALIFIED"
227};
228
229char* TTCN_Logger::logmatch_buffer = NULL;
230size_t TTCN_Logger::logmatch_buffer_len = 0;
231size_t TTCN_Logger::logmatch_buffer_size = 0;
232boolean TTCN_Logger::logmatch_printed = false;
233
234// TODO: Matching related stuff stays here for now. It just appends the
235// string to the end of the current (active) event.
236size_t TTCN_Logger::get_logmatch_buffer_len()
237{
238 return logmatch_buffer_len;
239}
240
241void TTCN_Logger::set_logmatch_buffer_len(size_t new_len)
242{
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';
249}
250
251void TTCN_Logger::print_logmatch_buffer()
252{
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);
257}
258
259void TTCN_Logger::log_logmatch_info(const char *fmt_str, ...)
260{
261 va_list p_var;
262 va_start(p_var, fmt_str);
263
264 if (fmt_str == NULL) fmt_str = "<NULL format string>";
265 for ( ; ; ) {
266 size_t free_space = logmatch_buffer_size - logmatch_buffer_len;
267 // Make a copy of p_var to allow multiple calls of vsnprintf().
268 va_list p_var2;
269 va_copy(p_var2, p_var);
270 int fragment_len = vsnprintf(logmatch_buffer + logmatch_buffer_len,
271 free_space, fmt_str, p_var2);
272 va_end(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);
276 else {
277 logmatch_buffer_len += fragment_len;
278 break;
279 }
280 }
281 va_end(p_var);
282}
283
284/** The "beginning of time" for the logger (seconds and microseconds
285 * since the Epoch)
286 */
287struct timeval TTCN_Logger::start_time;
288
289/** The base name of the current executable (no path, no extension) */
290char *TTCN_Logger::executable_name = NULL;
291
292/// True to log type (controlpart/altstep/testcase/function/...) and name
293/// of the entity responsible for the log message, false to suppress it.
294boolean TTCN_Logger::log_entity_name = FALSE;
295
296/// The default log format is the legacy (original) format.
297TTCN_Logger::data_log_format_t TTCN_Logger::data_log_format = LF_LEGACY;
298
299#include <assert.h>
300
301/** @brief Equality operator for component_id_t
302
303@param left component identifier
304@param right component identifier
305@return true if \p left and \p right refer to the same component
306
307@note This functions tests the equality of the component identifiers,
308not the components themselves. It can't detect that component named "foo" is
309the same as component number 3.
310
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,
315returns \c true.
316
317*/
318bool operator==(const component_id_t& left, const component_id_t& right)
319{
320 if (left.id_selector != right.id_selector)
321 return false;
322
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.
330 return true;
331 }
332}
333
334char *TTCN_Logger::mputstr_severity(char *str, const TTCN_Logger::Severity& severity)
335{
336 switch (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");
392 break;
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:
3f84031e 415 case TTCN_Logger::DEBUG_USER:
416 case TTCN_Logger::DEBUG_FRAMEWORK:
970ed795
EL
417 case TTCN_Logger::DEBUG_UNQUALIFIED:
418 return mputstr(str, "DEBUG");
419 default:
420 return mputstr(str, "UNKNOWN");
421 }
422}
423
424char *TTCN_Logger::mputstr_timestamp(char *str,
425 timestamp_format_t p_timestamp_format,
426 const struct timeval *tv)
427{
428 if (p_timestamp_format == TIMESTAMP_SECONDS) {
429 struct timeval diff;
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);
433 } else {
434 diff.tv_sec = tv->tv_sec - start_time.tv_sec;
435 diff.tv_usec = tv->tv_usec - start_time.tv_usec;
436 }
437 str = mputprintf(str, "%ld.%06ld", (long)diff.tv_sec, diff.tv_usec);
438 } else {
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);
445 } else {
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,
451 tv->tv_usec);
452 }
453 }
454 return str;
455}
456
457CHARSTRING TTCN_Logger::get_timestamp_str(timestamp_format_t p_timestamp_format)
458{
459 struct timeval tv;
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);
464 Free(str);
465 return ret_val;
466}
467
468CHARSTRING TTCN_Logger::get_source_info_str(source_info_format_t
469 p_source_info_format)
470{
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);
476 Free(source_info);
477 return ret_val;
478}
479
480/** @brief Logs a fatal error and terminates the application.
481This function doesn't return: it calls \c exit(EXIT_FAILURE);
482@param err_msg printf-style format string
483*/
484void TTCN_Logger::fatal_error(const char *err_msg, ...)
485{
486 fputs("Fatal error during logging: ", stderr);
487 va_list p_var;
488 va_start(p_var, err_msg);
489 vfprintf(stderr, err_msg, p_var);
490 va_end(p_var);
491 OS_error();
492 fputs(" Exiting.\n", stderr);
493 exit(EXIT_FAILURE);
494}
495
496void TTCN_Logger::initialize_logger()
497{
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;
502
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;
507
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;
512
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;
517}
518
519void TTCN_Logger::terminate_logger()
520{
521 // Get rid of plug-ins at first.
522 if (plugins_) {
523 plugins_->unload_plugins();
524 delete plugins_;
525 plugins_ = NULL;
526 }
527
528 Free(executable_name);
529 executable_name = NULL;
530
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);
535 }
536
537 if (COMPONENT_ID_NAME == file_log_mask.component_id.id_selector) {
538 Free(file_log_mask.component_id.id_name);
539 }
540
541 if (COMPONENT_ID_NAME == emergency_log_mask.component_id.id_selector) {
542 Free(emergency_log_mask.component_id.id_name);
543 }
544
545 Free(logmatch_buffer);
546 logmatch_buffer = NULL;
547}
548
549bool TTCN_Logger::is_logger_up()
550{
551 if (logmatch_buffer == NULL) return FALSE;
552 return get_logger_plugin_manager()->plugins_ready();
553}
554
555void TTCN_Logger::reset_configuration()
556{
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;
560
561 timestamp_format = TIMESTAMP_TIME;
562 source_info_format = SINFO_NONE;
563 log_event_types = LOGEVENTTYPES_NO;
564 log_entity_name = FALSE;
565
566 get_logger_plugin_manager()->reset();
567}
568
569void TTCN_Logger::set_executable_name(const char *argv_0)
570{
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))
575 name_end -= 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] == '/') {
580 name_begin = i + 1;
581 break;
582 }
583 }
584 int name_len = name_end - name_begin;
585 if (name_len > 0) {
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;
590}
591
592bool TTCN_Logger::add_parameter(const logging_setting_t& logging_param)
593{
594 return get_logger_plugin_manager()->add_parameter(logging_param);
595}
596
597void TTCN_Logger::set_plugin_parameters(component component_reference,
598 const char *component_name)
599{
600 get_logger_plugin_manager()->set_parameters(component_reference,
601 component_name);
602}
603
604void TTCN_Logger::load_plugins(component component_reference,
605 const char *component_name)
606{
607 get_logger_plugin_manager()->load_plugins(component_reference,
608 component_name);
609}
610
611void TTCN_Logger::set_file_name(const char *new_filename_skeleton,
612 boolean from_config)
613{
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);
618}
619
620bool TTCN_Logger::set_file_size(component_id_t const& comp, int p_size)
621{
622 return get_logger_plugin_manager()->set_file_size(comp, p_size);
623}
624
625bool TTCN_Logger::set_file_number(component_id_t const& comp, int p_number)
626{
627 return get_logger_plugin_manager()->set_file_number(comp, p_number);
628}
629
630bool TTCN_Logger::set_disk_full_action(component_id_t const& comp,
631 disk_full_action_t p_disk_full_action)
632{
633 return get_logger_plugin_manager()
634 ->set_disk_full_action(comp, p_disk_full_action);
635}
636
637void TTCN_Logger::set_start_time()
638{
639 if (gettimeofday(&start_time, NULL) == -1) {
640 fatal_error("gettimeofday() system call failed.");
641 }
642}
643
644LoggerPluginManager *TTCN_Logger::get_logger_plugin_manager()
645{
646 if (!plugins_) plugins_ = new LoggerPluginManager();
647 return plugins_;
648}
649
650
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.
653void TTCN_Logger::set_file_mask(component_id_t const& cmpt, const Logging_Bits& new_file_mask)
654{
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;
666}
667
668void TTCN_Logger::set_console_mask(component_id_t const& cmpt, const Logging_Bits& new_console_mask)
669{
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;
681}
682
683void TTCN_Logger::set_emergency_logging_mask(component_id_t const& cmpt, const Logging_Bits& new_logging_mask)
684{
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;
696}
697
698void TTCN_Logger::set_emergency_logging_behaviour(emergency_logging_behaviour_t behaviour)
699{
700 emergency_logging_behaviour= behaviour;
701}
702
703TTCN_Logger::emergency_logging_behaviour_t TTCN_Logger::get_emergency_logging_behaviour()
704{
705 return emergency_logging_behaviour;
706}
707
708size_t TTCN_Logger::get_emergency_logging()
709{
710 return emergency_logging;
711}
712
713void TTCN_Logger::set_emergency_logging(size_t size)
714{
715 emergency_logging = size;
716}
717
718Logging_Bits const& TTCN_Logger::get_file_mask()
719{
720 return file_log_mask.mask;
721}
722
723Logging_Bits const& TTCN_Logger::get_console_mask()
724{
725 return console_log_mask.mask;
726}
727
728Logging_Bits const& TTCN_Logger::get_emergency_logging_mask()
729{
730 return emergency_log_mask.mask;
731}
732
733void TTCN_Logger::register_plugin(const component_id_t comp, char *identifier, char *filename)
734{
735 get_logger_plugin_manager()->register_plugin(comp, identifier, filename);
736}
737
738char *TTCN_Logger::get_logger_settings_str()
739{
740 static const char *timestamp_format_names[] = {
741 "Time", "DateTime", "Seconds"
742 };
743 static const char *logeventtype_names[] = {
744 "No", "Yes", "Subcategories"
745 };
746 static const char *source_info_format_names[] = {
747 "None", "Single", "Stack"
748 };
749
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();
756
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);
767
768 Free(filemask_origin);
769 Free(consolemask_origin);
770 Free(filemask_description);
771 Free(consolemask_description);
772
773 return new_log_message;
774}
775
776void TTCN_Logger::write_logger_settings(bool /*opening*/)
777{
778 expstring_t new_log_message = get_logger_settings_str();
779
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));
784
785 Free(new_log_message);
786}
787
788boolean TTCN_Logger::should_log_to_file(TTCN_Logger::Severity sev)
789{
790 if (sev > 0 && sev < TTCN_Logger::NUMBER_OF_LOGSEVERITIES) {
791 return file_log_mask.mask.bits[sev];
792 }
793 return false;
794}
795
796boolean TTCN_Logger::should_log_to_console(TTCN_Logger::Severity sev)
797{
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];
802 }
803 return false;
804}
805
806boolean TTCN_Logger::should_log_to_emergency(TTCN_Logger::Severity sev)
807{
808 if (sev > 0 && sev < TTCN_Logger::NUMBER_OF_LOGSEVERITIES) {
809 return emergency_log_mask.mask.bits[sev];
810 }
811 return false;
812}
813
814void TTCN_Logger::set_timestamp_format(timestamp_format_t new_timestamp_format)
815{
816 timestamp_format = new_timestamp_format;
817}
818
819void TTCN_Logger::set_source_info_format(source_info_format_t new_source_info_format)
820{
821 source_info_format = new_source_info_format;
822}
823
824void TTCN_Logger::set_log_event_types(log_event_types_t new_log_event_types)
825{
826 log_event_types = new_log_event_types;
827}
828
829void TTCN_Logger::set_append_file(boolean new_append_file)
830{
831 get_logger_plugin_manager()->set_append_file(new_append_file);
832}
833
834void TTCN_Logger::set_log_entity_name(boolean new_log_entity_name)
835{
836 log_entity_name = new_log_entity_name;
837}
838
839void TTCN_Logger::open_file()
840{
841 get_logger_plugin_manager()->open_file();
842}
843
844void TTCN_Logger::close_file()
845{
846 get_logger_plugin_manager()->close_file();
847}
848
849void TTCN_Logger::ring_buffer_dump(bool do_close_file)
850{
851 get_logger_plugin_manager()->ring_buffer_dump(do_close_file);
852}
853
854unsigned int TTCN_Logger::get_mask()
855{
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;
860}
861
862TTCN_Logger::matching_verbosity_t TTCN_Logger::get_matching_verbosity()
863{
864 return matching_verbosity;
865}
866
867void TTCN_Logger::set_matching_verbosity(TTCN_Logger::matching_verbosity_t v)
868{
869 matching_verbosity = v;
870}
871
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
874// plug-ins.
875boolean TTCN_Logger::log_this_event(TTCN_Logger::Severity event_severity)
876{
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;
881 else return FALSE;
882}
883
884void TTCN_Logger::log(TTCN_Logger::Severity msg_severity,
885 const char *fmt_str, ...)
886{
887 va_list p_var;
888 va_start(p_var, fmt_str);
889 log_va_list(msg_severity, fmt_str, p_var);
890 va_end(p_var);
891}
892
893void TTCN_Logger::send_event_as_error()
894{
895 char* error_msg = get_logger_plugin_manager()->get_current_event_str();
896 if (!error_msg)
897 return;
898
899 if (TTCN_Communication::is_mc_connected()) {
900 TTCN_Communication::send_error("%s", error_msg);
901 } else {
902 fprintf(stderr, "%s\n", error_msg);
903 }
904 Free(error_msg);
905}
906
907// Part of the external interface. Don't touch.
908void TTCN_Logger::log_str(TTCN_Logger::Severity msg_severity,
909 const char *str_ptr)
910{
911 if (!log_this_event(msg_severity)) return;
912 if (str_ptr == NULL)
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;
917}
918
919void TTCN_Logger::log_va_list(TTCN_Logger::Severity msg_severity,
920 const char *fmt_str, va_list p_var)
921{
922 get_logger_plugin_manager()->log_va_list(msg_severity, fmt_str, p_var);
923 logmatch_printed = false;
924}
925
926void TTCN_Logger::begin_event(TTCN_Logger::Severity msg_severity, boolean log2str)
927{
928 get_logger_plugin_manager()->begin_event(msg_severity, log2str);
929}
930
931void TTCN_Logger::end_event()
932{
933 get_logger_plugin_manager()->end_event();
934 // TODO: Find another place for these...
935 logmatch_printed = false;
936}
937
938CHARSTRING TTCN_Logger::end_event_log2str()
939{
940 CHARSTRING ret_val = get_logger_plugin_manager()->end_event_log2str();
941 logmatch_printed = false;
942 return ret_val;
943}
944
945void TTCN_Logger::finish_event()
946{
947 get_logger_plugin_manager()->finish_event();
948}
949
950void TTCN_Logger::log_event(const char *fmt_str, ...)
951{
952 va_list p_var;
953 va_start(p_var, fmt_str);
954 log_event_va_list(fmt_str, p_var);
955 va_end(p_var);
956}
957
958void TTCN_Logger::log_event_str(const char *str_ptr)
959{
960 get_logger_plugin_manager()->log_event_str(str_ptr);
961 logmatch_printed = false;
962}
963
964void TTCN_Logger::log_event_va_list(const char *fmt_str, va_list p_var)
965{
966 get_logger_plugin_manager()->log_event_va_list(fmt_str, p_var);
967 logmatch_printed = false;
968}
969
970void TTCN_Logger::log_event_unbound()
971{
972 switch (data_log_format) {
973 case LF_LEGACY:
974 log_event_str("<unbound>");
975 break;
976 case LF_TTCN:
977 log_char('-');
978 break;
979 default:
980 log_event_str("<unknown>");
981 }
982}
983
984void TTCN_Logger::log_event_uninitialized()
985{
986 switch (data_log_format) {
987 case LF_LEGACY:
988 log_event_str("<uninitialized template>");
989 break;
990 case LF_TTCN:
991 log_char('-');
992 break;
993 default:
994 log_event_str("<unknown>");
995 }
996}
997
998void TTCN_Logger::log_event_enum(const char* enum_name_str, int enum_value)
999{
1000 switch (data_log_format) {
1001 case LF_LEGACY:
1002 TTCN_Logger::log_event("%s (%d)", enum_name_str, enum_value);
1003 break;
1004 case LF_TTCN:
1005 log_event_str(enum_name_str);
1006 break;
1007 default:
1008 log_event_str("<unknown>");
1009 }
1010}
1011
1012void TTCN_Logger::log_char(char c)
1013{
1014 get_logger_plugin_manager()->log_char(c);
1015 logmatch_printed = false;
1016}
1017
1018boolean TTCN_Logger::is_printable(unsigned char c)
1019{
1020 if (!isascii(c)) return FALSE;
1021 else if (isprint(c)) return TRUE;
1022 else {
1023 switch (c) {
1024 case '\a':
1025 case '\b':
1026 case '\t':
1027 case '\n':
1028 case '\v':
1029 case '\f':
1030 case '\r':
1031 return TRUE;
1032 default:
1033 return FALSE;
1034 }
1035 }
1036}
1037
1038void TTCN_Logger::log_char_escaped(unsigned char c)
1039{
1040 switch (c) {
1041 case '\n':
1042 log_event_str("\\n");
1043 break;
1044 case '\t':
1045 log_event_str("\\t");
1046 break;
1047 case '\v':
1048 log_event_str("\\v");
1049 break;
1050 case '\b':
1051 log_event_str("\\b");
1052 break;
1053 case '\r':
1054 log_event_str("\\r");
1055 break;
1056 case '\f':
1057 log_event_str("\\f");
1058 break;
1059 case '\a':
1060 log_event_str("\\a");
1061 break;
1062 case '\\':
1063 log_event_str("\\\\");
1064 break;
1065 case '"':
1066 log_event_str("\\\"");
1067 break;
1068 default:
1069 if (isprint(c)) log_char(c);
1070 else log_event("\\%03o", c);
1071 break;
1072 }
1073}
1074
1075void TTCN_Logger::log_char_escaped(unsigned char c, char*& p_buffer) {
1076 switch (c) {
1077 case '\n':
1078 p_buffer = mputstr(p_buffer, "\\n");
1079 break;
1080 case '\t':
1081 p_buffer = mputstr(p_buffer, "\\t");
1082 break;
1083 case '\v':
1084 p_buffer = mputstr(p_buffer, "\\v");
1085 break;
1086 case '\b':
1087 p_buffer = mputstr(p_buffer, "\\b");
1088 break;
1089 case '\r':
1090 p_buffer = mputstr(p_buffer, "\\r");
1091 break;
1092 case '\f':
1093 p_buffer = mputstr(p_buffer, "\\f");
1094 break;
1095 case '\a':
1096 p_buffer = mputstr(p_buffer, "\\a");
1097 break;
1098 case '\\':
1099 p_buffer = mputstr(p_buffer, "\\\\");
1100 break;
1101 case '"':
1102 p_buffer = mputstr(p_buffer, "\\\"");
1103 break;
1104 default:
1105 if (isprint(c)) p_buffer = mputc(p_buffer, c);
1106 else
1107 p_buffer = mputprintf(p_buffer, "\\%03o", c);
1108 break;
1109 }
1110}
1111
1112static const char hex_digits[] = { '0', '1', '2', '3', '4', '5', '6', '7',
1113 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1114
1115void TTCN_Logger::log_hex(unsigned char nibble)
1116{
1117 if (nibble < 16) log_char(hex_digits[nibble]);
1118 else log_event_str("<unknown>");
1119}
1120
1121void TTCN_Logger::log_octet(unsigned char octet)
1122{
1123 log_char(hex_digits[octet >> 4]);
1124 log_char(hex_digits[octet & 0x0F]);
1125}
1126
1127void TTCN_Logger::OS_error()
1128{
1129 if (errno != 0) {
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);
1133 errno = 0;
1134 }
1135}
1136
1137void TTCN_Logger::log_timer_read(const char *timer_name,
1138 double timeout_val)
1139{
1140 get_logger_plugin_manager()->log_timer_read(timer_name, timeout_val);
1141}
1142
1143void TTCN_Logger::log_timer_start(const char *timer_name, double start_val)
1144{
1145 get_logger_plugin_manager()->log_timer_start(timer_name, start_val);
1146}
1147
1148void TTCN_Logger::log_timer_guard(double start_val)
1149{
1150 get_logger_plugin_manager()->log_timer_guard(start_val);
1151}
1152
1153void TTCN_Logger::log_timer_stop(const char *timer_name, double stop_val)
1154{
1155 get_logger_plugin_manager()->log_timer_stop(timer_name, stop_val);
1156}
1157
1158void TTCN_Logger::log_timer_timeout(const char *timer_name,
1159 double timeout_val)
1160{
1161 get_logger_plugin_manager()->log_timer_timeout(timer_name, timeout_val);
1162}
1163
1164void TTCN_Logger::log_timer_any_timeout()
1165{
1166 get_logger_plugin_manager()->log_timer_any_timeout();
1167}
1168
1169void TTCN_Logger::log_timer_unqualified(const char *message)
1170{
1171 get_logger_plugin_manager()->log_timer_unqualified(message);
1172}
1173
1174void TTCN_Logger::log_testcase_started(const qualified_name& testcase_name)
1175{
1176 get_logger_plugin_manager()->log_testcase_started(testcase_name);
1177}
1178
1179void TTCN_Logger::log_testcase_finished(const qualified_name& testcase_name,
1180 verdicttype verdict,
1181 const char *reason)
1182{
1183 get_logger_plugin_manager()->log_testcase_finished(testcase_name, verdict, reason);
1184}
1185
1186void TTCN_Logger::log_setverdict(verdicttype new_verdict, verdicttype old_verdict,
1187 verdicttype local_verdict, const char *old_reason, const char *new_reason)
1188{
1189 get_logger_plugin_manager()->log_setverdict(new_verdict, old_verdict,
1190 local_verdict, old_reason, new_reason);
1191}
1192
1193void TTCN_Logger::log_getverdict(verdicttype verdict)
1194{
1195 get_logger_plugin_manager()->log_getverdict(verdict);
1196}
1197
1198void 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)
1202{
1203 get_logger_plugin_manager()->log_final_verdict(is_ptc, ptc_verdict,
1204 local_verdict, new_verdict, verdict_reason, notification, ptc_compref, ptc_name);
1205}
1206
1207void TTCN_Logger::log_controlpart_start_stop(const char *module_name, int finished)
1208{
1209 get_logger_plugin_manager()->log_controlpart_start_stop(module_name, finished);
1210}
1211
1212void TTCN_Logger::log_controlpart_errors(unsigned int error_count)
1213{
1214 get_logger_plugin_manager()->log_controlpart_errors(error_count);
1215}
1216
1217void 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)
1222{
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);
1228}
1229
1230void TTCN_Logger::log_defaultop_activate(const char *name, int id)
1231{
1232 get_logger_plugin_manager()->log_defaultop_activate(name, id);
1233}
1234
1235void TTCN_Logger::log_defaultop_deactivate(const char *name, int id)
1236{
1237 get_logger_plugin_manager()->log_defaultop_deactivate(name, id);
1238}
1239
1240void TTCN_Logger::log_defaultop_exit(const char *name, int id, int x)
1241{
1242 get_logger_plugin_manager()->log_defaultop_exit(name, id, x);
1243}
1244
1245void TTCN_Logger::log_executor_runtime(int reason)
1246{
1247 get_logger_plugin_manager()->log_executor_runtime(reason);
1248}
1249
1250void TTCN_Logger::log_HC_start(const char *host)
1251{
1252 get_logger_plugin_manager()->log_HC_start(host);
1253}
1254
1255void TTCN_Logger::log_fd_limits(int fd_limit, long fd_set_size)
1256{
1257 get_logger_plugin_manager()->log_fd_limits(fd_limit, fd_set_size);
1258}
1259
1260void TTCN_Logger::log_testcase_exec(const char *module, const char *tc)
1261{
1262 get_logger_plugin_manager()->log_testcase_exec(module, tc);
1263}
1264
1265void TTCN_Logger::log_module_init(const char *module, bool finish)
1266{
1267 get_logger_plugin_manager()->log_module_init(module, finish);
1268}
1269
1270void TTCN_Logger::log_mtc_created(long pid)
1271{
1272 get_logger_plugin_manager()->log_mtc_created(pid);
1273}
1274
1275void TTCN_Logger::log_configdata(int reason, const char *str)
1276{
1277 get_logger_plugin_manager()->log_configdata(reason, str);
1278}
1279
1280void TTCN_Logger::log_executor_component(int reason)
1281{
1282 get_logger_plugin_manager()->log_executor_component(reason);
1283}
1284
1285void TTCN_Logger::log_executor_misc(int reason, const char *name,
1286 const char *address, int port)
1287{
1288 get_logger_plugin_manager()->log_executor_misc(reason, name, address, port);
1289}
1290
1291void TTCN_Logger::log_extcommand(extcommand_t action, const char *cmd)
1292{
1293 get_logger_plugin_manager()->log_extcommand(action, cmd);
1294}
1295
1296void TTCN_Logger::log_matching_done(const char *type, int ptc,
1297 const char *return_type, int reason)
1298{
1299 get_logger_plugin_manager()->log_matching_done(reason, type, ptc, return_type);
1300}
1301
1302void TTCN_Logger::log_matching_problem(int reason, int operation, boolean check,
1303 boolean anyport, const char *port_name)
1304{
1305 get_logger_plugin_manager()->log_matching_problem(reason, operation,
1306 check, anyport, port_name);
1307}
1308
1309void TTCN_Logger::log_matching_success(int port_type, const char *port_name,
1310 int compref, const CHARSTRING& info)
1311{
1312 get_logger_plugin_manager()->log_matching_success(port_type, port_name,
1313 compref, info);
1314}
1315
1316void TTCN_Logger::log_matching_failure(int port_type, const char *port_name,
1317 int compref, int reason, const CHARSTRING& info)
1318{
1319 get_logger_plugin_manager()->log_matching_failure(port_type, port_name,
1320 compref, reason, info);
1321}
1322
1323void TTCN_Logger::log_matching_timeout(const char *timer_name)
1324{
1325 get_logger_plugin_manager()->log_matching_timeout(timer_name);
1326}
1327
1328void TTCN_Logger::log_portconnmap(int operation, int src_compref, const char *src_port,
1329 int dst_compref, const char *dst_port)
1330{
1331 get_logger_plugin_manager()->log_portconnmap(operation, src_compref, src_port,
1332 dst_compref, dst_port);
1333}
1334
1335void 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)
1337{
1338 get_logger_plugin_manager()->log_par_ptc(reason, module, name, compref,
1339 compname, tc_loc, alive_pid, status);
1340}
1341
1342void TTCN_Logger::log_port_queue(int operation, const char *port_name, int compref,
1343 int id, const CHARSTRING& address, const CHARSTRING& param)
1344{
1345 get_logger_plugin_manager()->log_port_queue(operation, port_name, compref,
1346 id, address, param);
1347}
1348
1349void TTCN_Logger::log_port_state(int operation, const char *port_name)
1350{
1351 get_logger_plugin_manager()->log_port_state(operation, port_name);
1352}
1353
1354void TTCN_Logger::log_procport_send(const char *portname, int operation, int compref,
1355 const CHARSTRING& system, const CHARSTRING& param)
1356{
1357 get_logger_plugin_manager()->log_procport_send(portname, operation, compref,
1358 system, param);
1359}
1360
1361void TTCN_Logger::log_procport_recv(const char *portname, int operation,
1362 int compref, boolean check, const CHARSTRING& param, int id)
1363{
1364 get_logger_plugin_manager()->log_procport_recv(portname, operation, compref,
1365 check, param, id);
1366}
1367
1368void TTCN_Logger::log_msgport_send(const char *portname, int compref,
1369 const CHARSTRING& param)
1370{
1371 get_logger_plugin_manager()->log_msgport_send(portname, compref, param);
1372}
1373
1374void TTCN_Logger::log_msgport_recv(const char *portname, int operation, int compref,
1375 const CHARSTRING& system, const CHARSTRING& param, int id)
1376{
1377 get_logger_plugin_manager()->log_msgport_recv(portname, operation, compref,
1378 system, param, id);
1379}
1380
1381void TTCN_Logger::log_dualport_map(boolean incoming, const char *target_type,
1382 const CHARSTRING& value, int id)
1383{
1384 get_logger_plugin_manager()->log_dualport_map(incoming, target_type, value, id);
1385}
1386
1387void TTCN_Logger::log_dualport_discard(boolean incoming, const char *target_type,
1388 const char *port_name, boolean unhandled)
1389{
1390 get_logger_plugin_manager()->log_dualport_discard(incoming, target_type, port_name,
1391 unhandled);
1392}
1393
1394void 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)
1397{
1398 get_logger_plugin_manager()->log_port_misc(reason, port_name,
1399 remote_component, remote_port, ip_address, tcp_port, new_size);
1400}
1401
1402void TTCN_Logger::log_random(int action, double v, unsigned long u)
1403{
1404 get_logger_plugin_manager()->log_random(action, v, u);
1405}
1406
1407void TTCN_Logger::clear_parameters() {
1408 get_logger_plugin_manager()->clear_param_list();
1409 get_logger_plugin_manager()->clear_plugin_list();
1410}
1411
1412// The one instance (only for backward compatibility).
1413TTCN_Logger TTCN_logger;
1414
1415// Location related stuff.
1416TTCN_Location *TTCN_Location::innermost_location = NULL,
1417 *TTCN_Location::outermost_location = NULL;
1418
1419TTCN_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)
1425{
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;
1432}
1433
1434void TTCN_Location::update_lineno(unsigned int new_lineno)
1435{
1436 line_number = new_lineno;
1437}
1438
1439TTCN_Location::~TTCN_Location()
1440{
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;
1445}
1446
1447char *TTCN_Location::print_location(boolean print_outers,
1448 boolean print_innermost, boolean print_entity_name)
1449{
1450 char *ret_val = NULL;
1451 if (innermost_location != NULL) {
1452 if (print_outers) {
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);
1457 }
1458 if (print_innermost)
1459 ret_val = innermost_location->append_contents(ret_val,
1460 print_entity_name);
1461 }
1462 return ret_val;
1463}
1464
1465void TTCN_Location::strip_entity_name(char*& par_str)
1466{
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++) {
1471 switch (*str_ptr) {
1472 case '(':
1473 in_paren = true;
1474 break;
1475 case ')':
1476 in_paren = false;
1477 break;
1478 default:
1479 if (!in_paren) new_str = mputc(new_str, *str_ptr);
1480 break;
1481 }
1482 }
1483 Free(par_str);
1484 par_str = new_str;
1485}
1486
1487char *TTCN_Location::append_contents(char *par_str,
1488 boolean print_entity_name) const
1489{
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);
1496 break;
1497 case LOCATION_TESTCASE:
1498 par_str = mputprintf(par_str, "(testcase:%s)", entity_name);
1499 break;
1500 case LOCATION_ALTSTEP:
1501 par_str = mputprintf(par_str, "(altstep:%s)", entity_name);
1502 break;
1503 case LOCATION_FUNCTION:
1504 par_str = mputprintf(par_str, "(function:%s)", entity_name);
1505 break;
1506 case LOCATION_EXTERNALFUNCTION:
1507 par_str = mputprintf(par_str, "(externalfunction:%s)", entity_name);
1508 break;
1509 case LOCATION_TEMPLATE:
1510 par_str = mputprintf(par_str, "(template:%s)", entity_name);
1511 break;
1512 default:
1513 break;
1514 }
1515 }
1516 return par_str;
1517}
1518
1519TTCN_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)
1523{
1524 TCov::hit(file_name, line_number, entity_name);
1525}
1526
1527void TTCN_Location_Statistics::update_lineno(unsigned int new_lineno)
1528{
1529 TTCN_Location::update_lineno(new_lineno);
1530 TCov::hit(file_name, line_number);
1531}
1532
1533void TTCN_Location_Statistics::init_file_lines(const char *file_name, const int line_nos[], size_t line_nos_len)
1534{
1535 TCov::init_file_lines(file_name, line_nos, line_nos_len);
1536}
1537
1538void TTCN_Location_Statistics::init_file_functions(const char *file_name, const char *function_names[], size_t function_names_len)
1539{
1540 TCov::init_file_functions(file_name, function_names, function_names_len);
1541}
1542
1543TTCN_Location_Statistics::~TTCN_Location_Statistics() { }
1544
1545expstring_t component_string(const component_id_t& comp_id)
1546{
1547 expstring_t retval;
1548 switch( comp_id.id_selector ) {
1549 case COMPONENT_ID_NAME:
1550 retval = mcopystr(comp_id.id_name);
1551 break;
1552 case COMPONENT_ID_COMPREF:
1553 retval = mprintf("%d", comp_id.id_compref);
1554 break;
1555 case COMPONENT_ID_ALL:
1556 retval = mcopystr("*");
1557 break;
1558 case COMPONENT_ID_SYSTEM:
1559 retval = mcopystr("<System>");
1560 break;
1561 default: // Can't happen.
1562 retval = mcopystr("Unknown component type !");
1563 break;
1564 }
1565 return retval;
1566}
This page took 0.078765 seconds and 5 git commands to generate.