Merge pull request #77 from balaskoa/master
[deliverable/titan.core.git] / core / Logger.cc
CommitLineData
d44e3c4f 1/******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Baranyi, Botond
11 * Beres, Szabolcs
12 * Delic, Adam
13 * Feher, Csaba
14 * Forstner, Matyas
15 * Kovacs, Ferenc
16 * Raduly, Csaba
17 * Szabados, Kristof
18 * Szabo, Janos Zoltan – initial implementation
19 * Zalanyi, Balazs Andor
20 * Pandi, Krisztian
21 *
22 ******************************************************************************/
970ed795
EL
23#include <stdio.h>
24#include <string.h>
25#include <ctype.h>
26#include <stdarg.h>
27#include <stdlib.h>
28#include <errno.h>
29#include <unistd.h>
30#include <netdb.h>
31#include <time.h>
32#include <sys/time.h>
33#include <sys/types.h>
34
35#include "../common/memory.h"
36#include "Logger.hh"
37#include "Communication.hh"
38#include "Component.hh"
39#include "LoggingBits.hh"
40#include "LoggerPluginManager.hh"
41#include "Charstring.hh"
42#include "LoggingParam.hh"
43#include "TCov.hh"
44
45/** work-around for missing va_copy() in GCC */
46#if defined(__GNUC__) && !defined(va_copy)
47# ifdef __va_copy
48# define va_copy(dest, src) __va_copy(dest, src)
49# else
50# define va_copy(dest, src) (dest) = (src)
51# endif
52#endif
53
54#define MIN_BUFFER_SIZE 1024
55
56
57/** @brief Return a string identifying the component
58
59If \p comp.id_selector is COMPONENT_ID_NAME, returns \p comp.id_name
60
61If \p comp.id_selector is COMPONENT_ID_COMPREF, returns a pointer
62to a static buffer, containing a string representation of \p comp.id_compref
63
64If \p comp.id_selector is COMPONENT_ID_ALL, returns "All".
65
66If \p comp.id_selector is COMPONENT_ID_SYSTEM, returns "System".
67
68@param comp component identifier
69@return string
70*/
71expstring_t component_string(const component_id_t& comp);
72
73
74/** @name Private data structures
75 @{
76*/
77
78/** Log mask
79
80For TTCN_Logger internal use, no user serviceable parts.
81*/
82struct TTCN_Logger::log_mask_struct
83{
84 component_id_t component_id; /**< Component */
85 Logging_Bits mask; /**< Settings for logging to console or file */
86};
87
88/** @} */
89
90class LogEventType;
91
92/* Static members */
93
94LoggerPluginManager *TTCN_Logger::plugins_ = NULL;
95
96/* No point in initializing here; will be done in initialize_logger() */
97TTCN_Logger::log_mask_struct TTCN_Logger::console_log_mask;
98TTCN_Logger::log_mask_struct TTCN_Logger::file_log_mask;
99TTCN_Logger::log_mask_struct TTCN_Logger::emergency_log_mask;
100
101TTCN_Logger::emergency_logging_behaviour_t TTCN_Logger::emergency_logging_behaviour = BUFFER_MASKED;
102size_t TTCN_Logger::emergency_logging;
d44e3c4f 103boolean TTCN_Logger::emergency_logging_for_fail_verdict = FALSE;
970ed795
EL
104
105TTCN_Logger::matching_verbosity_t TTCN_Logger::matching_verbosity = VERBOSITY_COMPACT;
106
107/** Timestamp format in the log files. */
108TTCN_Logger::timestamp_format_t TTCN_Logger::timestamp_format = TIMESTAMP_TIME;
109
110/** LogSourceInfo/SourceInfoFormat */
111TTCN_Logger::source_info_format_t TTCN_Logger::source_info_format = SINFO_SINGLE;
112
113/** LogEventTypes */
114TTCN_Logger::log_event_types_t TTCN_Logger::log_event_types = LOGEVENTTYPES_NO;
115
116// This array should contain all the _UNQUALIFIED severities.
117const TTCN_Logger::Severity TTCN_Logger::sev_categories[] =
118{
119 TTCN_Logger::NOTHING_TO_LOG, // 0
120 TTCN_Logger::ACTION_UNQUALIFIED, // 1
121 TTCN_Logger::DEFAULTOP_UNQUALIFIED, // 5
122 TTCN_Logger::ERROR_UNQUALIFIED, // 6
3f84031e 123 TTCN_Logger::EXECUTOR_UNQUALIFIED, // 12
124 TTCN_Logger::FUNCTION_UNQUALIFIED, // 14
125 TTCN_Logger::PARALLEL_UNQUALIFIED, // 18
126 TTCN_Logger::TESTCASE_UNQUALIFIED, // 21
127 TTCN_Logger::PORTEVENT_UNQUALIFIED, // 35
128 TTCN_Logger::STATISTICS_UNQUALIFIED, // 37
129 TTCN_Logger::TIMEROP_UNQUALIFIED, // 43
130 TTCN_Logger::USER_UNQUALIFIED, // 44
131 TTCN_Logger::VERDICTOP_UNQUALIFIED, // 48
132 TTCN_Logger::WARNING_UNQUALIFIED, // 49
133 TTCN_Logger::MATCHING_UNQUALIFIED, // 61
134 TTCN_Logger::DEBUG_UNQUALIFIED, // 66
970ed795
EL
135};
136
137const char* TTCN_Logger::severity_category_names[] =
138{
139 NULL,
140 "ACTION",
141 "DEFAULTOP",
142 "ERROR",
143 "EXECUTOR",
144 "FUNCTION",
145 "PARALLEL",
146 "TESTCASE",
147 "PORTEVENT",
148 "STATISTICS",
149 "TIMEROP",
150 "USER",
151 "VERDICTOP",
152 "WARNING",
153 "MATCHING",
154 "DEBUG",
155};
156
157
158/** Sub-category names for all Severity enum values,
159 * used when TTCN_Logger::log_event_types is set to log sub-categories */
160const char* TTCN_Logger::severity_subcategory_names[NUMBER_OF_LOGSEVERITIES] = {
161 "",
162 // ACTION:
163 "UNQUALIFIED",
164 // DEFAULTOP:
165 "ACTIVATE",
166 "DEACTIVATE",
167 "EXIT",
168 "UNQUALIFIED",
169 // ERROR:
170 "UNQUALIFIED",
171 // EXECUTOR:
172 "RUNTIME",
173 "CONFIGDATA",
174 "EXTCOMMAND",
175 "COMPONENT",
176 "LOGOPTIONS",
177 "UNQUALIFIED",
178 // FUNCTION:
179 "RND",
180 "UNQUALIFIED",
181 // PARALLEL:
182 "PTC",
183 "PORTCONN",
184 "PORTMAP",
185 "UNQUALIFIED",
186 // TESTCASE:
187 "START",
188 "FINISH",
189 "UNQUALIFIED",
190 // PORTEVENT:
191 "PQUEUE",
192 "MQUEUE",
193 "STATE",
194 "PMIN",
195 "PMOUT",
196 "PCIN",
197 "PCOUT",
198 "MMRECV",
199 "MMSEND",
200 "MCRECV",
201 "MCSEND",
202 "DUALRECV",
203 "DUALSEND",
204 "UNQUALIFIED",
205 // STATISTICS:
206 "VERDICT",
207 "UNQUALIFIED",
208 // TIMEROP:
209 "READ",
210 "START",
211 "GUARD",
212 "STOP",
213 "TIMEOUT",
214 "UNQUALIFIED",
215 // USER:
216 "UNQUALIFIED",
217 // VERDICTOP:
218 "GETVERDICT",
219 "SETVERDICT",
220 "FINAL",
221 "UNQUALIFIED",
222 // WARNING:
223 "UNQUALIFIED",
224 // MATCHING:
225 "DONE",
226 "TIMEOUT",
227 "PCSUCCESS",
228 "PCUNSUCC",
229 "PMSUCCESS",
230 "PMUNSUCC",
231 "MCSUCCESS",
232 "MCUNSUCC",
233 "MMSUCCESS",
234 "MMUNSUCC",
235 "PROBLEM",
236 "UNQUALIFIED",
237 // DEBUG:
238 "ENCDEC",
239 "TESTPORT",
3f84031e 240 "USER",
241 "FRAMEWORK",
970ed795
EL
242 "UNQUALIFIED"
243};
244
245char* TTCN_Logger::logmatch_buffer = NULL;
246size_t TTCN_Logger::logmatch_buffer_len = 0;
247size_t TTCN_Logger::logmatch_buffer_size = 0;
248boolean TTCN_Logger::logmatch_printed = false;
249
250// TODO: Matching related stuff stays here for now. It just appends the
251// string to the end of the current (active) event.
252size_t TTCN_Logger::get_logmatch_buffer_len()
253{
254 return logmatch_buffer_len;
255}
256
257void TTCN_Logger::set_logmatch_buffer_len(size_t new_len)
258{
259 logmatch_buffer_len = new_len;
260 logmatch_buffer_size = MIN_BUFFER_SIZE;
261 while (logmatch_buffer_size < new_len)
262 logmatch_buffer_size *= 2;
263 logmatch_buffer = (char *)Realloc(logmatch_buffer, logmatch_buffer_size);
264 logmatch_buffer[new_len] = '\0';
265}
266
267void TTCN_Logger::print_logmatch_buffer()
268{
269 if (logmatch_printed) TTCN_Logger::log_event_str(" , ");
270 else logmatch_printed = true;
271 if (logmatch_buffer_size > 0)
272 TTCN_Logger::log_event_str(logmatch_buffer);
273}
274
275void TTCN_Logger::log_logmatch_info(const char *fmt_str, ...)
276{
277 va_list p_var;
278 va_start(p_var, fmt_str);
279
280 if (fmt_str == NULL) fmt_str = "<NULL format string>";
281 for ( ; ; ) {
282 size_t free_space = logmatch_buffer_size - logmatch_buffer_len;
283 // Make a copy of p_var to allow multiple calls of vsnprintf().
284 va_list p_var2;
285 va_copy(p_var2, p_var);
286 int fragment_len = vsnprintf(logmatch_buffer + logmatch_buffer_len,
287 free_space, fmt_str, p_var2);
288 va_end(p_var2);
289 if (fragment_len < 0) set_logmatch_buffer_len(logmatch_buffer_size * 2);
290 else if ((size_t)fragment_len >= free_space)
291 set_logmatch_buffer_len(logmatch_buffer_len + fragment_len + 1);
292 else {
293 logmatch_buffer_len += fragment_len;
294 break;
295 }
296 }
297 va_end(p_var);
298}
299
300/** The "beginning of time" for the logger (seconds and microseconds
301 * since the Epoch)
302 */
303struct timeval TTCN_Logger::start_time;
304
305/** The base name of the current executable (no path, no extension) */
306char *TTCN_Logger::executable_name = NULL;
307
308/// True to log type (controlpart/altstep/testcase/function/...) and name
309/// of the entity responsible for the log message, false to suppress it.
310boolean TTCN_Logger::log_entity_name = FALSE;
311
312/// The default log format is the legacy (original) format.
313TTCN_Logger::data_log_format_t TTCN_Logger::data_log_format = LF_LEGACY;
314
315#include <assert.h>
316
317/** @brief Equality operator for component_id_t
318
319@param left component identifier
320@param right component identifier
321@return true if \p left and \p right refer to the same component
322
323@note This functions tests the equality of the component identifiers,
324not the components themselves. It can't detect that component named "foo" is
325the same as component number 3.
326
327@li If the selectors differ, returns \c false.
328@li If both selectors are COMPONENT_ID_NAME, compares the names.
329@li If both selectors are COMPONENT_ID_COMPREF, compares the comp. references.
330@li If both selectors are COMPONENT_ID_ALL or COMPONENT_ID_SYSTEM,
331returns \c true.
332
333*/
334bool operator==(const component_id_t& left, const component_id_t& right)
335{
336 if (left.id_selector != right.id_selector)
337 return false;
338
339 // The selectors are the same.
340 switch (left.id_selector) {
341 case COMPONENT_ID_NAME:
342 return !strcmp(left.id_name, right.id_name);
343 case COMPONENT_ID_COMPREF:
344 return left.id_compref == right.id_compref;
345 default: // Should be MTC or SYSTEM; identified by the selector.
346 return true;
347 }
348}
349
350char *TTCN_Logger::mputstr_severity(char *str, const TTCN_Logger::Severity& severity)
351{
352 switch (severity) {
353 case TTCN_Logger::ACTION_UNQUALIFIED:
354 return mputstr(str, "ACTION");
355 case TTCN_Logger::DEFAULTOP_ACTIVATE:
356 case TTCN_Logger::DEFAULTOP_DEACTIVATE:
357 case TTCN_Logger::DEFAULTOP_EXIT:
358 case TTCN_Logger::DEFAULTOP_UNQUALIFIED:
359 return mputstr(str, "DEFAULTOP");
360 case TTCN_Logger::ERROR_UNQUALIFIED:
361 return mputstr(str, "ERROR");
362 case TTCN_Logger::EXECUTOR_RUNTIME:
363 case TTCN_Logger::EXECUTOR_CONFIGDATA:
364 case TTCN_Logger::EXECUTOR_EXTCOMMAND:
365 case TTCN_Logger::EXECUTOR_COMPONENT:
366 case TTCN_Logger::EXECUTOR_LOGOPTIONS:
367 case TTCN_Logger::EXECUTOR_UNQUALIFIED:
368 return mputstr(str, "EXECUTOR");
369 case TTCN_Logger::FUNCTION_RND:
370 case TTCN_Logger::FUNCTION_UNQUALIFIED:
371 return mputstr(str, "FUNCTION");
372 case TTCN_Logger::PARALLEL_PTC:
373 case TTCN_Logger::PARALLEL_PORTCONN:
374 case TTCN_Logger::PARALLEL_PORTMAP:
375 case TTCN_Logger::PARALLEL_UNQUALIFIED:
376 return mputstr(str, "PARALLEL");
377 case TTCN_Logger::TESTCASE_START:
378 case TTCN_Logger::TESTCASE_FINISH:
379 case TTCN_Logger::TESTCASE_UNQUALIFIED:
380 return mputstr(str, "TESTCASE");
381 case TTCN_Logger::PORTEVENT_PQUEUE:
382 case TTCN_Logger::PORTEVENT_MQUEUE:
383 case TTCN_Logger::PORTEVENT_STATE:
384 case TTCN_Logger::PORTEVENT_PMIN:
385 case TTCN_Logger::PORTEVENT_PMOUT:
386 case TTCN_Logger::PORTEVENT_PCIN:
387 case TTCN_Logger::PORTEVENT_PCOUT:
388 case TTCN_Logger::PORTEVENT_MMRECV:
389 case TTCN_Logger::PORTEVENT_MMSEND:
390 case TTCN_Logger::PORTEVENT_MCRECV:
391 case TTCN_Logger::PORTEVENT_MCSEND:
392 case TTCN_Logger::PORTEVENT_DUALRECV:
393 case TTCN_Logger::PORTEVENT_DUALSEND:
394 case TTCN_Logger::PORTEVENT_UNQUALIFIED:
395 return mputstr(str, "PORTEVENT");
396 case TTCN_Logger::STATISTICS_VERDICT:
397 case TTCN_Logger::STATISTICS_UNQUALIFIED:
398 return mputstr(str, "STATISTICS");
399 case TTCN_Logger::TIMEROP_READ:
400 case TTCN_Logger::TIMEROP_START:
401 case TTCN_Logger::TIMEROP_GUARD:
402 case TTCN_Logger::TIMEROP_STOP:
403 case TTCN_Logger::TIMEROP_TIMEOUT:
404 case TTCN_Logger::TIMEROP_UNQUALIFIED:
405 return mputstr(str, "TIMEROP");
406 case TTCN_Logger::USER_UNQUALIFIED:
407 return mputstr(str, "USER");
408 break;
409 case TTCN_Logger::VERDICTOP_GETVERDICT:
410 case TTCN_Logger::VERDICTOP_SETVERDICT:
411 case TTCN_Logger::VERDICTOP_FINAL:
412 case TTCN_Logger::VERDICTOP_UNQUALIFIED:
413 return mputstr(str, "VERDICTOP");
414 case TTCN_Logger::WARNING_UNQUALIFIED:
415 return mputstr(str, "WARNING");
416 case TTCN_Logger::MATCHING_DONE:
417 case TTCN_Logger::MATCHING_TIMEOUT:
418 case TTCN_Logger::MATCHING_PCSUCCESS:
419 case TTCN_Logger::MATCHING_PCUNSUCC:
420 case TTCN_Logger::MATCHING_PMSUCCESS:
421 case TTCN_Logger::MATCHING_PMUNSUCC:
422 case TTCN_Logger::MATCHING_MCSUCCESS:
423 case TTCN_Logger::MATCHING_MCUNSUCC:
424 case TTCN_Logger::MATCHING_MMSUCCESS:
425 case TTCN_Logger::MATCHING_MMUNSUCC:
426 case TTCN_Logger::MATCHING_PROBLEM:
427 case TTCN_Logger::MATCHING_UNQUALIFIED:
428 return mputstr(str, "MATCHING");
429 case TTCN_Logger::DEBUG_ENCDEC:
430 case TTCN_Logger::DEBUG_TESTPORT:
3f84031e 431 case TTCN_Logger::DEBUG_USER:
432 case TTCN_Logger::DEBUG_FRAMEWORK:
970ed795
EL
433 case TTCN_Logger::DEBUG_UNQUALIFIED:
434 return mputstr(str, "DEBUG");
435 default:
436 return mputstr(str, "UNKNOWN");
437 }
438}
439
440char *TTCN_Logger::mputstr_timestamp(char *str,
441 timestamp_format_t p_timestamp_format,
442 const struct timeval *tv)
443{
444 if (p_timestamp_format == TIMESTAMP_SECONDS) {
445 struct timeval diff;
446 if (tv->tv_usec < start_time.tv_usec) {
447 diff.tv_sec = tv->tv_sec - start_time.tv_sec - 1;
448 diff.tv_usec = tv->tv_usec + (1000000L - start_time.tv_usec);
449 } else {
450 diff.tv_sec = tv->tv_sec - start_time.tv_sec;
451 diff.tv_usec = tv->tv_usec - start_time.tv_usec;
452 }
453 str = mputprintf(str, "%ld.%06ld", (long)diff.tv_sec, diff.tv_usec);
454 } else {
455 time_t tv_sec = tv->tv_sec;
456 struct tm *lt = localtime(&tv_sec);
457 if (lt == NULL) fatal_error("localtime() call failed.");
458 if (p_timestamp_format == TIMESTAMP_TIME) {
459 str = mputprintf(str, "%02d:%02d:%02d.%06ld",
460 lt->tm_hour, lt->tm_min, lt->tm_sec, tv->tv_usec);
461 } else {
462 static const char * const month_names[] = { "Jan", "Feb", "Mar",
463 "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
464 str = mputprintf(str, "%4d/%s/%02d %02d:%02d:%02d.%06ld",
465 lt->tm_year + 1900, month_names[lt->tm_mon],
466 lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec,
467 tv->tv_usec);
468 }
469 }
470 return str;
471}
472
473CHARSTRING TTCN_Logger::get_timestamp_str(timestamp_format_t p_timestamp_format)
474{
475 struct timeval tv;
476 if (gettimeofday(&tv, NULL) == -1)
477 fatal_error("gettimeofday() system call failed.");
478 char *str = mputstr_timestamp(NULL, p_timestamp_format, &tv);
479 CHARSTRING ret_val(mstrlen(str), str);
480 Free(str);
481 return ret_val;
482}
483
484CHARSTRING TTCN_Logger::get_source_info_str(source_info_format_t
485 p_source_info_format)
486{
487 if (p_source_info_format == SINFO_NONE) return CHARSTRING();
488 char *source_info = TTCN_Location::print_location(
489 p_source_info_format == SINFO_STACK, TRUE, log_entity_name);
490 if (source_info == NULL) return CHARSTRING('-');
491 CHARSTRING ret_val(mstrlen(source_info),source_info);
492 Free(source_info);
493 return ret_val;
494}
495
496/** @brief Logs a fatal error and terminates the application.
497This function doesn't return: it calls \c exit(EXIT_FAILURE);
498@param err_msg printf-style format string
499*/
500void TTCN_Logger::fatal_error(const char *err_msg, ...)
501{
502 fputs("Fatal error during logging: ", stderr);
503 va_list p_var;
504 va_start(p_var, err_msg);
505 vfprintf(stderr, err_msg, p_var);
506 va_end(p_var);
507 OS_error();
508 fputs(" Exiting.\n", stderr);
509 exit(EXIT_FAILURE);
510}
511
512void TTCN_Logger::initialize_logger()
513{
514 console_log_mask.component_id.id_selector = COMPONENT_ID_ALL;
515 console_log_mask.component_id.id_compref = ALL_COMPREF;
516 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
517 console_log_mask.mask = Logging_Bits::default_console_mask;
518
519 file_log_mask.component_id.id_selector = COMPONENT_ID_ALL;
520 file_log_mask.component_id.id_compref = ALL_COMPREF;
521 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
522 file_log_mask.mask = Logging_Bits::log_all;
523
524 emergency_log_mask.component_id.id_selector = COMPONENT_ID_ALL;
525 emergency_log_mask.component_id.id_compref = ALL_COMPREF;
526 // setting id_compref is optional when id_selector==COMPONENT_ID_ALL
527 emergency_log_mask.mask = Logging_Bits::log_all;
528
529 logmatch_buffer = (char*)Malloc(MIN_BUFFER_SIZE);
530 logmatch_buffer[0] = '\0';
531 logmatch_buffer_len = 0;
532 logmatch_buffer_size = MIN_BUFFER_SIZE;
533}
534
535void TTCN_Logger::terminate_logger()
536{
537 // Get rid of plug-ins at first.
538 if (plugins_) {
539 plugins_->unload_plugins();
540 delete plugins_;
541 plugins_ = NULL;
542 }
543
544 Free(executable_name);
545 executable_name = NULL;
546
547 // Clean up the log masks. *_log_masks (which points to the start of
548 // actual_*_log_mask) is borrowed as the "next" pointer.
549 if (COMPONENT_ID_NAME == console_log_mask.component_id.id_selector) {
550 Free(console_log_mask.component_id.id_name);
551 }
552
553 if (COMPONENT_ID_NAME == file_log_mask.component_id.id_selector) {
554 Free(file_log_mask.component_id.id_name);
555 }
556
557 if (COMPONENT_ID_NAME == emergency_log_mask.component_id.id_selector) {
558 Free(emergency_log_mask.component_id.id_name);
559 }
560
561 Free(logmatch_buffer);
562 logmatch_buffer = NULL;
563}
564
565bool TTCN_Logger::is_logger_up()
566{
567 if (logmatch_buffer == NULL) return FALSE;
568 return get_logger_plugin_manager()->plugins_ready();
569}
570
571void TTCN_Logger::reset_configuration()
572{
573 file_log_mask .mask = Logging_Bits::log_all;
574 console_log_mask.mask = Logging_Bits::default_console_mask;
575 emergency_log_mask.mask = Logging_Bits::log_all;
576
577 timestamp_format = TIMESTAMP_TIME;
578 source_info_format = SINFO_NONE;
579 log_event_types = LOGEVENTTYPES_NO;
580 log_entity_name = FALSE;
581
582 get_logger_plugin_manager()->reset();
583}
584
585void TTCN_Logger::set_executable_name(const char *argv_0)
586{
587 Free(executable_name);
588 size_t name_end = strlen(argv_0);
589 // Cut the '.exe' suffix from the end (if present).
590 if (name_end >= 4 && !strncasecmp(argv_0 + name_end - 4, ".exe", 4))
591 name_end -= 4;
592 size_t name_begin = 0;
593 // Find the last '/' (if present) to cut the leading directory part.
594 for (int i = name_end - 1; i >= 0; i--) {
595 if (argv_0[i] == '/') {
596 name_begin = i + 1;
597 break;
598 }
599 }
600 int name_len = name_end - name_begin;
601 if (name_len > 0) {
602 executable_name = (char*)Malloc(name_len + 1);
603 memcpy(executable_name, argv_0 + name_begin, name_len);
604 executable_name[name_len] = '\0';
605 } else executable_name = NULL;
606}
607
608bool TTCN_Logger::add_parameter(const logging_setting_t& logging_param)
609{
610 return get_logger_plugin_manager()->add_parameter(logging_param);
611}
612
613void TTCN_Logger::set_plugin_parameters(component component_reference,
614 const char *component_name)
615{
616 get_logger_plugin_manager()->set_parameters(component_reference,
617 component_name);
618}
619
620void TTCN_Logger::load_plugins(component component_reference,
621 const char *component_name)
622{
623 get_logger_plugin_manager()->load_plugins(component_reference,
624 component_name);
625}
626
627void TTCN_Logger::set_file_name(const char *new_filename_skeleton,
628 boolean from_config)
629{
630 // Pass the file's name to all plug-ins loaded. Not all of them is
631 // interested in this.
632 get_logger_plugin_manager()->
633 set_file_name(new_filename_skeleton, from_config);
634}
635
636bool TTCN_Logger::set_file_size(component_id_t const& comp, int p_size)
637{
638 return get_logger_plugin_manager()->set_file_size(comp, p_size);
639}
640
641bool TTCN_Logger::set_file_number(component_id_t const& comp, int p_number)
642{
643 return get_logger_plugin_manager()->set_file_number(comp, p_number);
644}
645
646bool TTCN_Logger::set_disk_full_action(component_id_t const& comp,
647 disk_full_action_t p_disk_full_action)
648{
649 return get_logger_plugin_manager()
650 ->set_disk_full_action(comp, p_disk_full_action);
651}
652
653void TTCN_Logger::set_start_time()
654{
655 if (gettimeofday(&start_time, NULL) == -1) {
656 fatal_error("gettimeofday() system call failed.");
657 }
658}
659
660LoggerPluginManager *TTCN_Logger::get_logger_plugin_manager()
661{
662 if (!plugins_) plugins_ = new LoggerPluginManager();
663 return plugins_;
664}
665
666
667// These masks can control not only file and console! They're general purpose
668// event filters, hence their name is not changed. Stay here.
669void TTCN_Logger::set_file_mask(component_id_t const& cmpt, const Logging_Bits& new_file_mask)
670{
671 // If FileMask was set with a component-specific value, do not allow
672 // overwriting with a generic value.
673 if (file_log_mask.component_id.id_selector == COMPONENT_ID_COMPREF
674 && cmpt.id_selector == COMPONENT_ID_ALL) return;
675 file_log_mask.mask = new_file_mask;
676 if (cmpt.id_selector == COMPONENT_ID_NAME) { // deep copy needed
677 if (file_log_mask.component_id.id_selector == COMPONENT_ID_NAME)
678 Free(file_log_mask.component_id.id_name);
679 file_log_mask.component_id.id_selector = COMPONENT_ID_NAME;
680 file_log_mask.component_id.id_name = mcopystr(cmpt.id_name);
681 } else file_log_mask.component_id = cmpt;
682}
683
684void TTCN_Logger::set_console_mask(component_id_t const& cmpt, const Logging_Bits& new_console_mask)
685{
686 // If ConsoleMask was set with a component-specific value, do not allow
687 // overwriting with a generic value.
688 if (console_log_mask.component_id.id_selector == COMPONENT_ID_COMPREF
689 && cmpt.id_selector == COMPONENT_ID_ALL) return;
690 console_log_mask.mask = new_console_mask;
691 if (cmpt.id_selector == COMPONENT_ID_NAME) { // deep copy needed
692 if (console_log_mask.component_id.id_selector == COMPONENT_ID_NAME)
693 Free(console_log_mask.component_id.id_name);
694 console_log_mask.component_id.id_selector = COMPONENT_ID_NAME;
695 console_log_mask.component_id.id_name = mcopystr(cmpt.id_name);
696 } else console_log_mask.component_id = cmpt;
697}
698
699void TTCN_Logger::set_emergency_logging_mask(component_id_t const& cmpt, const Logging_Bits& new_logging_mask)
700{
701 // If Emergency Logging Mask was set with a component-specific value, do not allow
702 // overwriting with a generic value.
703 if (emergency_log_mask.component_id.id_selector == COMPONENT_ID_COMPREF
704 && cmpt.id_selector == COMPONENT_ID_ALL) return;
705 emergency_log_mask.mask = new_logging_mask;
706 if (cmpt.id_selector == COMPONENT_ID_NAME) { // deep copy needed
707 if (emergency_log_mask.component_id.id_selector == COMPONENT_ID_NAME)
708 Free(emergency_log_mask.component_id.id_name);
709 emergency_log_mask.component_id.id_selector = COMPONENT_ID_NAME;
710 emergency_log_mask.component_id.id_name = mcopystr(cmpt.id_name);
711 } else emergency_log_mask.component_id = cmpt;
712}
713
714void TTCN_Logger::set_emergency_logging_behaviour(emergency_logging_behaviour_t behaviour)
715{
716 emergency_logging_behaviour= behaviour;
717}
718
719TTCN_Logger::emergency_logging_behaviour_t TTCN_Logger::get_emergency_logging_behaviour()
720{
721 return emergency_logging_behaviour;
722}
723
724size_t TTCN_Logger::get_emergency_logging()
725{
726 return emergency_logging;
727}
728
729void TTCN_Logger::set_emergency_logging(size_t size)
730{
731 emergency_logging = size;
732}
733
d44e3c4f 734boolean TTCN_Logger::get_emergency_logging_for_fail_verdict()
735{
736 return emergency_logging_for_fail_verdict;
737}
738
739void TTCN_Logger::set_emergency_logging_for_fail_verdict(boolean b)
740{
741 emergency_logging_for_fail_verdict = b;
742}
743
970ed795
EL
744Logging_Bits const& TTCN_Logger::get_file_mask()
745{
746 return file_log_mask.mask;
747}
748
749Logging_Bits const& TTCN_Logger::get_console_mask()
750{
751 return console_log_mask.mask;
752}
753
754Logging_Bits const& TTCN_Logger::get_emergency_logging_mask()
755{
756 return emergency_log_mask.mask;
757}
758
759void TTCN_Logger::register_plugin(const component_id_t comp, char *identifier, char *filename)
760{
761 get_logger_plugin_manager()->register_plugin(comp, identifier, filename);
762}
763
764char *TTCN_Logger::get_logger_settings_str()
765{
766 static const char *timestamp_format_names[] = {
767 "Time", "DateTime", "Seconds"
768 };
769 static const char *logeventtype_names[] = {
770 "No", "Yes", "Subcategories"
771 };
772 static const char *source_info_format_names[] = {
773 "None", "Single", "Stack"
774 };
775
776 expstring_t filemask_origin =
777 component_string(file_log_mask.component_id);
778 expstring_t consolemask_origin =
779 component_string(console_log_mask.component_id);
780 expstring_t filemask_description = file_log_mask.mask.describe();
781 expstring_t consolemask_description = console_log_mask.mask.describe();
782
783 // Global options, common stuff for all plug-ins.
784 expstring_t new_log_message = mprintf("TTCN Logger v%d.%d options: "
785 "TimeStampFormat:=%s; LogEntityName:=%s; LogEventTypes:=%s; "
786 "SourceInfoFormat:=%s; %s.FileMask:=%s; %s.ConsoleMask:=%s;",
787 TTCN_Logger::major_version, TTCN_Logger::minor_version,
788 timestamp_format_names[timestamp_format],
789 logeventtype_names[log_entity_name],
790 logeventtype_names[log_event_types],
791 source_info_format_names[source_info_format], filemask_origin,
792 filemask_description, consolemask_origin, consolemask_description);
793
794 Free(filemask_origin);
795 Free(consolemask_origin);
796 Free(filemask_description);
797 Free(consolemask_description);
798
799 return new_log_message;
800}
801
802void TTCN_Logger::write_logger_settings(bool /*opening*/)
803{
804 expstring_t new_log_message = get_logger_settings_str();
805
806 // If we get called too early (and become buffered), the logger options
807 // must be updated. By default the initial values are used.
808 get_logger_plugin_manager()->log_log_options(new_log_message,
809 mstrlen(new_log_message));
810
811 Free(new_log_message);
812}
813
814boolean TTCN_Logger::should_log_to_file(TTCN_Logger::Severity sev)
815{
816 if (sev > 0 && sev < TTCN_Logger::NUMBER_OF_LOGSEVERITIES) {
817 return file_log_mask.mask.bits[sev];
818 }
819 return false;
820}
821
822boolean TTCN_Logger::should_log_to_console(TTCN_Logger::Severity sev)
823{
824 // CR_TR00015406: Always log external scripts to the console | MCTR.
825 if (sev == TTCN_Logger::EXECUTOR_EXTCOMMAND) return true;
826 if (sev > 0 && sev < TTCN_Logger::NUMBER_OF_LOGSEVERITIES) {
827 return console_log_mask.mask.bits[sev];
828 }
829 return false;
830}
831
832boolean TTCN_Logger::should_log_to_emergency(TTCN_Logger::Severity sev)
833{
834 if (sev > 0 && sev < TTCN_Logger::NUMBER_OF_LOGSEVERITIES) {
835 return emergency_log_mask.mask.bits[sev];
836 }
837 return false;
838}
839
840void TTCN_Logger::set_timestamp_format(timestamp_format_t new_timestamp_format)
841{
842 timestamp_format = new_timestamp_format;
843}
844
845void TTCN_Logger::set_source_info_format(source_info_format_t new_source_info_format)
846{
847 source_info_format = new_source_info_format;
848}
849
850void TTCN_Logger::set_log_event_types(log_event_types_t new_log_event_types)
851{
852 log_event_types = new_log_event_types;
853}
854
855void TTCN_Logger::set_append_file(boolean new_append_file)
856{
857 get_logger_plugin_manager()->set_append_file(new_append_file);
858}
859
860void TTCN_Logger::set_log_entity_name(boolean new_log_entity_name)
861{
862 log_entity_name = new_log_entity_name;
863}
864
865void TTCN_Logger::open_file()
866{
867 get_logger_plugin_manager()->open_file();
868}
869
870void TTCN_Logger::close_file()
871{
872 get_logger_plugin_manager()->close_file();
873}
874
875void TTCN_Logger::ring_buffer_dump(bool do_close_file)
876{
877 get_logger_plugin_manager()->ring_buffer_dump(do_close_file);
878}
879
880unsigned int TTCN_Logger::get_mask()
881{
882 TTCN_warning("TTCN_Logger::get_mask() is deprecated, please use "
883 "TTCN_Logger::should_log_to_file() or "
884 "TTCN_Logger::should_log_to_console() instead.");
885 return LOG_ALL_IMPORTANT | MATCHING_UNQUALIFIED | DEBUG_UNQUALIFIED;
886}
887
888TTCN_Logger::matching_verbosity_t TTCN_Logger::get_matching_verbosity()
889{
890 return matching_verbosity;
891}
892
893void TTCN_Logger::set_matching_verbosity(TTCN_Logger::matching_verbosity_t v)
894{
895 matching_verbosity = v;
896}
897
898// Called from the generated code and many more places... Stay here. The
899// existence of the file descriptors etc. is the responsibility of the
900// plug-ins.
901boolean TTCN_Logger::log_this_event(TTCN_Logger::Severity event_severity)
902{
903 //ToDO: emergency logging = true
904 if (should_log_to_file(event_severity)) return TRUE;
905 else if (should_log_to_console(event_severity)) return TRUE;
906 else if (should_log_to_emergency(event_severity) && (get_emergency_logging() > 0)) return TRUE;
907 else return FALSE;
908}
909
910void TTCN_Logger::log(TTCN_Logger::Severity msg_severity,
911 const char *fmt_str, ...)
912{
913 va_list p_var;
914 va_start(p_var, fmt_str);
915 log_va_list(msg_severity, fmt_str, p_var);
916 va_end(p_var);
917}
918
919void TTCN_Logger::send_event_as_error()
920{
921 char* error_msg = get_logger_plugin_manager()->get_current_event_str();
922 if (!error_msg)
923 return;
924
925 if (TTCN_Communication::is_mc_connected()) {
926 TTCN_Communication::send_error("%s", error_msg);
927 } else {
928 fprintf(stderr, "%s\n", error_msg);
929 }
930 Free(error_msg);
931}
932
933// Part of the external interface. Don't touch.
934void TTCN_Logger::log_str(TTCN_Logger::Severity msg_severity,
935 const char *str_ptr)
936{
937 if (!log_this_event(msg_severity)) return;
938 if (str_ptr == NULL)
939 str_ptr = "<NULL pointer>";
940 get_logger_plugin_manager()->log_unhandled_event(msg_severity,
941 str_ptr, strlen(str_ptr));
942 logmatch_printed = false;
943}
944
945void TTCN_Logger::log_va_list(TTCN_Logger::Severity msg_severity,
946 const char *fmt_str, va_list p_var)
947{
948 get_logger_plugin_manager()->log_va_list(msg_severity, fmt_str, p_var);
949 logmatch_printed = false;
950}
951
952void TTCN_Logger::begin_event(TTCN_Logger::Severity msg_severity, boolean log2str)
953{
954 get_logger_plugin_manager()->begin_event(msg_severity, log2str);
955}
956
957void TTCN_Logger::end_event()
958{
959 get_logger_plugin_manager()->end_event();
960 // TODO: Find another place for these...
961 logmatch_printed = false;
962}
963
964CHARSTRING TTCN_Logger::end_event_log2str()
965{
966 CHARSTRING ret_val = get_logger_plugin_manager()->end_event_log2str();
967 logmatch_printed = false;
968 return ret_val;
969}
970
971void TTCN_Logger::finish_event()
972{
973 get_logger_plugin_manager()->finish_event();
974}
975
976void TTCN_Logger::log_event(const char *fmt_str, ...)
977{
978 va_list p_var;
979 va_start(p_var, fmt_str);
980 log_event_va_list(fmt_str, p_var);
981 va_end(p_var);
982}
983
984void TTCN_Logger::log_event_str(const char *str_ptr)
985{
986 get_logger_plugin_manager()->log_event_str(str_ptr);
987 logmatch_printed = false;
988}
989
990void TTCN_Logger::log_event_va_list(const char *fmt_str, va_list p_var)
991{
992 get_logger_plugin_manager()->log_event_va_list(fmt_str, p_var);
993 logmatch_printed = false;
994}
995
996void TTCN_Logger::log_event_unbound()
997{
998 switch (data_log_format) {
999 case LF_LEGACY:
1000 log_event_str("<unbound>");
1001 break;
1002 case LF_TTCN:
1003 log_char('-');
1004 break;
1005 default:
1006 log_event_str("<unknown>");
1007 }
1008}
1009
1010void TTCN_Logger::log_event_uninitialized()
1011{
1012 switch (data_log_format) {
1013 case LF_LEGACY:
1014 log_event_str("<uninitialized template>");
1015 break;
1016 case LF_TTCN:
1017 log_char('-');
1018 break;
1019 default:
1020 log_event_str("<unknown>");
1021 }
1022}
1023
1024void TTCN_Logger::log_event_enum(const char* enum_name_str, int enum_value)
1025{
1026 switch (data_log_format) {
1027 case LF_LEGACY:
1028 TTCN_Logger::log_event("%s (%d)", enum_name_str, enum_value);
1029 break;
1030 case LF_TTCN:
1031 log_event_str(enum_name_str);
1032 break;
1033 default:
1034 log_event_str("<unknown>");
1035 }
1036}
1037
1038void TTCN_Logger::log_char(char c)
1039{
1040 get_logger_plugin_manager()->log_char(c);
1041 logmatch_printed = false;
1042}
1043
1044boolean TTCN_Logger::is_printable(unsigned char c)
1045{
1046 if (!isascii(c)) return FALSE;
1047 else if (isprint(c)) return TRUE;
1048 else {
1049 switch (c) {
1050 case '\a':
1051 case '\b':
1052 case '\t':
1053 case '\n':
1054 case '\v':
1055 case '\f':
1056 case '\r':
1057 return TRUE;
1058 default:
1059 return FALSE;
1060 }
1061 }
1062}
1063
1064void TTCN_Logger::log_char_escaped(unsigned char c)
1065{
1066 switch (c) {
1067 case '\n':
1068 log_event_str("\\n");
1069 break;
1070 case '\t':
1071 log_event_str("\\t");
1072 break;
1073 case '\v':
1074 log_event_str("\\v");
1075 break;
1076 case '\b':
1077 log_event_str("\\b");
1078 break;
1079 case '\r':
1080 log_event_str("\\r");
1081 break;
1082 case '\f':
1083 log_event_str("\\f");
1084 break;
1085 case '\a':
1086 log_event_str("\\a");
1087 break;
1088 case '\\':
1089 log_event_str("\\\\");
1090 break;
1091 case '"':
1092 log_event_str("\\\"");
1093 break;
1094 default:
1095 if (isprint(c)) log_char(c);
1096 else log_event("\\%03o", c);
1097 break;
1098 }
1099}
1100
1101void TTCN_Logger::log_char_escaped(unsigned char c, char*& p_buffer) {
1102 switch (c) {
1103 case '\n':
1104 p_buffer = mputstr(p_buffer, "\\n");
1105 break;
1106 case '\t':
1107 p_buffer = mputstr(p_buffer, "\\t");
1108 break;
1109 case '\v':
1110 p_buffer = mputstr(p_buffer, "\\v");
1111 break;
1112 case '\b':
1113 p_buffer = mputstr(p_buffer, "\\b");
1114 break;
1115 case '\r':
1116 p_buffer = mputstr(p_buffer, "\\r");
1117 break;
1118 case '\f':
1119 p_buffer = mputstr(p_buffer, "\\f");
1120 break;
1121 case '\a':
1122 p_buffer = mputstr(p_buffer, "\\a");
1123 break;
1124 case '\\':
1125 p_buffer = mputstr(p_buffer, "\\\\");
1126 break;
1127 case '"':
1128 p_buffer = mputstr(p_buffer, "\\\"");
1129 break;
1130 default:
1131 if (isprint(c)) p_buffer = mputc(p_buffer, c);
1132 else
1133 p_buffer = mputprintf(p_buffer, "\\%03o", c);
1134 break;
1135 }
1136}
1137
1138static const char hex_digits[] = { '0', '1', '2', '3', '4', '5', '6', '7',
1139 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1140
1141void TTCN_Logger::log_hex(unsigned char nibble)
1142{
1143 if (nibble < 16) log_char(hex_digits[nibble]);
1144 else log_event_str("<unknown>");
1145}
1146
1147void TTCN_Logger::log_octet(unsigned char octet)
1148{
1149 log_char(hex_digits[octet >> 4]);
1150 log_char(hex_digits[octet & 0x0F]);
1151}
1152
1153void TTCN_Logger::OS_error()
1154{
1155 if (errno != 0) {
1156 const char *error_string = strerror(errno);
1157 if (error_string != NULL) log_event(" (%s)", error_string);
1158 else log_event(" (Unknown error: errno = %d)", errno);
1159 errno = 0;
1160 }
1161}
1162
1163void TTCN_Logger::log_timer_read(const char *timer_name,
1164 double timeout_val)
1165{
1166 get_logger_plugin_manager()->log_timer_read(timer_name, timeout_val);
1167}
1168
1169void TTCN_Logger::log_timer_start(const char *timer_name, double start_val)
1170{
1171 get_logger_plugin_manager()->log_timer_start(timer_name, start_val);
1172}
1173
1174void TTCN_Logger::log_timer_guard(double start_val)
1175{
1176 get_logger_plugin_manager()->log_timer_guard(start_val);
1177}
1178
1179void TTCN_Logger::log_timer_stop(const char *timer_name, double stop_val)
1180{
1181 get_logger_plugin_manager()->log_timer_stop(timer_name, stop_val);
1182}
1183
1184void TTCN_Logger::log_timer_timeout(const char *timer_name,
1185 double timeout_val)
1186{
1187 get_logger_plugin_manager()->log_timer_timeout(timer_name, timeout_val);
1188}
1189
1190void TTCN_Logger::log_timer_any_timeout()
1191{
1192 get_logger_plugin_manager()->log_timer_any_timeout();
1193}
1194
1195void TTCN_Logger::log_timer_unqualified(const char *message)
1196{
1197 get_logger_plugin_manager()->log_timer_unqualified(message);
1198}
1199
1200void TTCN_Logger::log_testcase_started(const qualified_name& testcase_name)
1201{
1202 get_logger_plugin_manager()->log_testcase_started(testcase_name);
1203}
1204
1205void TTCN_Logger::log_testcase_finished(const qualified_name& testcase_name,
1206 verdicttype verdict,
1207 const char *reason)
1208{
1209 get_logger_plugin_manager()->log_testcase_finished(testcase_name, verdict, reason);
1210}
1211
1212void TTCN_Logger::log_setverdict(verdicttype new_verdict, verdicttype old_verdict,
1213 verdicttype local_verdict, const char *old_reason, const char *new_reason)
1214{
1215 get_logger_plugin_manager()->log_setverdict(new_verdict, old_verdict,
1216 local_verdict, old_reason, new_reason);
1217}
1218
1219void TTCN_Logger::log_getverdict(verdicttype verdict)
1220{
1221 get_logger_plugin_manager()->log_getverdict(verdict);
1222}
1223
1224void TTCN_Logger::log_final_verdict(bool is_ptc, verdicttype ptc_verdict,
1225 verdicttype local_verdict, verdicttype new_verdict,
1226 const char *verdict_reason, int notification, int ptc_compref,
1227 const char *ptc_name)
1228{
1229 get_logger_plugin_manager()->log_final_verdict(is_ptc, ptc_verdict,
1230 local_verdict, new_verdict, verdict_reason, notification, ptc_compref, ptc_name);
1231}
1232
1233void TTCN_Logger::log_controlpart_start_stop(const char *module_name, int finished)
1234{
1235 get_logger_plugin_manager()->log_controlpart_start_stop(module_name, finished);
1236}
1237
1238void TTCN_Logger::log_controlpart_errors(unsigned int error_count)
1239{
1240 get_logger_plugin_manager()->log_controlpart_errors(error_count);
1241}
1242
1243void TTCN_Logger::log_verdict_statistics(size_t none_count, double none_percent,
1244 size_t pass_count, double pass_percent,
1245 size_t inconc_count, double inconc_percent,
1246 size_t fail_count, double fail_percent,
1247 size_t error_count, double error_percent)
1248{
1249 get_logger_plugin_manager()->log_verdict_statistics(none_count, none_percent,
1250 pass_count, pass_percent,
1251 inconc_count, inconc_percent,
1252 fail_count, fail_percent,
1253 error_count, error_percent);
1254}
1255
1256void TTCN_Logger::log_defaultop_activate(const char *name, int id)
1257{
1258 get_logger_plugin_manager()->log_defaultop_activate(name, id);
1259}
1260
1261void TTCN_Logger::log_defaultop_deactivate(const char *name, int id)
1262{
1263 get_logger_plugin_manager()->log_defaultop_deactivate(name, id);
1264}
1265
1266void TTCN_Logger::log_defaultop_exit(const char *name, int id, int x)
1267{
1268 get_logger_plugin_manager()->log_defaultop_exit(name, id, x);
1269}
1270
1271void TTCN_Logger::log_executor_runtime(int reason)
1272{
1273 get_logger_plugin_manager()->log_executor_runtime(reason);
1274}
1275
1276void TTCN_Logger::log_HC_start(const char *host)
1277{
1278 get_logger_plugin_manager()->log_HC_start(host);
1279}
1280
1281void TTCN_Logger::log_fd_limits(int fd_limit, long fd_set_size)
1282{
1283 get_logger_plugin_manager()->log_fd_limits(fd_limit, fd_set_size);
1284}
1285
1286void TTCN_Logger::log_testcase_exec(const char *module, const char *tc)
1287{
1288 get_logger_plugin_manager()->log_testcase_exec(module, tc);
1289}
1290
1291void TTCN_Logger::log_module_init(const char *module, bool finish)
1292{
1293 get_logger_plugin_manager()->log_module_init(module, finish);
1294}
1295
1296void TTCN_Logger::log_mtc_created(long pid)
1297{
1298 get_logger_plugin_manager()->log_mtc_created(pid);
1299}
1300
1301void TTCN_Logger::log_configdata(int reason, const char *str)
1302{
1303 get_logger_plugin_manager()->log_configdata(reason, str);
1304}
1305
1306void TTCN_Logger::log_executor_component(int reason)
1307{
1308 get_logger_plugin_manager()->log_executor_component(reason);
1309}
1310
1311void TTCN_Logger::log_executor_misc(int reason, const char *name,
1312 const char *address, int port)
1313{
1314 get_logger_plugin_manager()->log_executor_misc(reason, name, address, port);
1315}
1316
1317void TTCN_Logger::log_extcommand(extcommand_t action, const char *cmd)
1318{
1319 get_logger_plugin_manager()->log_extcommand(action, cmd);
1320}
1321
1322void TTCN_Logger::log_matching_done(const char *type, int ptc,
1323 const char *return_type, int reason)
1324{
1325 get_logger_plugin_manager()->log_matching_done(reason, type, ptc, return_type);
1326}
1327
1328void TTCN_Logger::log_matching_problem(int reason, int operation, boolean check,
1329 boolean anyport, const char *port_name)
1330{
1331 get_logger_plugin_manager()->log_matching_problem(reason, operation,
1332 check, anyport, port_name);
1333}
1334
1335void TTCN_Logger::log_matching_success(int port_type, const char *port_name,
1336 int compref, const CHARSTRING& info)
1337{
1338 get_logger_plugin_manager()->log_matching_success(port_type, port_name,
1339 compref, info);
1340}
1341
1342void TTCN_Logger::log_matching_failure(int port_type, const char *port_name,
1343 int compref, int reason, const CHARSTRING& info)
1344{
1345 get_logger_plugin_manager()->log_matching_failure(port_type, port_name,
1346 compref, reason, info);
1347}
1348
1349void TTCN_Logger::log_matching_timeout(const char *timer_name)
1350{
1351 get_logger_plugin_manager()->log_matching_timeout(timer_name);
1352}
1353
1354void TTCN_Logger::log_portconnmap(int operation, int src_compref, const char *src_port,
1355 int dst_compref, const char *dst_port)
1356{
1357 get_logger_plugin_manager()->log_portconnmap(operation, src_compref, src_port,
1358 dst_compref, dst_port);
1359}
1360
1361void TTCN_Logger::log_par_ptc(int reason, const char *module, const char *name,
1362 int compref, const char *compname, const char *tc_loc, int alive_pid, int status)
1363{
1364 get_logger_plugin_manager()->log_par_ptc(reason, module, name, compref,
1365 compname, tc_loc, alive_pid, status);
1366}
1367
1368void TTCN_Logger::log_port_queue(int operation, const char *port_name, int compref,
1369 int id, const CHARSTRING& address, const CHARSTRING& param)
1370{
1371 get_logger_plugin_manager()->log_port_queue(operation, port_name, compref,
1372 id, address, param);
1373}
1374
1375void TTCN_Logger::log_port_state(int operation, const char *port_name)
1376{
1377 get_logger_plugin_manager()->log_port_state(operation, port_name);
1378}
1379
1380void TTCN_Logger::log_procport_send(const char *portname, int operation, int compref,
1381 const CHARSTRING& system, const CHARSTRING& param)
1382{
1383 get_logger_plugin_manager()->log_procport_send(portname, operation, compref,
1384 system, param);
1385}
1386
1387void TTCN_Logger::log_procport_recv(const char *portname, int operation,
1388 int compref, boolean check, const CHARSTRING& param, int id)
1389{
1390 get_logger_plugin_manager()->log_procport_recv(portname, operation, compref,
1391 check, param, id);
1392}
1393
1394void TTCN_Logger::log_msgport_send(const char *portname, int compref,
1395 const CHARSTRING& param)
1396{
1397 get_logger_plugin_manager()->log_msgport_send(portname, compref, param);
1398}
1399
1400void TTCN_Logger::log_msgport_recv(const char *portname, int operation, int compref,
1401 const CHARSTRING& system, const CHARSTRING& param, int id)
1402{
1403 get_logger_plugin_manager()->log_msgport_recv(portname, operation, compref,
1404 system, param, id);
1405}
1406
1407void TTCN_Logger::log_dualport_map(boolean incoming, const char *target_type,
1408 const CHARSTRING& value, int id)
1409{
1410 get_logger_plugin_manager()->log_dualport_map(incoming, target_type, value, id);
1411}
1412
1413void TTCN_Logger::log_dualport_discard(boolean incoming, const char *target_type,
1414 const char *port_name, boolean unhandled)
1415{
1416 get_logger_plugin_manager()->log_dualport_discard(incoming, target_type, port_name,
1417 unhandled);
1418}
1419
1420void TTCN_Logger::log_port_misc(int reason, const char *port_name,
1421 int remote_component, const char *remote_port,
1422 const char *ip_address, int tcp_port, int new_size)
1423{
1424 get_logger_plugin_manager()->log_port_misc(reason, port_name,
1425 remote_component, remote_port, ip_address, tcp_port, new_size);
1426}
1427
1428void TTCN_Logger::log_random(int action, double v, unsigned long u)
1429{
1430 get_logger_plugin_manager()->log_random(action, v, u);
1431}
1432
1433void TTCN_Logger::clear_parameters() {
1434 get_logger_plugin_manager()->clear_param_list();
1435 get_logger_plugin_manager()->clear_plugin_list();
1436}
1437
1438// The one instance (only for backward compatibility).
1439TTCN_Logger TTCN_logger;
1440
1441// Location related stuff.
1442TTCN_Location *TTCN_Location::innermost_location = NULL,
1443 *TTCN_Location::outermost_location = NULL;
1444
1445TTCN_Location::TTCN_Location(const char *par_file_name,
1446 unsigned int par_line_number, entity_type_t par_entity_type,
1447 const char *par_entity_name)
1448: file_name(par_file_name), line_number(par_line_number),
1449 entity_type(par_entity_type), entity_name(par_entity_name),
1450 inner_location(NULL), outer_location(innermost_location)
1451{
1452 if (par_file_name == NULL) file_name = "<unknown file>";
1453 if (par_entity_type == LOCATION_UNKNOWN) entity_name = NULL;
1454 else if (par_entity_name == NULL) entity_name = "<unknown>";
1455 if (outer_location != NULL) outer_location->inner_location = this;
1456 else outermost_location = this;
1457 innermost_location = this;
1458}
1459
1460void TTCN_Location::update_lineno(unsigned int new_lineno)
1461{
1462 line_number = new_lineno;
1463}
1464
1465TTCN_Location::~TTCN_Location()
1466{
1467 if (inner_location == NULL) innermost_location = outer_location;
1468 else inner_location->outer_location = outer_location;
1469 if (outer_location == NULL) outermost_location = inner_location;
1470 else outer_location->inner_location = inner_location;
1471}
1472
1473char *TTCN_Location::print_location(boolean print_outers,
1474 boolean print_innermost, boolean print_entity_name)
1475{
1476 char *ret_val = NULL;
1477 if (innermost_location != NULL) {
1478 if (print_outers) {
1479 for (TTCN_Location *iter = outermost_location;
1480 iter != NULL && iter != innermost_location;
1481 iter = iter->inner_location)
1482 ret_val = iter->append_contents(ret_val, print_entity_name);
1483 }
1484 if (print_innermost)
1485 ret_val = innermost_location->append_contents(ret_val,
1486 print_entity_name);
1487 }
1488 return ret_val;
1489}
1490
1491void TTCN_Location::strip_entity_name(char*& par_str)
1492{
1493 if (!par_str) return;
1494 char *new_str = NULL;
1495 bool in_paren = false;
1496 for (char *str_ptr = par_str; *str_ptr != '\0' ; str_ptr++) {
1497 switch (*str_ptr) {
1498 case '(':
1499 in_paren = true;
1500 break;
1501 case ')':
1502 in_paren = false;
1503 break;
1504 default:
1505 if (!in_paren) new_str = mputc(new_str, *str_ptr);
1506 break;
1507 }
1508 }
1509 Free(par_str);
1510 par_str = new_str;
1511}
1512
f08ff9ca
BB
1513unsigned int TTCN_Location::get_line_number()
1514{
1515 if (innermost_location != NULL) {
1516 return innermost_location->line_number;
1517 }
1518 return 0;
1519}
1520
970ed795
EL
1521char *TTCN_Location::append_contents(char *par_str,
1522 boolean print_entity_name) const
1523{
1524 if (par_str != NULL) par_str = mputstr(par_str, "->");
1525 par_str = mputprintf(par_str, "%s:%u", file_name, line_number);
1526 if (print_entity_name) {
1527 switch (entity_type) {
1528 case LOCATION_CONTROLPART:
1529 par_str = mputprintf(par_str, "(controlpart:%s)", entity_name);
1530 break;
1531 case LOCATION_TESTCASE:
1532 par_str = mputprintf(par_str, "(testcase:%s)", entity_name);
1533 break;
1534 case LOCATION_ALTSTEP:
1535 par_str = mputprintf(par_str, "(altstep:%s)", entity_name);
1536 break;
1537 case LOCATION_FUNCTION:
1538 par_str = mputprintf(par_str, "(function:%s)", entity_name);
1539 break;
1540 case LOCATION_EXTERNALFUNCTION:
1541 par_str = mputprintf(par_str, "(externalfunction:%s)", entity_name);
1542 break;
1543 case LOCATION_TEMPLATE:
1544 par_str = mputprintf(par_str, "(template:%s)", entity_name);
1545 break;
1546 default:
1547 break;
1548 }
1549 }
1550 return par_str;
1551}
1552
1553TTCN_Location_Statistics::TTCN_Location_Statistics(const char *par_file_name,
1554 unsigned int par_line_number, entity_type_t par_entity_type,
1555 const char *par_entity_name): TTCN_Location(par_file_name, par_line_number,
1556 par_entity_type, par_entity_name)
1557{
1558 TCov::hit(file_name, line_number, entity_name);
1559}
1560
1561void TTCN_Location_Statistics::update_lineno(unsigned int new_lineno)
1562{
1563 TTCN_Location::update_lineno(new_lineno);
1564 TCov::hit(file_name, line_number);
1565}
1566
1567void TTCN_Location_Statistics::init_file_lines(const char *file_name, const int line_nos[], size_t line_nos_len)
1568{
1569 TCov::init_file_lines(file_name, line_nos, line_nos_len);
1570}
1571
1572void TTCN_Location_Statistics::init_file_functions(const char *file_name, const char *function_names[], size_t function_names_len)
1573{
1574 TCov::init_file_functions(file_name, function_names, function_names_len);
1575}
1576
1577TTCN_Location_Statistics::~TTCN_Location_Statistics() { }
1578
1579expstring_t component_string(const component_id_t& comp_id)
1580{
1581 expstring_t retval;
1582 switch( comp_id.id_selector ) {
1583 case COMPONENT_ID_NAME:
1584 retval = mcopystr(comp_id.id_name);
1585 break;
1586 case COMPONENT_ID_COMPREF:
1587 retval = mprintf("%d", comp_id.id_compref);
1588 break;
1589 case COMPONENT_ID_ALL:
1590 retval = mcopystr("*");
1591 break;
1592 case COMPONENT_ID_SYSTEM:
1593 retval = mcopystr("<System>");
1594 break;
1595 default: // Can't happen.
1596 retval = mcopystr("Unknown component type !");
1597 break;
1598 }
1599 return retval;
1600}
This page took 0.082362 seconds and 5 git commands to generate.