1/* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <stdarg.h>
17#include <stdlib.h>
18#include <string.h>
19
20#include "jerryscript-port.h"
21#include "jerryscript-port-default.h"
22#include "jerryscript-debugger.h"
23
24#ifndef DISABLE_EXTRA_API
25
26/**
27 * Actual log level
28 */
29static jerry_log_level_t jerry_port_default_log_level = JERRY_LOG_LEVEL_ERROR;
30
31#define JERRY_PORT_DEFAULT_LOG_LEVEL jerry_port_default_log_level
32
33/**
34 * Get the log level
35 *
36 * @return current log level
37 *
38 * Note:
39 *      This function is only available if the port implementation library is
40 *      compiled without the DISABLE_EXTRA_API macro.
41 */
42jerry_log_level_t
43jerry_port_default_get_log_level (void)
44{
45  return jerry_port_default_log_level;
46} /* jerry_port_default_get_log_level */
47
48/**
49 * Set the log level
50 *
51 * Note:
52 *      This function is only available if the port implementation library is
53 *      compiled without the DISABLE_EXTRA_API macro.
54 */
55void
56jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */
57{
58  jerry_port_default_log_level = level;
59} /* jerry_port_default_set_log_level */
60
61#else /* DISABLE_EXTRA_API */
62#define JERRY_PORT_DEFAULT_LOG_LEVEL JERRY_LOG_LEVEL_ERROR
63#endif /* !DISABLE_EXTRA_API */
64
65/**
66 * Default implementation of jerry_port_log. Prints log message to the standard
67 * error with 'vfprintf' if message log level is less than or equal to the
68 * current log level.
69 *
70 * If debugger support is enabled, printing happens first to an in-memory buffer,
71 * which is then sent both to the standard error and to the debugger client.
72 *
73 * Note:
74 *      Changing the log level from JERRY_LOG_LEVEL_ERROR is only possible if
75 *      the port implementation library is compiled without the
76 *      DISABLE_EXTRA_API macro.
77 */
78void
79jerry_port_log (jerry_log_level_t level, /**< message log level */
80                const char *format, /**< format string */
81                ...)  /**< parameters */
82{
83  if (level <= JERRY_PORT_DEFAULT_LOG_LEVEL)
84  {
85    va_list args;
86    va_start (args, format);
87#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
88    if (jerry_debugger_is_connected())
89    {
90      int length = vsnprintf (NULL, 0, format, args);
91      va_end (args);
92      va_start (args, format);
93
94      JERRY_VLA (char, buffer, length + 1);
95      vsnprintf (buffer, (size_t) length + 1, format, args);
96
97      fprintf (stderr, "[JERRYSCRIPT]%s", buffer);
98      jerry_debugger_send_log (level, (jerry_char_t *) buffer, (jerry_size_t) length);
99    }
100    else
101    {
102      vfprintf (stderr, format, args);
103    }
104#else /* If jerry-debugger isn't defined, libc is turned on */
105    vfprintf (stderr, format, args);
106#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
107    va_end (args);
108  }
109} /* jerry_port_log */
110
111#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
112
113#define DEBUG_BUFFER_SIZE (256)
114static char debug_buffer[DEBUG_BUFFER_SIZE];
115static int debug_buffer_index = 0;
116
117#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
118
119/**
120 * Default implementation of jerry_port_print_char. Uses 'putchar' to
121 * print a single character to standard output.
122 */
123void
124jerry_port_print_char (char c) /**< the character to print */
125{
126  putchar (c);
127
128#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
129  debug_buffer[debug_buffer_index++] = c;
130
131  if ((debug_buffer_index == DEBUG_BUFFER_SIZE) || (c == '\n'))
132  {
133    jerry_debugger_send_output ((jerry_char_t *) debug_buffer, (jerry_size_t) debug_buffer_index);
134    debug_buffer_index = 0;
135  }
136#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
137} /* jerry_port_print_char */
138