forked from bellard/quickjs
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathquickjs-find-module.c
More file actions
147 lines (120 loc) · 3.52 KB
/
quickjs-find-module.c
File metadata and controls
147 lines (120 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "quickjs-config.h"
#include "quickjs.h"
#include "cutils.h"
#include "quickjs-libc.h"
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <limits.h>
#ifndef CONFIG_SHEXT
#ifdef _WIN32
#define CONFIG_SHEXT ".dll"
#else
#define CONFIG_SHEXT ".so"
#endif
#endif
#if defined(_WIN32) && !defined(__MSYS__)
#include <io.h>
#define PATHSEP_CHAR '\\'
#define PATHSEP_STR "\\"
#define LISTSEP_CHAR ';'
#define LISTSEP_STR ";"
#else
#include <unistd.h>
#define PATHSEP_CHAR '/'
#define PATHSEP_STR "/"
#define LISTSEP_CHAR ':'
#define LISTSEP_STR ":"
#endif
const char js_default_module_path[] =
#ifdef QUICKJS_MODULE_PATH
QUICKJS_MODULE_PATH
#elif defined(QUICKJS_C_MODULE_DIR) && defined(QUICKJS_JS_MODULE_DIR)
QUICKJS_C_MODULE_DIR LISTSEP_STR QUICKJS_JS_MODULE_DIR
#elif defined(QUICKJS_PREFIX)
#ifdef HOST_SYSTEM_NAME
QUICKJS_PREFIX "/lib/" HOST_SYSTEM_NAME "/quickjs" LISTSEP_STR
#endif
QUICKJS_PREFIX "/lib/quickjs"
#endif
;
static inline size_t
strchrs(const char* in, const char needles[]) {
const char* t;
for(t = in; *t; ++t)
for(size_t i = 0; needles[i]; i++)
if(*t == needles[i])
return (size_t)(t - in);
return (size_t)(t - in);
}
char*
js_find_module_ext(JSContext* ctx, const char* module_name, const char* ext) {
const char *module_path, *p, *q;
char filename[PATH_MAX];
size_t n, m;
struct stat st;
char listsep[3] = { LISTSEP_CHAR, ';', 0}, pathsep = PATHSEP_CHAR;
if((module_path = getenv("QUICKJS_MODULE_PATH")) == NULL)
module_path = js_default_module_path;
if(module_path[0] != PATHSEP_CHAR && module_path[1] == ':' && (module_path[2] == '/' || module_path[2] == '\\')) {
listsep[0] = ';';
pathsep = module_path[2];
}
for(p = module_path; *p; p = q) {
n = strchrs(p, listsep);
//n = (q = strchr(p, listsep)) ? q - p : strlen(p);
if(*(q = p + n))
++q;
//filename = js_malloc(ctx, n + 1 + strlen(module_name) + 3 + 1);
strncpy(filename, p, n);
filename[n] = pathsep;
strcpy(&filename[n + 1], module_name);
m = strlen(module_name);
if(!(m >= 3 && !strcmp(&module_name[m - 3], ext)))
strcpy(&filename[n + 1 + m], ext);
if(0 == access(filename, F_OK))
return js_strdup(ctx, filename);
// while(strchrs(q, LISTSEP_CHARS) == 0) ++q;
}
return NULL;
}
char*
js_find_module(JSContext* ctx, const char* module_name) {
char* ret = NULL;
size_t len;
// while(!strncmp(module_name, "." PATHSEP_STR, 2)) module_name += 2;
len = strlen(module_name);
if(!strchr(module_name, '.')) {
ret = js_find_module_ext(ctx, module_name, CONFIG_SHEXT);
if(ret == NULL)
ret = js_find_module_ext(ctx, module_name, ".js");
} else {
ret = js_find_module_ext(ctx, module_name, "");
}
return ret;
}
static JSModuleDef*
js_find_module_path(JSContext* ctx, const char* module_name, void* opaque) {
char* filename;
JSModuleDef* ret = NULL;
filename =
module_name[strchrs(module_name, "." PATHSEP_STR)] ? js_strdup(ctx, module_name) : js_find_module(ctx, module_name);
if(filename) {
ret = js_module_loader(ctx, filename, opaque);
js_free(ctx, filename);
}
return ret;
}
JSModuleDef*
js_module_loader_path(JSContext* ctx, const char* module_name, void* opaque) {
return js_find_module_path(ctx, module_name, opaque);
}
static JSModuleLoaderFunc* module_loader_path = &js_find_module_path;
void
js_std_set_module_loader_func(JSModuleLoaderFunc* func) {
module_loader_path = func;
}
JSModuleLoaderFunc*
js_std_get_module_loader_func() {
return module_loader_path;
}