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#if !defined (_WIN32) && !defined(JERRY_FOR_IAR_CONFIG)
17425bb815Sopenharmony_ci#include <libgen.h>
18425bb815Sopenharmony_ci#endif /* !defined (_WIN32) */
19425bb815Sopenharmony_ci#include <limits.h>
20425bb815Sopenharmony_ci#include <stdarg.h>
21425bb815Sopenharmony_ci#include <stdlib.h>
22425bb815Sopenharmony_ci#include <string.h>
23425bb815Sopenharmony_ci
24425bb815Sopenharmony_ci#include "jerryscript-port.h"
25425bb815Sopenharmony_ci#include "jerryscript-port-default.h"
26425bb815Sopenharmony_ci
27425bb815Sopenharmony_ci/**
28425bb815Sopenharmony_ci * Determines the size of the given file.
29425bb815Sopenharmony_ci * @return size of the file
30425bb815Sopenharmony_ci */
31425bb815Sopenharmony_cistatic size_t
32425bb815Sopenharmony_cijerry_port_get_file_size (FILE *file_p) /**< opened file */
33425bb815Sopenharmony_ci{
34425bb815Sopenharmony_ci  fseek (file_p, 0, SEEK_END);
35425bb815Sopenharmony_ci  long size = ftell (file_p);
36425bb815Sopenharmony_ci  fseek (file_p, 0, SEEK_SET);
37425bb815Sopenharmony_ci
38425bb815Sopenharmony_ci  return (size_t) size;
39425bb815Sopenharmony_ci} /* jerry_port_get_file_size */
40425bb815Sopenharmony_ci
41425bb815Sopenharmony_ci/**
42425bb815Sopenharmony_ci * Opens file with the given path and reads its source.
43425bb815Sopenharmony_ci * @return the source of the file
44425bb815Sopenharmony_ci */
45425bb815Sopenharmony_ciuint8_t *
46425bb815Sopenharmony_cijerry_port_read_source (const char *file_name_p, /**< file name */
47425bb815Sopenharmony_ci                        size_t *out_size_p) /**< [out] read bytes */
48425bb815Sopenharmony_ci{
49425bb815Sopenharmony_ci  FILE *file_p = fopen (file_name_p, "rb");
50425bb815Sopenharmony_ci
51425bb815Sopenharmony_ci  if (file_p == NULL)
52425bb815Sopenharmony_ci  {
53425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to open file: %s\n", file_name_p);
54425bb815Sopenharmony_ci    return NULL;
55425bb815Sopenharmony_ci  }
56425bb815Sopenharmony_ci
57425bb815Sopenharmony_ci  size_t file_size = jerry_port_get_file_size (file_p);
58425bb815Sopenharmony_ci  uint8_t *buffer_p = (uint8_t *) malloc (file_size);
59425bb815Sopenharmony_ci
60425bb815Sopenharmony_ci  if (buffer_p == NULL)
61425bb815Sopenharmony_ci  {
62425bb815Sopenharmony_ci    fclose (file_p);
63425bb815Sopenharmony_ci
64425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to allocate memory for module");
65425bb815Sopenharmony_ci    return NULL;
66425bb815Sopenharmony_ci  }
67425bb815Sopenharmony_ci
68425bb815Sopenharmony_ci  size_t bytes_read = fread (buffer_p, 1u, file_size, file_p);
69425bb815Sopenharmony_ci
70425bb815Sopenharmony_ci  if (!bytes_read)
71425bb815Sopenharmony_ci  {
72425bb815Sopenharmony_ci    fclose (file_p);
73425bb815Sopenharmony_ci    free (buffer_p);
74425bb815Sopenharmony_ci
75425bb815Sopenharmony_ci    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name_p);
76425bb815Sopenharmony_ci    return NULL;
77425bb815Sopenharmony_ci  }
78425bb815Sopenharmony_ci
79425bb815Sopenharmony_ci  fclose (file_p);
80425bb815Sopenharmony_ci  *out_size_p = bytes_read;
81425bb815Sopenharmony_ci
82425bb815Sopenharmony_ci  return buffer_p;
83425bb815Sopenharmony_ci} /* jerry_port_read_source */
84425bb815Sopenharmony_ci
85425bb815Sopenharmony_ci/**
86425bb815Sopenharmony_ci * Release the previously opened file's content.
87425bb815Sopenharmony_ci */
88425bb815Sopenharmony_civoid
89425bb815Sopenharmony_cijerry_port_release_source (uint8_t *buffer_p) /**< buffer to free */
90425bb815Sopenharmony_ci{
91425bb815Sopenharmony_ci  free (buffer_p);
92425bb815Sopenharmony_ci} /* jerry_port_release_source */
93425bb815Sopenharmony_ci
94425bb815Sopenharmony_ci/**
95425bb815Sopenharmony_ci * Normalize a file path
96425bb815Sopenharmony_ci *
97425bb815Sopenharmony_ci * @return length of the path written to the output buffer
98425bb815Sopenharmony_ci */
99425bb815Sopenharmony_cisize_t
100425bb815Sopenharmony_cijerry_port_normalize_path (const char *in_path_p,   /**< input file path */
101425bb815Sopenharmony_ci                           char *out_buf_p,         /**< output buffer */
102425bb815Sopenharmony_ci                           size_t out_buf_size,     /**< size of output buffer */
103425bb815Sopenharmony_ci                           char *base_file_p)       /**< base file path */
104425bb815Sopenharmony_ci{
105425bb815Sopenharmony_ci  size_t ret = 0;
106425bb815Sopenharmony_ci
107425bb815Sopenharmony_ci#if defined (_WIN32)
108425bb815Sopenharmony_ci  char drive[_MAX_DRIVE];
109425bb815Sopenharmony_ci  char *dir_p = (char *) malloc (_MAX_DIR);
110425bb815Sopenharmony_ci
111425bb815Sopenharmony_ci  char *path_p = (char *) malloc (_MAX_PATH * 2);
112425bb815Sopenharmony_ci  *path_p = '\0';
113425bb815Sopenharmony_ci
114425bb815Sopenharmony_ci  if (base_file_p != NULL)
115425bb815Sopenharmony_ci  {
116425bb815Sopenharmony_ci    _splitpath_s (base_file_p,
117425bb815Sopenharmony_ci                  drive,
118425bb815Sopenharmony_ci                  _MAX_DRIVE,
119425bb815Sopenharmony_ci                  dir_p,
120425bb815Sopenharmony_ci                  _MAX_DIR,
121425bb815Sopenharmony_ci                  NULL,
122425bb815Sopenharmony_ci                  0,
123425bb815Sopenharmony_ci                  NULL,
124425bb815Sopenharmony_ci                  0);
125425bb815Sopenharmony_ci    strncat (path_p, drive, _MAX_DRIVE);
126425bb815Sopenharmony_ci    strncat (path_p, dir_p, _MAX_DIR);
127425bb815Sopenharmony_ci  }
128425bb815Sopenharmony_ci
129425bb815Sopenharmony_ci  strncat (path_p, in_path_p, _MAX_PATH);
130425bb815Sopenharmony_ci
131425bb815Sopenharmony_ci  char *norm_p = _fullpath (out_buf_p, path_p, out_buf_size);
132425bb815Sopenharmony_ci
133425bb815Sopenharmony_ci  free (path_p);
134425bb815Sopenharmony_ci  free (dir_p);
135425bb815Sopenharmony_ci
136425bb815Sopenharmony_ci  if (norm_p != NULL)
137425bb815Sopenharmony_ci  {
138425bb815Sopenharmony_ci    ret = strnlen (norm_p, out_buf_size);
139425bb815Sopenharmony_ci  }
140425bb815Sopenharmony_ci#elif defined (__unix__) || defined (__APPLE__)
141425bb815Sopenharmony_ci#define MAX_JERRY_PATH_SIZE 256
142425bb815Sopenharmony_ci  char *buffer_p = (char *) malloc (PATH_MAX);
143425bb815Sopenharmony_ci  char *path_p = (char *) malloc (PATH_MAX);
144425bb815Sopenharmony_ci
145425bb815Sopenharmony_ci  char *base_p = dirname (base_file_p);
146425bb815Sopenharmony_ci  strncpy (path_p, base_p, MAX_JERRY_PATH_SIZE);
147425bb815Sopenharmony_ci  strncat (path_p, "/", 1);
148425bb815Sopenharmony_ci  strncat (path_p, in_path_p, MAX_JERRY_PATH_SIZE);
149425bb815Sopenharmony_ci
150425bb815Sopenharmony_ci  char *norm_p = realpath (path_p, buffer_p);
151425bb815Sopenharmony_ci  free (path_p);
152425bb815Sopenharmony_ci
153425bb815Sopenharmony_ci  if (norm_p != NULL)
154425bb815Sopenharmony_ci  {
155425bb815Sopenharmony_ci    const size_t len = strnlen (norm_p, out_buf_size);
156425bb815Sopenharmony_ci    if (len < out_buf_size)
157425bb815Sopenharmony_ci    {
158425bb815Sopenharmony_ci      strncpy (out_buf_p, norm_p, out_buf_size);
159425bb815Sopenharmony_ci      ret = len;
160425bb815Sopenharmony_ci    }
161425bb815Sopenharmony_ci  }
162425bb815Sopenharmony_ci
163425bb815Sopenharmony_ci  free (buffer_p);
164425bb815Sopenharmony_ci#undef MAX_JERRY_PATH_SIZE
165425bb815Sopenharmony_ci#else
166425bb815Sopenharmony_ci  (void) base_file_p;
167425bb815Sopenharmony_ci
168425bb815Sopenharmony_ci  /* Do nothing, just copy the input. */
169425bb815Sopenharmony_ci  const size_t len = strnlen (in_path_p, out_buf_size);
170425bb815Sopenharmony_ci  if (len < out_buf_size)
171425bb815Sopenharmony_ci  {
172425bb815Sopenharmony_ci    strncpy (out_buf_p, in_path_p, out_buf_size);
173425bb815Sopenharmony_ci    ret = len;
174425bb815Sopenharmony_ci  }
175425bb815Sopenharmony_ci#endif
176425bb815Sopenharmony_ci
177425bb815Sopenharmony_ci  return ret;
178425bb815Sopenharmony_ci} /* jerry_port_normalize_path */
179425bb815Sopenharmony_ci
180425bb815Sopenharmony_ci/**
181425bb815Sopenharmony_ci * Get the module object of a native module.
182425bb815Sopenharmony_ci *
183425bb815Sopenharmony_ci * @return Undefined, if 'name' is not a native module
184425bb815Sopenharmony_ci *         jerry_value_t containing the module object, otherwise
185425bb815Sopenharmony_ci */
186425bb815Sopenharmony_cijerry_value_t
187425bb815Sopenharmony_cijerry_port_get_native_module (jerry_value_t name) /**< module specifier */
188425bb815Sopenharmony_ci{
189425bb815Sopenharmony_ci  (void) name;
190425bb815Sopenharmony_ci  return jerry_create_undefined ();
191425bb815Sopenharmony_ci} /* jerry_port_get_native_module */
192