1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "jerryscript-ext/handler.h" 17425bb815Sopenharmony_ci#include "jerryscript-port.h" 18425bb815Sopenharmony_ci#include "jerryscript-debugger.h" 19425bb815Sopenharmony_ci 20425bb815Sopenharmony_ci/** 21425bb815Sopenharmony_ci * Provide a 'print' implementation for scripts. 22425bb815Sopenharmony_ci * 23425bb815Sopenharmony_ci * The routine converts all of its arguments to strings and outputs them 24425bb815Sopenharmony_ci * char-by-char using jerry_port_print_char. 25425bb815Sopenharmony_ci * 26425bb815Sopenharmony_ci * The NUL character is output as "\u0000", other characters are output 27425bb815Sopenharmony_ci * bytewise. 28425bb815Sopenharmony_ci * 29425bb815Sopenharmony_ci * Note: 30425bb815Sopenharmony_ci * This implementation does not use standard C `printf` to print its 31425bb815Sopenharmony_ci * output. This allows more flexibility but also extends the core 32425bb815Sopenharmony_ci * JerryScript engine port API. Applications that want to use 33425bb815Sopenharmony_ci * `jerryx_handler_print` must ensure that their port implementation also 34425bb815Sopenharmony_ci * provides `jerry_port_print_char`. 35425bb815Sopenharmony_ci * 36425bb815Sopenharmony_ci * @return undefined - if all arguments could be converted to strings, 37425bb815Sopenharmony_ci * error - otherwise. 38425bb815Sopenharmony_ci */ 39425bb815Sopenharmony_cijerry_value_t 40425bb815Sopenharmony_cijerryx_handler_print (const jerry_value_t func_obj_val, /**< function object */ 41425bb815Sopenharmony_ci const jerry_value_t this_p, /**< this arg */ 42425bb815Sopenharmony_ci const jerry_value_t args_p[], /**< function arguments */ 43425bb815Sopenharmony_ci const jerry_length_t args_cnt) /**< number of function arguments */ 44425bb815Sopenharmony_ci{ 45425bb815Sopenharmony_ci (void) func_obj_val; /* unused */ 46425bb815Sopenharmony_ci (void) this_p; /* unused */ 47425bb815Sopenharmony_ci 48425bb815Sopenharmony_ci const char * const null_str = "\\u0000"; 49425bb815Sopenharmony_ci 50425bb815Sopenharmony_ci jerry_value_t ret_val = jerry_create_undefined (); 51425bb815Sopenharmony_ci 52425bb815Sopenharmony_ci for (jerry_length_t arg_index = 0; arg_index < args_cnt; arg_index++) 53425bb815Sopenharmony_ci { 54425bb815Sopenharmony_ci jerry_value_t str_val; 55425bb815Sopenharmony_ci 56425bb815Sopenharmony_ci if (jerry_value_is_symbol (args_p[arg_index])) 57425bb815Sopenharmony_ci { 58425bb815Sopenharmony_ci str_val = jerry_get_symbol_descriptive_string (args_p[arg_index]); 59425bb815Sopenharmony_ci } 60425bb815Sopenharmony_ci else 61425bb815Sopenharmony_ci { 62425bb815Sopenharmony_ci str_val = jerry_value_to_string (args_p[arg_index]); 63425bb815Sopenharmony_ci } 64425bb815Sopenharmony_ci 65425bb815Sopenharmony_ci if (jerry_value_is_error (str_val)) 66425bb815Sopenharmony_ci { 67425bb815Sopenharmony_ci /* There is no need to free the undefined value. */ 68425bb815Sopenharmony_ci ret_val = str_val; 69425bb815Sopenharmony_ci break; 70425bb815Sopenharmony_ci } 71425bb815Sopenharmony_ci 72425bb815Sopenharmony_ci jerry_length_t length = jerry_get_utf8_string_length (str_val); 73425bb815Sopenharmony_ci jerry_length_t substr_pos = 0; 74425bb815Sopenharmony_ci jerry_char_t substr_buf[256]; 75425bb815Sopenharmony_ci 76425bb815Sopenharmony_ci do 77425bb815Sopenharmony_ci { 78425bb815Sopenharmony_ci jerry_size_t substr_size = jerry_substring_to_utf8_char_buffer (str_val, 79425bb815Sopenharmony_ci substr_pos, 80425bb815Sopenharmony_ci length, 81425bb815Sopenharmony_ci substr_buf, 82425bb815Sopenharmony_ci 256 - 1); 83425bb815Sopenharmony_ci 84425bb815Sopenharmony_ci jerry_char_t *buf_end_p = substr_buf + substr_size; 85425bb815Sopenharmony_ci 86425bb815Sopenharmony_ci /* Update start position by the number of utf-8 characters. */ 87425bb815Sopenharmony_ci for (jerry_char_t *buf_p = substr_buf; buf_p < buf_end_p; buf_p++) 88425bb815Sopenharmony_ci { 89425bb815Sopenharmony_ci /* Skip intermediate utf-8 octets. */ 90425bb815Sopenharmony_ci if ((*buf_p & 0xc0) != 0x80) 91425bb815Sopenharmony_ci { 92425bb815Sopenharmony_ci substr_pos++; 93425bb815Sopenharmony_ci } 94425bb815Sopenharmony_ci } 95425bb815Sopenharmony_ci 96425bb815Sopenharmony_ci if (substr_pos == length) 97425bb815Sopenharmony_ci { 98425bb815Sopenharmony_ci *buf_end_p++ = (arg_index < args_cnt - 1) ? ' ' : '\n'; 99425bb815Sopenharmony_ci } 100425bb815Sopenharmony_ci 101425bb815Sopenharmony_ci for (jerry_char_t *buf_p = substr_buf; buf_p < buf_end_p; buf_p++) 102425bb815Sopenharmony_ci { 103425bb815Sopenharmony_ci char chr = (char) *buf_p; 104425bb815Sopenharmony_ci 105425bb815Sopenharmony_ci if (chr != '\0') 106425bb815Sopenharmony_ci { 107425bb815Sopenharmony_ci jerry_port_print_char (chr); 108425bb815Sopenharmony_ci continue; 109425bb815Sopenharmony_ci } 110425bb815Sopenharmony_ci 111425bb815Sopenharmony_ci for (jerry_size_t null_index = 0; null_str[null_index] != '\0'; null_index++) 112425bb815Sopenharmony_ci { 113425bb815Sopenharmony_ci jerry_port_print_char (null_str[null_index]); 114425bb815Sopenharmony_ci } 115425bb815Sopenharmony_ci } 116425bb815Sopenharmony_ci } 117425bb815Sopenharmony_ci while (substr_pos < length); 118425bb815Sopenharmony_ci 119425bb815Sopenharmony_ci jerry_release_value (str_val); 120425bb815Sopenharmony_ci } 121425bb815Sopenharmony_ci 122425bb815Sopenharmony_ci if (args_cnt == 0 || jerry_value_is_error (ret_val)) 123425bb815Sopenharmony_ci { 124425bb815Sopenharmony_ci jerry_port_print_char ('\n'); 125425bb815Sopenharmony_ci } 126425bb815Sopenharmony_ci 127425bb815Sopenharmony_ci return ret_val; 128425bb815Sopenharmony_ci} /* jerryx_handler_print */ 129