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 "jerryscript-ext/handler.h" |
17 | #include "jerryscript-port.h" |
18 | #include "jerryscript-debugger.h" |
19 | |
20 | /** |
21 | * Provide a 'print' implementation for scripts. |
22 | * |
23 | * The routine converts all of its arguments to strings and outputs them |
24 | * char-by-char using jerry_port_print_char. |
25 | * |
26 | * The NUL character is output as "\u0000", other characters are output |
27 | * bytewise. |
28 | * |
29 | * Note: |
30 | * This implementation does not use standard C `printf` to print its |
31 | * output. This allows more flexibility but also extends the core |
32 | * JerryScript engine port API. Applications that want to use |
33 | * `jerryx_handler_print` must ensure that their port implementation also |
34 | * provides `jerry_port_print_char`. |
35 | * |
36 | * @return undefined - if all arguments could be converted to strings, |
37 | * error - otherwise. |
38 | */ |
39 | jerry_value_t |
40 | jerryx_handler_print (const jerry_value_t func_obj_val, /**< function object */ |
41 | const jerry_value_t this_p, /**< this arg */ |
42 | const jerry_value_t args_p[], /**< function arguments */ |
43 | const jerry_length_t args_cnt) /**< number of function arguments */ |
44 | { |
45 | (void) func_obj_val; /* unused */ |
46 | (void) this_p; /* unused */ |
47 | |
48 | const char * const null_str = "\\u0000" ; |
49 | |
50 | jerry_value_t ret_val = jerry_create_undefined (); |
51 | |
52 | for (jerry_length_t arg_index = 0; arg_index < args_cnt; arg_index++) |
53 | { |
54 | jerry_value_t str_val; |
55 | |
56 | if (jerry_value_is_symbol (args_p[arg_index])) |
57 | { |
58 | str_val = jerry_get_symbol_descriptive_string (args_p[arg_index]); |
59 | } |
60 | else |
61 | { |
62 | str_val = jerry_value_to_string (args_p[arg_index]); |
63 | } |
64 | |
65 | if (jerry_value_is_error (str_val)) |
66 | { |
67 | /* There is no need to free the undefined value. */ |
68 | ret_val = str_val; |
69 | break; |
70 | } |
71 | |
72 | jerry_length_t length = jerry_get_utf8_string_length (str_val); |
73 | jerry_length_t substr_pos = 0; |
74 | jerry_char_t substr_buf[256]; |
75 | |
76 | do |
77 | { |
78 | jerry_size_t substr_size = jerry_substring_to_utf8_char_buffer (str_val, |
79 | substr_pos, |
80 | length, |
81 | substr_buf, |
82 | 256 - 1); |
83 | |
84 | jerry_char_t *buf_end_p = substr_buf + substr_size; |
85 | |
86 | /* Update start position by the number of utf-8 characters. */ |
87 | for (jerry_char_t *buf_p = substr_buf; buf_p < buf_end_p; buf_p++) |
88 | { |
89 | /* Skip intermediate utf-8 octets. */ |
90 | if ((*buf_p & 0xc0) != 0x80) |
91 | { |
92 | substr_pos++; |
93 | } |
94 | } |
95 | |
96 | if (substr_pos == length) |
97 | { |
98 | *buf_end_p++ = (arg_index < args_cnt - 1) ? ' ' : '\n'; |
99 | } |
100 | |
101 | for (jerry_char_t *buf_p = substr_buf; buf_p < buf_end_p; buf_p++) |
102 | { |
103 | char chr = (char) *buf_p; |
104 | |
105 | if (chr != '\0') |
106 | { |
107 | jerry_port_print_char (chr); |
108 | continue; |
109 | } |
110 | |
111 | for (jerry_size_t null_index = 0; null_str[null_index] != '\0'; null_index++) |
112 | { |
113 | jerry_port_print_char (null_str[null_index]); |
114 | } |
115 | } |
116 | } |
117 | while (substr_pos < length); |
118 | |
119 | jerry_release_value (str_val); |
120 | } |
121 | |
122 | if (args_cnt == 0 || jerry_value_is_error (ret_val)) |
123 | { |
124 | jerry_port_print_char ('\n'); |
125 | } |
126 | |
127 | return ret_val; |
128 | } /* jerryx_handler_print */ |
129 | |