Sync with 5.4.0
[deliverable/titan.core.git] / core / Logger.cc
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 ///////////////////////////////////////////////////////////////////////////////
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
44 If \p comp.id_selector is COMPONENT_ID_NAME, returns \p comp.id_name
45
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
48
49 If \p comp.id_selector is COMPONENT_ID_ALL, returns "All".
50
51 If \p comp.id_selector is COMPONENT_ID_SYSTEM, returns "System".
52
53 @param comp component identifier
54 @return string
55 */
56 expstring_t component_string(const component_id_t& comp);
57
58
59 /** @name Private data structures
60 @{
61 */
62
63 /** Log mask
64
65 For TTCN_Logger internal use, no user serviceable parts.
66 */
67 struct 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
75 class LogEventType;
76
77 /* Static members */
78
79 LoggerPluginManager *TTCN_Logger::plugins_ = NULL;
80
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;
85
86 TTCN_Logger::emergency_logging_behaviour_t TTCN_Logger::emergency_logging_behaviour = BUFFER_MASKED;
87 size_t TTCN_Logger::emergency_logging;
88
89 TTCN_Logger::matching_verbosity_t TTCN_Logger::matching_verbosity = VERBOSITY_COMPACT;
90
91 /** Timestamp format in the log files. */
92 TTCN_Logger::timestamp_format_t TTCN_Logger::timestamp_format = TIMESTAMP_TIME;
93
94 /** LogSourceInfo/SourceInfoFormat */
95 TTCN_Logger::source_info_format_t TTCN_Logger::source_info_format = SINFO_SINGLE;
96
97 /** LogEventTypes */
98 TTCN_Logger::log_event_types_t TTCN_Logger::log_event_types = LOGEVENTTYPES_NO;
99
100 // This array should contain all the _UNQUALIFIED severities.
101 const 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
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
119 };
120
121 const 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 */
144 const 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",
224 "UNQUALIFIED"
225 };
226
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;
231
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()
235 {
236 return logmatch_buffer_len;
237 }
238
239 void TTCN_Logger::set_logmatch_buffer_len(size_t new_len)
240 {
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';
247 }
248
249 void TTCN_Logger::print_logmatch_buffer()
250 {
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);
255 }
256
257 void TTCN_Logger::log_logmatch_info(const char *fmt_str, ...)
258 {
259 va_list p_var;
260 va_start(p_var, fmt_str);
261
262 if (fmt_str == NULL) fmt_str = "<NULL format string>";
263 for ( ; ; ) {
264 size_t free_space = logmatch_buffer_size - logmatch_buffer_len;
265 // Make a copy of p_var to allow multiple calls of vsnprintf().
266 va_list p_var2;
267 va_copy(p_var2, p_var);
268 int fragment_len = vsnprintf(logmatch_buffer + logmatch_buffer_len,
269 free_space, fmt_str, p_var2);
270 va_end(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);
274 else {
275 logmatch_buffer_len += fragment_len;
276 break;
277 }
278 }
279 va_end(p_var);
280 }
281
282 /** The "beginning of time" for the logger (seconds and microseconds
283 * since the Epoch)
284 */
285 struct timeval TTCN_Logger::start_time;
286
287 /** The base name of the current executable (no path, no extension) */
288 char *TTCN_Logger::executable_name = NULL;
289
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;
293
294 /// The default log format is the legacy (original) format.
295 TTCN_Logger::data_log_format_t TTCN_Logger::data_log_format = LF_LEGACY;
296
297 #include <assert.h>
298
299 /** @brief Equality operator for component_id_t
300
301 @param left component identifier
302 @param right component identifier
303 @return true if \p left and \p right refer to the same component
304
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.
308
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,
313 returns \c true.
314
315 */
316 bool operator==(const component_id_t& left, const component_id_t& right)
317 {
318 if (left.id_selector != right.id_selector)
319 return false;
320
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.
328 return true;
329 }
330 }
331
332 char *TTCN_Logger::mputstr_severity(char *str, const TTCN_Logger::Severity& severity)
333 {
334 switch (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");
390 break;
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");
415 default:
416 return mputstr(str, "UNKNOWN");
417 }
418 }
419
420 char *TTCN_Logger::mputstr_timestamp(char *str,
421 timestamp_format_t p_timestamp_format,
422 const struct timeval *tv)
423 {
424 if (p_timestamp_format == TIMESTAMP_SECONDS) {
425 struct timeval diff;
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);
429 } else {
430 diff.tv_sec = tv->tv_sec - start_time.tv_sec;
431 diff.tv_usec = tv->tv_usec - start_time.tv_usec;
432 }
433 str = mputprintf(str, "%ld.%06ld", (long)diff.tv_sec, diff.tv_usec);
434 } else {
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);
441 } else {
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,
447 tv->tv_usec);
448 }
449 }
450 return str;
451 }
452
453 CHARSTRING TTCN_Logger::get_timestamp_str(timestamp_format_t p_timestamp_format)
454 {
455 struct timeval tv;
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);
460 Free(str);
461 return ret_val;
462 }
463
464 CHARSTRING TTCN_Logger::get_source_info_str(source_info_format_t
465 p_source_info_format)
466 {
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);
472 Free(source_info);
473 return ret_val;
474 }
475
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
479 */
480 void TTCN_Logger::fatal_error(const char *err_msg, ...)
481 {
482 fputs("Fatal error during logging: ", stderr);
483 va_list p_var;
484 va_start(p_var, err_msg);
485 vfprintf(stderr, err_msg, p_var);
486 va_end(p_var);
487 OS_error();
488 fputs(" Exiting.\n", stderr);
489 exit(EXIT_FAILURE);
490 }
491
492 void TTCN_Logger::initialize_logger()
493 {
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;
498
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;
503
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;
508
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;
513 }
514
515 void TTCN_Logger::terminate_logger()
516 {
517 // Get rid of plug-ins at first.
518 if (plugins_) {
519 plugins_->unload_plugins();
520 delete plugins_;
521 plugins_ = NULL;
522 }
523
524 Free(executable_name);
525 executable_name = NULL;
526
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);
531 }
532
533 if (COMPONENT_ID_NAME == file_log_mask.component_id.id_selector) {
534 Free(file_log_mask.component_id.id_name);
535 }
536
537 if (COMPONENT_ID_NAME == emergency_log_mask.component_id.id_selector) {
538 Free(emergency_log_mask.component_id.id_name);
539 }
540
541 Free(logmatch_buffer);
542 logmatch_buffer = NULL;
543 }
544
545 bool TTCN_Logger::is_logger_up()
546 {
547 if (logmatch_buffer == NULL) return FALSE;
548 return get_logger_plugin_manager()->plugins_ready();
549 }
550
551 void TTCN_Logger::reset_configuration()
552 {
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;
556
557 timestamp_format = TIMESTAMP_TIME;
558 source_info_format = SINFO_NONE;
559 log_event_types = LOGEVENTTYPES_NO;
560 log_entity_name = FALSE;
561
562 get_logger_plugin_manager()->reset();
563 }
564
565 void TTCN_Logger::set_executable_name(const char *argv_0)
566 {
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))
571 name_end -= 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] == '/') {
576 name_begin = i + 1;
577 break;
578 }
579 }
580 int name_len = name_end - name_begin;
581 if (name_len > 0) {
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;
586 }
587
588 bool TTCN_Logger::add_parameter(const logging_setting_t& logging_param)
589 {
590 return get_logger_plugin_manager()->add_parameter(logging_param);
591 }
592
593 void TTCN_Logger::set_plugin_parameters(component component_reference,
594 const char *component_name)
595 {
596 get_logger_plugin_manager()->set_parameters(component_reference,
597 component_name);
598 }
599
600 void TTCN_Logger::load_plugins(component component_reference,
601 const char *component_name)
602 {
603 get_logger_plugin_manager()->load_plugins(component_reference,
604 component_name);
605 }
606
607 void TTCN_Logger::set_file_name(const char *new_filename_skeleton,
608 boolean from_config)
609 {
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);
614 }
615
616 bool TTCN_Logger::set_file_size(component_id_t const& comp, int p_size)
617 {
618 return get_logger_plugin_manager()->set_file_size(comp, p_size);
619 }
620
621 bool TTCN_Logger::set_file_number(component_id_t const& comp, int p_number)
622 {
623 return get_logger_plugin_manager()->set_file_number(comp, p_number);
624 }
625
626 bool TTCN_Logger::set_disk_full_action(component_id_t const& comp,
627 disk_full_action_t p_disk_full_action)
628 {
629 return get_logger_plugin_manager()
630 ->set_disk_full_action(comp, p_disk_full_action);
631 }
632
633 void TTCN_Logger::set_start_time()
634 {
635 if (gettimeofday(&start_time, NULL) == -1) {
636 fatal_error("gettimeofday() system call failed.");
637 }
638 }
639
640 LoggerPluginManager *TTCN_Logger::get_logger_plugin_manager()
641 {
642 if (!plugins_) plugins_ = new LoggerPluginManager();
643 return plugins_;
644 }
645
646
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)
650 {
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;
662 }
663
664 void TTCN_Logger::set_console_mask(component_id_t const& cmpt, const Logging_Bits& new_console_mask)
665 {
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;
677 }
678
679 void TTCN_Logger::set_emergency_logging_mask(component_id_t const& cmpt, const Logging_Bits& new_logging_mask)
680 {
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;
692 }
693
694 void TTCN_Logger::set_emergency_logging_behaviour(emergency_logging_behaviour_t behaviour)
695 {
696 emergency_logging_behaviour= behaviour;
697 }
698
699 TTCN_Logger::emergency_logging_behaviour_t TTCN_Logger::get_emergency_logging_behaviour()
700 {
701 return emergency_logging_behaviour;
702 }
703
704 size_t TTCN_Logger::get_emergency_logging()
705 {
706 return emergency_logging;
707 }
708
709 void TTCN_Logger::set_emergency_logging(size_t size)
710 {
711 emergency_logging = size;
712 }
713
714 Logging_Bits const& TTCN_Logger::get_file_mask()
715 {
716 return file_log_mask.mask;
717 }
718
719 Logging_Bits const& TTCN_Logger::get_console_mask()
720 {
721 return console_log_mask.mask;
722 }
723
724 Logging_Bits const& TTCN_Logger::get_emergency_logging_mask()
725 {
726 return emergency_log_mask.mask;
727 }
728
729 void TTCN_Logger::register_plugin(const component_id_t comp, char *identifier, char *filename)
730 {
731 get_logger_plugin_manager()->register_plugin(comp, identifier, filename);
732 }
733
734 char *TTCN_Logger::get_logger_settings_str()
735 {
736 static const char *timestamp_format_names[] = {
737 "Time", "DateTime", "Seconds"
738 };
739 static const char *logeventtype_names[] = {
740 "No", "Yes", "Subcategories"
741 };
742 static const char *source_info_format_names[] = {
743 "None", "Single", "Stack"
744 };
745
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();
752
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);
763
764 Free(filemask_origin);
765 Free(consolemask_origin);
766 Free(filemask_description);
767 Free(consolemask_description);
768
769 return new_log_message;
770 }
771
772 void TTCN_Logger::write_logger_settings(bool /*opening*/)
773 {
774 expstring_t new_log_message = get_logger_settings_str();
775
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));
780
781 Free(new_log_message);
782 }
783
784 boolean TTCN_Logger::should_log_to_file(TTCN_Logger::Severity sev)
785 {
786 if (sev > 0 && sev < TTCN_Logger::NUMBER_OF_LOGSEVERITIES) {
787 return file_log_mask.mask.bits[sev];
788 }
789 return false;
790 }
791
792 boolean TTCN_Logger::should_log_to_console(TTCN_Logger::Severity sev)
793 {
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];
798 }
799 return false;
800 }
801
802 boolean TTCN_Logger::should_log_to_emergency(TTCN_Logger::Severity sev)
803 {
804 if (sev > 0 && sev < TTCN_Logger::NUMBER_OF_LOGSEVERITIES) {
805 return emergency_log_mask.mask.bits[sev];
806 }
807 return false;
808 }
809
810 void TTCN_Logger::set_timestamp_format(timestamp_format_t new_timestamp_format)
811 {
812 timestamp_format = new_timestamp_format;
813 }
814
815 void TTCN_Logger::set_source_info_format(source_info_format_t new_source_info_format)
816 {
817 source_info_format = new_source_info_format;
818 }
819
820 void TTCN_Logger::set_log_event_types(log_event_types_t new_log_event_types)
821 {
822 log_event_types = new_log_event_types;
823 }
824
825 void TTCN_Logger::set_append_file(boolean new_append_file)
826 {
827 get_logger_plugin_manager()->set_append_file(new_append_file);
828 }
829
830 void TTCN_Logger::set_log_entity_name(boolean new_log_entity_name)
831 {
832 log_entity_name = new_log_entity_name;
833 }
834
835 void TTCN_Logger::open_file()
836 {
837 get_logger_plugin_manager()->open_file();
838 }
839
840 void TTCN_Logger::close_file()
841 {
842 get_logger_plugin_manager()->close_file();
843 }
844
845 void TTCN_Logger::ring_buffer_dump(bool do_close_file)
846 {
847 get_logger_plugin_manager()->ring_buffer_dump(do_close_file);
848 }
849
850 unsigned int TTCN_Logger::get_mask()
851 {
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;
856 }
857
858 TTCN_Logger::matching_verbosity_t TTCN_Logger::get_matching_verbosity()
859 {
860 return matching_verbosity;
861 }
862
863 void TTCN_Logger::set_matching_verbosity(TTCN_Logger::matching_verbosity_t v)
864 {
865 matching_verbosity = v;
866 }
867
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
870 // plug-ins.
871 boolean TTCN_Logger::log_this_event(TTCN_Logger::Severity event_severity)
872 {
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;
877 else return FALSE;
878 }
879
880 void TTCN_Logger::log(TTCN_Logger::Severity msg_severity,
881 const char *fmt_str, ...)
882 {
883 va_list p_var;
884 va_start(p_var, fmt_str);
885 log_va_list(msg_severity, fmt_str, p_var);
886 va_end(p_var);
887 }
888
889 void TTCN_Logger::send_event_as_error()
890 {
891 char* error_msg = get_logger_plugin_manager()->get_current_event_str();
892 if (!error_msg)
893 return;
894
895 if (TTCN_Communication::is_mc_connected()) {
896 TTCN_Communication::send_error("%s", error_msg);
897 } else {
898 fprintf(stderr, "%s\n", error_msg);
899 }
900 Free(error_msg);
901 }
902
903 // Part of the external interface. Don't touch.
904 void TTCN_Logger::log_str(TTCN_Logger::Severity msg_severity,
905 const char *str_ptr)
906 {
907 if (!log_this_event(msg_severity)) return;
908 if (str_ptr == NULL)
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;
913 }
914
915 void TTCN_Logger::log_va_list(TTCN_Logger::Severity msg_severity,
916 const char *fmt_str, va_list p_var)
917 {
918 get_logger_plugin_manager()->log_va_list(msg_severity, fmt_str, p_var);
919 logmatch_printed = false;
920 }
921
922 void TTCN_Logger::begin_event(TTCN_Logger::Severity msg_severity, boolean log2str)
923 {
924 get_logger_plugin_manager()->begin_event(msg_severity, log2str);
925 }
926
927 void TTCN_Logger::end_event()
928 {
929 get_logger_plugin_manager()->end_event();
930 // TODO: Find another place for these...
931 logmatch_printed = false;
932 }
933
934 CHARSTRING TTCN_Logger::end_event_log2str()
935 {
936 CHARSTRING ret_val = get_logger_plugin_manager()->end_event_log2str();
937 logmatch_printed = false;
938 return ret_val;
939 }
940
941 void TTCN_Logger::finish_event()
942 {
943 get_logger_plugin_manager()->finish_event();
944 }
945
946 void TTCN_Logger::log_event(const char *fmt_str, ...)
947 {
948 va_list p_var;
949 va_start(p_var, fmt_str);
950 log_event_va_list(fmt_str, p_var);
951 va_end(p_var);
952 }
953
954 void TTCN_Logger::log_event_str(const char *str_ptr)
955 {
956 get_logger_plugin_manager()->log_event_str(str_ptr);
957 logmatch_printed = false;
958 }
959
960 void TTCN_Logger::log_event_va_list(const char *fmt_str, va_list p_var)
961 {
962 get_logger_plugin_manager()->log_event_va_list(fmt_str, p_var);
963 logmatch_printed = false;
964 }
965
966 void TTCN_Logger::log_event_unbound()
967 {
968 switch (data_log_format) {
969 case LF_LEGACY:
970 log_event_str("<unbound>");
971 break;
972 case LF_TTCN:
973 log_char('-');
974 break;
975 default:
976 log_event_str("<unknown>");
977 }
978 }
979
980 void TTCN_Logger::log_event_uninitialized()
981 {
982 switch (data_log_format) {
983 case LF_LEGACY:
984 log_event_str("<uninitialized template>");
985 break;
986 case LF_TTCN:
987 log_char('-');
988 break;
989 default:
990 log_event_str("<unknown>");
991 }
992 }
993
994 void TTCN_Logger::log_event_enum(const char* enum_name_str, int enum_value)
995 {
996 switch (data_log_format) {
997 case LF_LEGACY:
998 TTCN_Logger::log_event("%s (%d)", enum_name_str, enum_value);
999 break;
1000 case LF_TTCN:
1001 log_event_str(enum_name_str);
1002 break;
1003 default:
1004 log_event_str("<unknown>");
1005 }
1006 }
1007
1008 void TTCN_Logger::log_char(char c)
1009 {
1010 get_logger_plugin_manager()->log_char(c);
1011 logmatch_printed = false;
1012 }
1013
1014 boolean TTCN_Logger::is_printable(unsigned char c)
1015 {
1016 if (!isascii(c)) return FALSE;
1017 else if (isprint(c)) return TRUE;
1018 else {
1019 switch (c) {
1020 case '\a':
1021 case '\b':
1022 case '\t':
1023 case '\n':
1024 case '\v':
1025 case '\f':
1026 case '\r':
1027 return TRUE;
1028 default:
1029 return FALSE;
1030 }
1031 }
1032 }
1033
1034 void TTCN_Logger::log_char_escaped(unsigned char c)
1035 {
1036 switch (c) {
1037 case '\n':
1038 log_event_str("\\n");
1039 break;
1040 case '\t':
1041 log_event_str("\\t");
1042 break;
1043 case '\v':
1044 log_event_str("\\v");
1045 break;
1046 case '\b':
1047 log_event_str("\\b");
1048 break;
1049 case '\r':
1050 log_event_str("\\r");
1051 break;
1052 case '\f':
1053 log_event_str("\\f");
1054 break;
1055 case '\a':
1056 log_event_str("\\a");
1057 break;
1058 case '\\':
1059 log_event_str("\\\\");
1060 break;
1061 case '"':
1062 log_event_str("\\\"");
1063 break;
1064 default:
1065 if (isprint(c)) log_char(c);
1066 else log_event("\\%03o", c);
1067 break;
1068 }
1069 }
1070
1071 void TTCN_Logger::log_char_escaped(unsigned char c, char*& p_buffer) {
1072 switch (c) {
1073 case '\n':
1074 p_buffer = mputstr(p_buffer, "\\n");
1075 break;
1076 case '\t':
1077 p_buffer = mputstr(p_buffer, "\\t");
1078 break;
1079 case '\v':
1080 p_buffer = mputstr(p_buffer, "\\v");
1081 break;
1082 case '\b':
1083 p_buffer = mputstr(p_buffer, "\\b");
1084 break;
1085 case '\r':
1086 p_buffer = mputstr(p_buffer, "\\r");
1087 break;
1088 case '\f':
1089 p_buffer = mputstr(p_buffer, "\\f");
1090 break;
1091 case '\a':
1092 p_buffer = mputstr(p_buffer, "\\a");
1093 break;
1094 case '\\':
1095 p_buffer = mputstr(p_buffer, "\\\\");
1096 break;
1097 case '"':
1098 p_buffer = mputstr(p_buffer, "\\\"");
1099 break;
1100 default:
1101 if (isprint(c)) p_buffer = mputc(p_buffer, c);
1102 else
1103 p_buffer = mputprintf(p_buffer, "\\%03o", c);
1104 break;
1105 }
1106 }
1107
1108 static const char hex_digits[] = { '0', '1', '2', '3', '4', '5', '6', '7',
1109 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1110
1111 void TTCN_Logger::log_hex(unsigned char nibble)
1112 {
1113 if (nibble < 16) log_char(hex_digits[nibble]);
1114 else log_event_str("<unknown>");
1115 }
1116
1117 void TTCN_Logger::log_octet(unsigned char octet)
1118 {
1119 log_char(hex_digits[octet >> 4]);
1120 log_char(hex_digits[octet & 0x0F]);
1121 }
1122
1123 void TTCN_Logger::OS_error()
1124 {
1125 if (errno != 0) {
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);
1129 errno = 0;
1130 }
1131 }
1132
1133 void TTCN_Logger::log_timer_read(const char *timer_name,
1134 double timeout_val)
1135 {
1136 get_logger_plugin_manager()->log_timer_read(timer_name, timeout_val);
1137 }
1138
1139 void TTCN_Logger::log_timer_start(const char *timer_name, double start_val)
1140 {
1141 get_logger_plugin_manager()->log_timer_start(timer_name, start_val);
1142 }
1143
1144 void TTCN_Logger::log_timer_guard(double start_val)
1145 {
1146 get_logger_plugin_manager()->log_timer_guard(start_val);
1147 }
1148
1149 void TTCN_Logger::log_timer_stop(const char *timer_name, double stop_val)
1150 {
1151 get_logger_plugin_manager()->log_timer_stop(timer_name, stop_val);
1152 }
1153
1154 void TTCN_Logger::log_timer_timeout(const char *timer_name,
1155 double timeout_val)
1156 {
1157 get_logger_plugin_manager()->log_timer_timeout(timer_name, timeout_val);
1158 }
1159
1160 void TTCN_Logger::log_timer_any_timeout()
1161 {
1162 get_logger_plugin_manager()->log_timer_any_timeout();
1163 }
1164
1165 void TTCN_Logger::log_timer_unqualified(const char *message)
1166 {
1167 get_logger_plugin_manager()->log_timer_unqualified(message);
1168 }
1169
1170 void TTCN_Logger::log_testcase_started(const qualified_name& testcase_name)
1171 {
1172 get_logger_plugin_manager()->log_testcase_started(testcase_name);
1173 }
1174
1175 void TTCN_Logger::log_testcase_finished(const qualified_name& testcase_name,
1176 verdicttype verdict,
1177 const char *reason)
1178 {
1179 get_logger_plugin_manager()->log_testcase_finished(testcase_name, verdict, reason);
1180 }
1181
1182 void TTCN_Logger::log_setverdict(verdicttype new_verdict, verdicttype old_verdict,
1183 verdicttype local_verdict, const char *old_reason, const char *new_reason)
1184 {
1185 get_logger_plugin_manager()->log_setverdict(new_verdict, old_verdict,
1186 local_verdict, old_reason, new_reason);
1187 }
1188
1189 void TTCN_Logger::log_getverdict(verdicttype verdict)
1190 {
1191 get_logger_plugin_manager()->log_getverdict(verdict);
1192 }
1193
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)
1198 {
1199 get_logger_plugin_manager()->log_final_verdict(is_ptc, ptc_verdict,
1200 local_verdict, new_verdict, verdict_reason, notification, ptc_compref, ptc_name);
1201 }
1202
1203 void TTCN_Logger::log_controlpart_start_stop(const char *module_name, int finished)
1204 {
1205 get_logger_plugin_manager()->log_controlpart_start_stop(module_name, finished);
1206 }
1207
1208 void TTCN_Logger::log_controlpart_errors(unsigned int error_count)
1209 {
1210 get_logger_plugin_manager()->log_controlpart_errors(error_count);
1211 }
1212
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)
1218 {
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);
1224 }
1225
1226 void TTCN_Logger::log_defaultop_activate(const char *name, int id)
1227 {
1228 get_logger_plugin_manager()->log_defaultop_activate(name, id);
1229 }
1230
1231 void TTCN_Logger::log_defaultop_deactivate(const char *name, int id)
1232 {
1233 get_logger_plugin_manager()->log_defaultop_deactivate(name, id);
1234 }
1235
1236 void TTCN_Logger::log_defaultop_exit(const char *name, int id, int x)
1237 {
1238 get_logger_plugin_manager()->log_defaultop_exit(name, id, x);
1239 }
1240
1241 void TTCN_Logger::log_executor_runtime(int reason)
1242 {
1243 get_logger_plugin_manager()->log_executor_runtime(reason);
1244 }
1245
1246 void TTCN_Logger::log_HC_start(const char *host)
1247 {
1248 get_logger_plugin_manager()->log_HC_start(host);
1249 }
1250
1251 void TTCN_Logger::log_fd_limits(int fd_limit, long fd_set_size)
1252 {
1253 get_logger_plugin_manager()->log_fd_limits(fd_limit, fd_set_size);
1254 }
1255
1256 void TTCN_Logger::log_testcase_exec(const char *module, const char *tc)
1257 {
1258 get_logger_plugin_manager()->log_testcase_exec(module, tc);
1259 }
1260
1261 void TTCN_Logger::log_module_init(const char *module, bool finish)
1262 {
1263 get_logger_plugin_manager()->log_module_init(module, finish);
1264 }
1265
1266 void TTCN_Logger::log_mtc_created(long pid)
1267 {
1268 get_logger_plugin_manager()->log_mtc_created(pid);
1269 }
1270
1271 void TTCN_Logger::log_configdata(int reason, const char *str)
1272 {
1273 get_logger_plugin_manager()->log_configdata(reason, str);
1274 }
1275
1276 void TTCN_Logger::log_executor_component(int reason)
1277 {
1278 get_logger_plugin_manager()->log_executor_component(reason);
1279 }
1280
1281 void TTCN_Logger::log_executor_misc(int reason, const char *name,
1282 const char *address, int port)
1283 {
1284 get_logger_plugin_manager()->log_executor_misc(reason, name, address, port);
1285 }
1286
1287 void TTCN_Logger::log_extcommand(extcommand_t action, const char *cmd)
1288 {
1289 get_logger_plugin_manager()->log_extcommand(action, cmd);
1290 }
1291
1292 void TTCN_Logger::log_matching_done(const char *type, int ptc,
1293 const char *return_type, int reason)
1294 {
1295 get_logger_plugin_manager()->log_matching_done(reason, type, ptc, return_type);
1296 }
1297
1298 void TTCN_Logger::log_matching_problem(int reason, int operation, boolean check,
1299 boolean anyport, const char *port_name)
1300 {
1301 get_logger_plugin_manager()->log_matching_problem(reason, operation,
1302 check, anyport, port_name);
1303 }
1304
1305 void TTCN_Logger::log_matching_success(int port_type, const char *port_name,
1306 int compref, const CHARSTRING& info)
1307 {
1308 get_logger_plugin_manager()->log_matching_success(port_type, port_name,
1309 compref, info);
1310 }
1311
1312 void TTCN_Logger::log_matching_failure(int port_type, const char *port_name,
1313 int compref, int reason, const CHARSTRING& info)
1314 {
1315 get_logger_plugin_manager()->log_matching_failure(port_type, port_name,
1316 compref, reason, info);
1317 }
1318
1319 void TTCN_Logger::log_matching_timeout(const char *timer_name)
1320 {
1321 get_logger_plugin_manager()->log_matching_timeout(timer_name);
1322 }
1323
1324 void TTCN_Logger::log_portconnmap(int operation, int src_compref, const char *src_port,
1325 int dst_compref, const char *dst_port)
1326 {
1327 get_logger_plugin_manager()->log_portconnmap(operation, src_compref, src_port,
1328 dst_compref, dst_port);
1329 }
1330
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)
1333 {
1334 get_logger_plugin_manager()->log_par_ptc(reason, module, name, compref,
1335 compname, tc_loc, alive_pid, status);
1336 }
1337
1338 void TTCN_Logger::log_port_queue(int operation, const char *port_name, int compref,
1339 int id, const CHARSTRING& address, const CHARSTRING& param)
1340 {
1341 get_logger_plugin_manager()->log_port_queue(operation, port_name, compref,
1342 id, address, param);
1343 }
1344
1345 void TTCN_Logger::log_port_state(int operation, const char *port_name)
1346 {
1347 get_logger_plugin_manager()->log_port_state(operation, port_name);
1348 }
1349
1350 void TTCN_Logger::log_procport_send(const char *portname, int operation, int compref,
1351 const CHARSTRING& system, const CHARSTRING& param)
1352 {
1353 get_logger_plugin_manager()->log_procport_send(portname, operation, compref,
1354 system, param);
1355 }
1356
1357 void TTCN_Logger::log_procport_recv(const char *portname, int operation,
1358 int compref, boolean check, const CHARSTRING& param, int id)
1359 {
1360 get_logger_plugin_manager()->log_procport_recv(portname, operation, compref,
1361 check, param, id);
1362 }
1363
1364 void TTCN_Logger::log_msgport_send(const char *portname, int compref,
1365 const CHARSTRING& param)
1366 {
1367 get_logger_plugin_manager()->log_msgport_send(portname, compref, param);
1368 }
1369
1370 void TTCN_Logger::log_msgport_recv(const char *portname, int operation, int compref,
1371 const CHARSTRING& system, const CHARSTRING& param, int id)
1372 {
1373 get_logger_plugin_manager()->log_msgport_recv(portname, operation, compref,
1374 system, param, id);
1375 }
1376
1377 void TTCN_Logger::log_dualport_map(boolean incoming, const char *target_type,
1378 const CHARSTRING& value, int id)
1379 {
1380 get_logger_plugin_manager()->log_dualport_map(incoming, target_type, value, id);
1381 }
1382
1383 void TTCN_Logger::log_dualport_discard(boolean incoming, const char *target_type,
1384 const char *port_name, boolean unhandled)
1385 {
1386 get_logger_plugin_manager()->log_dualport_discard(incoming, target_type, port_name,
1387 unhandled);
1388 }
1389
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)
1393 {
1394 get_logger_plugin_manager()->log_port_misc(reason, port_name,
1395 remote_component, remote_port, ip_address, tcp_port, new_size);
1396 }
1397
1398 void TTCN_Logger::log_random(int action, double v, unsigned long u)
1399 {
1400 get_logger_plugin_manager()->log_random(action, v, u);
1401 }
1402
1403 void TTCN_Logger::clear_parameters() {
1404 get_logger_plugin_manager()->clear_param_list();
1405 get_logger_plugin_manager()->clear_plugin_list();
1406 }
1407
1408 // The one instance (only for backward compatibility).
1409 TTCN_Logger TTCN_logger;
1410
1411 // Location related stuff.
1412 TTCN_Location *TTCN_Location::innermost_location = NULL,
1413 *TTCN_Location::outermost_location = NULL;
1414
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)
1421 {
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;
1428 }
1429
1430 void TTCN_Location::update_lineno(unsigned int new_lineno)
1431 {
1432 line_number = new_lineno;
1433 }
1434
1435 TTCN_Location::~TTCN_Location()
1436 {
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;
1441 }
1442
1443 char *TTCN_Location::print_location(boolean print_outers,
1444 boolean print_innermost, boolean print_entity_name)
1445 {
1446 char *ret_val = NULL;
1447 if (innermost_location != NULL) {
1448 if (print_outers) {
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);
1453 }
1454 if (print_innermost)
1455 ret_val = innermost_location->append_contents(ret_val,
1456 print_entity_name);
1457 }
1458 return ret_val;
1459 }
1460
1461 void TTCN_Location::strip_entity_name(char*& par_str)
1462 {
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++) {
1467 switch (*str_ptr) {
1468 case '(':
1469 in_paren = true;
1470 break;
1471 case ')':
1472 in_paren = false;
1473 break;
1474 default:
1475 if (!in_paren) new_str = mputc(new_str, *str_ptr);
1476 break;
1477 }
1478 }
1479 Free(par_str);
1480 par_str = new_str;
1481 }
1482
1483 char *TTCN_Location::append_contents(char *par_str,
1484 boolean print_entity_name) const
1485 {
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);
1492 break;
1493 case LOCATION_TESTCASE:
1494 par_str = mputprintf(par_str, "(testcase:%s)", entity_name);
1495 break;
1496 case LOCATION_ALTSTEP:
1497 par_str = mputprintf(par_str, "(altstep:%s)", entity_name);
1498 break;
1499 case LOCATION_FUNCTION:
1500 par_str = mputprintf(par_str, "(function:%s)", entity_name);
1501 break;
1502 case LOCATION_EXTERNALFUNCTION:
1503 par_str = mputprintf(par_str, "(externalfunction:%s)", entity_name);
1504 break;
1505 case LOCATION_TEMPLATE:
1506 par_str = mputprintf(par_str, "(template:%s)", entity_name);
1507 break;
1508 default:
1509 break;
1510 }
1511 }
1512 return par_str;
1513 }
1514
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)
1519 {
1520 TCov::hit(file_name, line_number, entity_name);
1521 }
1522
1523 void TTCN_Location_Statistics::update_lineno(unsigned int new_lineno)
1524 {
1525 TTCN_Location::update_lineno(new_lineno);
1526 TCov::hit(file_name, line_number);
1527 }
1528
1529 void TTCN_Location_Statistics::init_file_lines(const char *file_name, const int line_nos[], size_t line_nos_len)
1530 {
1531 TCov::init_file_lines(file_name, line_nos, line_nos_len);
1532 }
1533
1534 void TTCN_Location_Statistics::init_file_functions(const char *file_name, const char *function_names[], size_t function_names_len)
1535 {
1536 TCov::init_file_functions(file_name, function_names, function_names_len);
1537 }
1538
1539 TTCN_Location_Statistics::~TTCN_Location_Statistics() { }
1540
1541 expstring_t component_string(const component_id_t& comp_id)
1542 {
1543 expstring_t retval;
1544 switch( comp_id.id_selector ) {
1545 case COMPONENT_ID_NAME:
1546 retval = mcopystr(comp_id.id_name);
1547 break;
1548 case COMPONENT_ID_COMPREF:
1549 retval = mprintf("%d", comp_id.id_compref);
1550 break;
1551 case COMPONENT_ID_ALL:
1552 retval = mcopystr("*");
1553 break;
1554 case COMPONENT_ID_SYSTEM:
1555 retval = mcopystr("<System>");
1556 break;
1557 default: // Can't happen.
1558 retval = mcopystr("Unknown component type !");
1559 break;
1560 }
1561 return retval;
1562 }
This page took 0.064435 seconds and 6 git commands to generate.