xbintsc 0.3.15 → 0.3.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/dist/src/cli/main.js +4 -4
  2. package/dist/src/cli/main.js.map +1 -1
  3. package/dist/src/codegen/generator/state.js +8 -0
  4. package/dist/src/codegen/generator/state.js.map +1 -1
  5. package/dist/src/codegen/generator/tables.js +8 -0
  6. package/dist/src/codegen/generator/tables.js.map +1 -1
  7. package/dist/src/driver/bundler/graph.d.ts +8 -0
  8. package/dist/src/driver/bundler/graph.js +85 -0
  9. package/dist/src/driver/bundler/graph.js.map +1 -0
  10. package/dist/src/driver/bundler/merge.d.ts +11 -0
  11. package/dist/src/driver/bundler/merge.js +288 -0
  12. package/dist/src/driver/bundler/merge.js.map +1 -0
  13. package/dist/src/driver/bundler/resolve.d.ts +12 -0
  14. package/dist/src/driver/bundler/resolve.js +246 -0
  15. package/dist/src/driver/bundler/resolve.js.map +1 -0
  16. package/dist/src/driver/bundler/symbols.d.ts +15 -0
  17. package/dist/src/driver/bundler/symbols.js +51 -0
  18. package/dist/src/driver/bundler/symbols.js.map +1 -0
  19. package/dist/src/driver/bundler/types.d.ts +36 -0
  20. package/dist/src/driver/bundler/types.js +5 -0
  21. package/dist/src/driver/bundler/types.js.map +1 -0
  22. package/dist/src/driver/modules.d.ts +9 -16
  23. package/dist/src/driver/modules.js +8 -644
  24. package/dist/src/driver/modules.js.map +1 -1
  25. package/dist/src/extensions/catalog.js +2 -1
  26. package/dist/src/extensions/catalog.js.map +1 -1
  27. package/dist/src/extensions/gui/index.d.ts +24 -0
  28. package/dist/src/extensions/gui/index.js +101 -0
  29. package/dist/src/extensions/gui/index.js.map +1 -0
  30. package/dist/tests/e2e/compile-basics.test.d.ts +4 -0
  31. package/dist/tests/e2e/compile-basics.test.js +134 -0
  32. package/dist/tests/e2e/compile-basics.test.js.map +1 -0
  33. package/dist/tests/e2e/compile-builtins.test.d.ts +4 -0
  34. package/dist/tests/e2e/compile-builtins.test.js +191 -0
  35. package/dist/tests/e2e/compile-builtins.test.js.map +1 -0
  36. package/dist/tests/e2e/compile-control-flow.test.d.ts +4 -0
  37. package/dist/tests/e2e/compile-control-flow.test.js +190 -0
  38. package/dist/tests/e2e/compile-control-flow.test.js.map +1 -0
  39. package/dist/tests/e2e/compile-modules.test.d.ts +4 -0
  40. package/dist/tests/e2e/compile-modules.test.js +48 -0
  41. package/dist/tests/e2e/compile-modules.test.js.map +1 -0
  42. package/dist/tests/e2e/compile-objects-classes.test.d.ts +4 -0
  43. package/dist/tests/e2e/compile-objects-classes.test.js +362 -0
  44. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -0
  45. package/dist/tests/e2e/differential-helpers.d.ts +12 -0
  46. package/dist/tests/e2e/differential-helpers.js +16 -0
  47. package/dist/tests/e2e/differential-helpers.js.map +1 -0
  48. package/dist/tests/e2e/differential-language.test.d.ts +4 -0
  49. package/dist/tests/e2e/{differential.test.js → differential-language.test.js} +5 -287
  50. package/dist/tests/e2e/differential-language.test.js.map +1 -0
  51. package/dist/tests/e2e/differential-symbols.test.d.ts +4 -0
  52. package/dist/tests/e2e/differential-symbols.test.js +92 -0
  53. package/dist/tests/e2e/differential-symbols.test.js.map +1 -0
  54. package/dist/tests/e2e/differential-values.test.d.ts +4 -0
  55. package/dist/tests/e2e/differential-values.test.js +197 -0
  56. package/dist/tests/e2e/differential-values.test.js.map +1 -0
  57. package/dist/tests/e2e/gui.test.d.ts +12 -0
  58. package/dist/tests/e2e/gui.test.js +493 -0
  59. package/dist/tests/e2e/gui.test.js.map +1 -0
  60. package/dist/tests/e2e/runtime-coverage-buffer.test.d.ts +4 -0
  61. package/dist/tests/e2e/runtime-coverage-buffer.test.js +97 -0
  62. package/dist/tests/e2e/runtime-coverage-buffer.test.js.map +1 -0
  63. package/dist/tests/e2e/runtime-coverage-globals.test.d.ts +4 -0
  64. package/dist/tests/e2e/runtime-coverage-globals.test.js +149 -0
  65. package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -0
  66. package/dist/tests/e2e/runtime-coverage-node-modules.test.d.ts +4 -0
  67. package/dist/tests/e2e/runtime-coverage-node-modules.test.js +177 -0
  68. package/dist/tests/e2e/runtime-coverage-node-modules.test.js.map +1 -0
  69. package/dist/tests/e2e/runtime-coverage-streams.test.d.ts +4 -0
  70. package/dist/tests/e2e/runtime-coverage-streams.test.js +161 -0
  71. package/dist/tests/e2e/runtime-coverage-streams.test.js.map +1 -0
  72. package/dist/tests/e2e/runtime-coverage-system.test.d.ts +4 -0
  73. package/dist/tests/e2e/runtime-coverage-system.test.js +91 -0
  74. package/dist/tests/e2e/runtime-coverage-system.test.js.map +1 -0
  75. package/dist/tests/e2e/timers.test.d.ts +7 -0
  76. package/dist/tests/e2e/timers.test.js +63 -0
  77. package/dist/tests/e2e/timers.test.js.map +1 -0
  78. package/package.json +2 -1
  79. package/runtime/ext_gui/css.cpp +743 -0
  80. package/runtime/ext_gui/css.h +98 -0
  81. package/runtime/ext_gui/document.cpp +264 -0
  82. package/runtime/ext_gui/document.h +89 -0
  83. package/runtime/ext_gui/dom.cpp +472 -0
  84. package/runtime/ext_gui/dom.h +71 -0
  85. package/runtime/ext_gui/gui.cpp +457 -0
  86. package/runtime/ext_gui/gui_engine.h +81 -0
  87. package/runtime/ext_gui/image.cpp +125 -0
  88. package/runtime/ext_gui/image.h +42 -0
  89. package/runtime/ext_gui/layout.cpp +748 -0
  90. package/runtime/ext_gui/layout.h +93 -0
  91. package/runtime/ext_gui/paint.cpp +137 -0
  92. package/runtime/ext_gui/paint.h +75 -0
  93. package/runtime/ext_gui/renderer.cpp +959 -0
  94. package/runtime/ext_gui/renderer.h +68 -0
  95. package/runtime/ext_gui/stb_image.h +7988 -0
  96. package/runtime/ext_gui/style.cpp +771 -0
  97. package/runtime/ext_gui/style.h +117 -0
  98. package/runtime/ext_gui/text.cpp +378 -0
  99. package/runtime/ext_gui/text.h +78 -0
  100. package/runtime/ext_gui/window.cpp +405 -0
  101. package/runtime/ext_node/fs/fs_common.h +13 -527
  102. package/runtime/ext_node/fs/parts/buffer-bridge.inc +6 -0
  103. package/runtime/ext_node/fs/parts/builtins.inc +69 -0
  104. package/runtime/ext_node/fs/parts/dir.inc +47 -0
  105. package/runtime/ext_node/fs/parts/encoding.inc +186 -0
  106. package/runtime/ext_node/fs/parts/errors.inc +66 -0
  107. package/runtime/ext_node/fs/parts/flags.inc +39 -0
  108. package/runtime/ext_node/fs/parts/platform.inc +86 -0
  109. package/runtime/ext_node/fs/parts/promisify.inc +15 -0
  110. package/runtime/ext_node/fs/parts/time.inc +9 -0
  111. package/runtime/rt.h +33 -0
  112. package/runtime/xt_builtins.c +4 -0
  113. package/runtime/xt_containers/access.inc +168 -0
  114. package/runtime/xt_containers/arrays.inc +108 -0
  115. package/runtime/xt_containers/boxes.inc +11 -0
  116. package/runtime/xt_containers/objects.inc +326 -0
  117. package/runtime/xt_containers.c +8 -618
  118. package/runtime/xt_io/base64.inc +87 -0
  119. package/runtime/xt_io/console.inc +119 -0
  120. package/runtime/xt_io/exception.inc +142 -0
  121. package/runtime/xt_io/inspect.inc +212 -0
  122. package/runtime/xt_io.c +8 -553
  123. package/runtime/xt_loop.c +262 -24
  124. package/runtime/xt_regex/api.inc +58 -0
  125. package/runtime/xt_regex/helpers.inc +68 -0
  126. package/runtime/xt_regex/matcher.inc +248 -0
  127. package/runtime/xt_regex/parser.inc +236 -0
  128. package/runtime/xt_regex/types.inc +58 -0
  129. package/runtime/xt_regex.h +9 -672
  130. package/runtime/xt_values/arithmetic.inc +150 -0
  131. package/runtime/xt_values/comparison.inc +112 -0
  132. package/runtime/xt_values/constructors.inc +41 -0
  133. package/runtime/xt_values/conversions.inc +115 -0
  134. package/runtime/xt_values/number-format.inc +180 -0
  135. package/runtime/xt_values/strings.inc +22 -0
  136. package/runtime/xt_values.c +10 -626
  137. package/scripts/build-gui.ts +317 -0
  138. package/src/cli/main.ts +4 -3
  139. package/src/codegen/generator/state.ts +8 -0
  140. package/src/codegen/generator/tables.ts +8 -0
  141. package/src/driver/bundler/graph.ts +95 -0
  142. package/src/driver/bundler/merge.ts +312 -0
  143. package/src/driver/bundler/resolve.ts +240 -0
  144. package/src/driver/bundler/symbols.ts +55 -0
  145. package/src/driver/bundler/types.ts +37 -0
  146. package/src/driver/modules.ts +9 -693
  147. package/src/extensions/catalog.ts +2 -1
  148. package/src/extensions/gui/index.ts +107 -0
  149. package/dist/tests/e2e/compile.test.d.ts +0 -8
  150. package/dist/tests/e2e/compile.test.js +0 -893
  151. package/dist/tests/e2e/compile.test.js.map +0 -1
  152. package/dist/tests/e2e/differential.test.d.ts +0 -7
  153. package/dist/tests/e2e/differential.test.js.map +0 -1
  154. package/dist/tests/e2e/runtime-coverage.test.d.ts +0 -11
  155. package/dist/tests/e2e/runtime-coverage.test.js +0 -646
  156. package/dist/tests/e2e/runtime-coverage.test.js.map +0 -1
@@ -6,6 +6,10 @@
6
6
  * through these static inline helpers. Encoding support is deliberately
7
7
  * buffer-free: `base64`/`hex` are encoded to strings directly, since xbintsc
8
8
  * has no `Buffer` value type yet.
9
+ *
10
+ * The helpers are grouped by functional area under `fs/parts/` and
11
+ * `#include`d here, so this stays the single header every `fs` translation
12
+ * unit already pulls in.
9
13
  */
10
14
  #ifndef XT_NODE_FS_COMMON_H
11
15
  #define XT_NODE_FS_COMMON_H
@@ -18,532 +22,14 @@
18
22
  #include <string.h>
19
23
  #include <time.h>
20
24
 
21
- /* -- platform shims ------------------------------------------------------- */
22
-
23
- #if defined(_WIN32)
24
- #include <direct.h>
25
- #include <fcntl.h>
26
- #include <io.h>
27
- #include <sys/stat.h>
28
- #include <sys/types.h>
29
-
30
- /* Stat results are filled from Win32 directly. The CRT's `_stat` converts the
31
- * FILETIME through the *local* time zone before producing `time_t`, so a time
32
- * near the Unix epoch (e.g. `utimesSync(path, 1000, 2000)`) maps to 1969 on a
33
- * machine west of UTC and the CRT reports an unrepresentable `st_mtime` (-1).
34
- * Reading the Win32 FILETIME and converting it to Unix seconds in UTC like
35
- * libuv/Node keeps the values exact and timezone independent. */
36
- typedef struct {
37
- long long st_size;
38
- unsigned int st_mode;
39
- unsigned int st_uid;
40
- unsigned int st_gid;
41
- unsigned int st_dev;
42
- unsigned long long st_ino;
43
- unsigned int st_nlink;
44
- unsigned int st_rdev;
45
- long long st_mtime; /* seconds since the Unix epoch */
46
- long long st_atime;
47
- long long st_ctime;
48
- } xt_fs_stat_t;
49
-
50
- int xt_fs_win_stat(const char *path, xt_fs_stat_t *out);
51
- int xt_fs_win_lstat(const char *path, xt_fs_stat_t *out);
52
- int xt_fs_win_fstat(int fd, xt_fs_stat_t *out);
53
- #define xt_fs_stat_fn xt_fs_win_stat
54
- #define xt_fs_lstat_fn xt_fs_win_lstat
55
- #define xt_fs_fstat_fn xt_fs_win_fstat
56
- #define xt_fs_access _access
57
- #define xt_fs_mkdir_mode(path, mode) _mkdir(path)
58
- #define xt_fs_mkdir_one(path) _mkdir(path)
59
- #define xt_fs_rmdir_one(path) _rmdir(path)
60
- #define XT_FS_OPEN _open
61
- #define XT_FS_CLOSE _close
62
- #define XT_FS_READ _read
63
- #define XT_FS_WRITE _write
64
-
65
- #ifndef S_ISREG
66
- #define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
67
- #endif
68
- #ifndef S_ISDIR
69
- #define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
70
- #endif
71
- #ifndef S_ISLNK
72
- #define S_ISLNK(m) 0
73
- #endif
74
- #ifndef S_ISFIFO
75
- #define S_ISFIFO(m) 0
76
- #endif
77
- #ifndef S_ISSOCK
78
- #define S_ISSOCK(m) 0
79
- #endif
80
- #ifndef S_ISBLK
81
- #define S_ISBLK(m) 0
82
- #endif
83
- #ifndef S_ISCHR
84
- #define S_ISCHR(m) (((m) & _S_IFMT) == _S_IFCHR)
85
- #endif
86
- #ifndef F_OK
87
- #define F_OK 0
88
- #endif
89
- #else
90
- #include <fcntl.h>
91
- #include <sys/stat.h>
92
- #include <sys/types.h>
93
- #include <unistd.h>
94
-
95
- typedef struct stat xt_fs_stat_t;
96
- #define xt_fs_stat_fn stat
97
- #define xt_fs_lstat_fn lstat
98
- #define xt_fs_access access
99
- #define xt_fs_mkdir_mode(path, mode) mkdir((path), (mode))
100
- #define xt_fs_mkdir_one(path) mkdir(path, 0777)
101
- #define xt_fs_rmdir_one(path) rmdir(path)
102
- #define XT_FS_OPEN open
103
- #define XT_FS_CLOSE close
104
- #define XT_FS_READ read
105
- #define XT_FS_WRITE write
106
- #endif
107
-
108
- /* -- directory iteration -------------------------------------------------- */
109
-
110
- #if defined(_WIN32)
111
- /* Directory iteration backed by the CRT's _findfirst/_findnext. */
112
- typedef struct {
113
- intptr_t handle;
114
- struct _finddata_t entry;
115
- } xt_fs_dir;
116
-
117
- static inline int xt_fs_dir_open(xt_fs_dir *dir, const char *path) {
118
- size_t length = strlen(path);
119
- char *pattern = (char *)malloc(length + 3);
120
- if (!pattern) return 0;
121
- memcpy(pattern, path, length);
122
- pattern[length] = '/';
123
- pattern[length + 1] = '*';
124
- pattern[length + 2] = '\0';
125
- dir->handle = _findfirst(pattern, &dir->entry);
126
- free(pattern);
127
- return dir->handle != -1;
128
- }
129
-
130
- static inline int xt_fs_dir_next(xt_fs_dir *dir) { return _findnext(dir->handle, &dir->entry) == 0; }
131
- static inline const char *xt_fs_dir_name(xt_fs_dir *dir) { return dir->entry.name; }
132
- static inline void xt_fs_dir_close(xt_fs_dir *dir) { _findclose(dir->handle); }
133
- #else
134
- #include <dirent.h>
135
-
136
- typedef struct {
137
- DIR *handle;
138
- struct dirent *entry;
139
- } xt_fs_dir;
140
-
141
- static inline int xt_fs_dir_open(xt_fs_dir *dir, const char *path) {
142
- dir->handle = opendir(path);
143
- dir->entry = NULL;
144
- return dir->handle != NULL;
145
- }
146
-
147
- static inline int xt_fs_dir_next(xt_fs_dir *dir) {
148
- dir->entry = readdir(dir->handle);
149
- return dir->entry != NULL;
150
- }
151
-
152
- static inline const char *xt_fs_dir_name(xt_fs_dir *dir) { return dir->entry->d_name; }
153
- static inline void xt_fs_dir_close(xt_fs_dir *dir) { closedir(dir->handle); }
154
- #endif
155
-
156
- /* -- errors --------------------------------------------------------------- */
157
-
158
- /* Node's `err.code` for the errno values the fs module can raise. */
159
- static inline const char *xt_fs_errno_name(int err) {
160
- switch (err) {
161
- case ENOENT: return "ENOENT";
162
- case EACCES: return "EACCES";
163
- case EEXIST: return "EEXIST";
164
- case ENOTDIR: return "ENOTDIR";
165
- case EISDIR: return "EISDIR";
166
- case EPERM: return "EPERM";
167
- case EINVAL: return "EINVAL";
168
- case EBADF: return "EBADF";
169
- case ENOSPC: return "ENOSPC";
170
- case EROFS: return "EROFS";
171
- case EMFILE: return "EMFILE";
172
- #ifdef ENOTEMPTY
173
- case ENOTEMPTY: return "ENOTEMPTY";
174
- #endif
175
- #ifdef ELOOP
176
- case ELOOP: return "ELOOP";
177
- #endif
178
- #ifdef ENAMETOOLONG
179
- case ENAMETOOLONG: return "ENAMETOOLONG";
180
- #endif
181
- #ifdef EXDEV
182
- case EXDEV: return "EXDEV";
183
- #endif
184
- default: return "UNKNOWN";
185
- }
186
- }
187
-
188
- /* Build a Node-shaped Error (`code`/`errno`/`syscall`/`path`/`message`). */
189
- static inline xt_value xt_fs_error_object(int err, const char *syscall, const char *path) {
190
- const char *code = xt_fs_errno_name(err);
191
- char buffer[1024];
192
- snprintf(buffer, sizeof(buffer), "%s: %s, %s '%s'", code, strerror(err), syscall ? syscall : "",
193
- path ? path : "");
194
- xt_value error = xt_object_new();
195
- ((xt_object *)XT_GET_PTR(error))->header.kind = XT_OBJECT_KIND_ERROR;
196
- xt_object_set(error, xt_string_from_cstr("name"), xt_string_from_cstr("Error"));
197
- xt_object_set(error, xt_string_from_cstr("message"), xt_string_from_cstr(buffer));
198
- xt_object_set(error, xt_string_from_cstr("code"), xt_string_from_cstr(code));
199
- xt_object_set(error, xt_string_from_cstr("errno"), xt_number((double)(-err)));
200
- if (syscall) xt_object_set(error, xt_string_from_cstr("syscall"), xt_string_from_cstr(syscall));
201
- if (path) xt_object_set(error, xt_string_from_cstr("path"), xt_string_from_cstr(path));
202
- return error;
203
- }
204
-
205
- /* Raise `errno` (captured by the caller right after a failed syscall). */
206
- static inline void xt_fs_raise_errno(int err, const char *syscall, const char *path) {
207
- xt_throw(xt_fs_error_object(err, syscall, path));
208
- }
209
-
210
- static inline void xt_fs_raise_path(const char *syscall, const char *path) {
211
- xt_fs_raise_errno(errno, syscall, path);
212
- }
213
-
214
- /* -- time helpers --------------------------------------------------------- */
215
-
216
- /* Node accepts a Date or a number of seconds; Date stores milliseconds. */
217
- static inline double xt_fs_time_seconds(xt_value value) {
218
- if (XT_IS_OBJECT(value) && ((xt_object *)XT_GET_PTR(value))->header.kind == XT_OBJECT_KIND_DATE) {
219
- return ((xt_date *)XT_GET_PTR(value))->time / 1000.0;
220
- }
221
- return xt_to_number(value);
222
- }
223
-
224
- /* -- open-flag parsing ---------------------------------------------------- */
225
-
226
- #if defined(_WIN32)
227
- #define XT_FS_BINARY_FLAG _O_BINARY
228
- #define XT_FS_RDONLY _O_RDONLY
229
- #define XT_FS_WRONLY _O_WRONLY
230
- #define XT_FS_RDWR _O_RDWR
231
- #define XT_FS_CREAT _O_CREAT
232
- #define XT_FS_TRUNC _O_TRUNC
233
- #define XT_FS_APPEND _O_APPEND
234
- #define XT_FS_EXCL _O_EXCL
235
- #else
236
- #define XT_FS_BINARY_FLAG 0
237
- #define XT_FS_RDONLY O_RDONLY
238
- #define XT_FS_WRONLY O_WRONLY
239
- #define XT_FS_RDWR O_RDWR
240
- #define XT_FS_CREAT O_CREAT
241
- #define XT_FS_TRUNC O_TRUNC
242
- #define XT_FS_APPEND O_APPEND
243
- #define XT_FS_EXCL O_EXCL
244
- #endif
245
-
246
- /* Translate a Node flag string (`"r"`, `"w+"`, `"a"`, ...) or number. */
247
- static inline int xt_fs_parse_flags(xt_value value) {
248
- if (XT_IS_STRING(value)) {
249
- const char *flag = xt_string_data(value);
250
- if (!flag) return XT_FS_RDONLY | XT_FS_BINARY_FLAG;
251
- int plus = strchr(flag, '+') != NULL;
252
- int excl = strchr(flag, 'x') != NULL;
253
- int base;
254
- if (flag[0] == 'a') base = XT_FS_APPEND | XT_FS_CREAT;
255
- else if (flag[0] == 'w') base = XT_FS_CREAT | XT_FS_TRUNC;
256
- else base = 0; /* 'r' and the numeric path below */
257
- base |= (plus || flag[0] == 'w' || flag[0] == 'a') ? XT_FS_RDWR : XT_FS_RDONLY;
258
- if (excl) base |= XT_FS_EXCL;
259
- return base | XT_FS_BINARY_FLAG;
260
- }
261
- return (int)xt_to_number(value) | XT_FS_BINARY_FLAG;
262
- }
263
-
264
- /* -- shared object builders (defined in fs_ops.c) ------------------------- */
265
-
266
- xt_value xt_node_stat_result(const xt_fs_stat_t *info);
267
- xt_value xt_node_dirent_result(const char *dir, const char *name);
268
-
269
- /* -- synchronous fs builtins (one translation unit per group) ------------- */
270
-
271
- xt_value xt_node_read_text_file(int32_t argc, xt_value *argv);
272
- xt_value xt_node_write_file(int32_t argc, xt_value *argv);
273
- xt_value xt_node_append_file(int32_t argc, xt_value *argv);
274
- xt_value xt_node_exists(int32_t argc, xt_value *argv);
275
- xt_value xt_node_mkdir(int32_t argc, xt_value *argv);
276
- xt_value xt_node_read_dir(int32_t argc, xt_value *argv);
277
- xt_value xt_node_rm(int32_t argc, xt_value *argv);
278
- xt_value xt_node_unlink(int32_t argc, xt_value *argv);
279
- xt_value xt_node_rmdir(int32_t argc, xt_value *argv);
280
- xt_value xt_node_rename(int32_t argc, xt_value *argv);
281
- xt_value xt_node_copy_file(int32_t argc, xt_value *argv);
282
- xt_value xt_node_realpath(int32_t argc, xt_value *argv);
283
- xt_value xt_node_stat(int32_t argc, xt_value *argv);
284
- xt_value xt_node_lstat(int32_t argc, xt_value *argv);
285
- xt_value xt_node_cp(int32_t argc, xt_value *argv);
286
-
287
- /* fd_ops.c */
288
- xt_value xt_node_open(int32_t argc, xt_value *argv);
289
- xt_value xt_node_close(int32_t argc, xt_value *argv);
290
- xt_value xt_node_read(int32_t argc, xt_value *argv);
291
- xt_value xt_node_write(int32_t argc, xt_value *argv);
292
- xt_value xt_node_readv(int32_t argc, xt_value *argv);
293
- xt_value xt_node_writev(int32_t argc, xt_value *argv);
294
- xt_value xt_node_fstat(int32_t argc, xt_value *argv);
295
- xt_value xt_node_fsync(int32_t argc, xt_value *argv);
296
- xt_value xt_node_fdatasync(int32_t argc, xt_value *argv);
297
- xt_value xt_node_ftruncate(int32_t argc, xt_value *argv);
298
- xt_value xt_node_fchmod(int32_t argc, xt_value *argv);
299
- xt_value xt_node_fchown(int32_t argc, xt_value *argv);
300
- xt_value xt_node_futimes(int32_t argc, xt_value *argv);
301
-
302
- /* meta_ops.c */
303
- xt_value xt_node_access(int32_t argc, xt_value *argv);
304
- xt_value xt_node_chmod(int32_t argc, xt_value *argv);
305
- xt_value xt_node_chown(int32_t argc, xt_value *argv);
306
- xt_value xt_node_lchmod(int32_t argc, xt_value *argv);
307
- xt_value xt_node_lchown(int32_t argc, xt_value *argv);
308
- xt_value xt_node_truncate(int32_t argc, xt_value *argv);
309
- xt_value xt_node_utimes(int32_t argc, xt_value *argv);
310
- xt_value xt_node_lutimes(int32_t argc, xt_value *argv);
311
- xt_value xt_node_statfs(int32_t argc, xt_value *argv);
312
- xt_value xt_node_mkdtemp(int32_t argc, xt_value *argv);
313
-
314
- /* link_ops.c */
315
- xt_value xt_node_link(int32_t argc, xt_value *argv);
316
- xt_value xt_node_symlink(int32_t argc, xt_value *argv);
317
- xt_value xt_node_readlink(int32_t argc, xt_value *argv);
318
-
319
- /* dir.c */
320
- xt_value xt_node_opendir(int32_t argc, xt_value *argv);
321
-
322
- /* glob.c */
323
- xt_value xt_node_glob(int32_t argc, xt_value *argv);
324
-
325
- /* watch.c */
326
- xt_value xt_node_watch(int32_t argc, xt_value *argv);
327
- xt_value xt_node_watch_file(int32_t argc, xt_value *argv);
328
- xt_value xt_node_unwatch_file(int32_t argc, xt_value *argv);
329
-
330
- /* constants.c */
331
- xt_value xt_fs_constants(void);
332
- xt_value xt_fs_promises(void);
333
-
334
- /* A promise wrapper over a synchronous builtin: an immediately settled
335
- * promise that is rejected (rather than throwing) when the builtin raises. */
336
- static inline xt_value xt_fs_promisify(xt_value (*fn)(int32_t, xt_value *), int32_t argc, xt_value *argv) {
337
- void *frame = xt_try_enter();
338
- if (xt_try_setjmp(frame) == 0) {
339
- xt_value result = fn(argc, argv);
340
- xt_try_leave(frame);
341
- return xt_promise_resolve(result);
342
- }
343
- xt_value exception = xt_try_exception(frame);
344
- xt_try_leave(frame);
345
- return xt_promise_reject(exception);
346
- }
347
-
348
- /* -- Buffer bridge (defined in buffer/parts/prototype.inc) ---------------- */
349
-
350
- int xt_node_is_buffer(xt_value value);
351
- unsigned char *xt_node_buffer_bytes(xt_value value, size_t *outLength);
352
- uint32_t xt_node_buffer_length(xt_value value);
353
- void xt_node_buffer_set(xt_value value, uint32_t index, unsigned char byte);
354
-
355
- static const char xt_fs_base64_alphabet[] =
356
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
357
-
358
- /* Accepts a bare encoding string or an options object with `encoding`. */
359
- static inline const char *xt_fs_encoding(xt_value options) {
360
- if (XT_IS_STRING(options)) return xt_string_data(options);
361
- if (XT_IS_OBJECT(options)) {
362
- xt_value encoding = xt_object_get_cstr(options, "encoding");
363
- if (XT_IS_STRING(encoding)) return xt_string_data(encoding);
364
- }
365
- return NULL;
366
- }
367
-
368
- static inline int xt_fs_is_hex(const char *encoding) {
369
- return encoding && strcmp(encoding, "hex") == 0;
370
- }
371
-
372
- static inline int xt_fs_is_base64(const char *encoding) {
373
- return encoding && strcmp(encoding, "base64") == 0;
374
- }
375
-
376
- static inline int xt_fs_is_base64url(const char *encoding) {
377
- return encoding && strcmp(encoding, "base64url") == 0;
378
- }
379
-
380
- static inline int xt_fs_is_utf16(const char *encoding) {
381
- return encoding && (strcmp(encoding, "utf16le") == 0 || strcmp(encoding, "ucs2") == 0 ||
382
- strcmp(encoding, "ucs-2") == 0 || strcmp(encoding, "utf-16le") == 0);
383
- }
384
-
385
- static inline xt_value xt_fs_encode_hex(const unsigned char *data, size_t length) {
386
- static const char digits[] = "0123456789abcdef";
387
- char *buffer = (char *)malloc(length * 2 + 1);
388
- if (!buffer) return xt_undefined();
389
- for (size_t i = 0; i < length; i++) {
390
- buffer[i * 2] = digits[data[i] >> 4];
391
- buffer[i * 2 + 1] = digits[data[i] & 0x0f];
392
- }
393
- xt_value result = xt_string_new(buffer, length * 2);
394
- free(buffer);
395
- return result;
396
- }
397
-
398
- static inline xt_value xt_fs_encode_base64(const unsigned char *data, size_t length) {
399
- size_t outLength = ((length + 2) / 3) * 4;
400
- char *buffer = (char *)malloc(outLength + 1);
401
- if (!buffer) return xt_undefined();
402
- size_t i = 0, j = 0;
403
- while (i + 2 < length) {
404
- uint32_t n = ((uint32_t)data[i] << 16) | ((uint32_t)data[i + 1] << 8) | (uint32_t)data[i + 2];
405
- buffer[j++] = xt_fs_base64_alphabet[(n >> 18) & 63];
406
- buffer[j++] = xt_fs_base64_alphabet[(n >> 12) & 63];
407
- buffer[j++] = xt_fs_base64_alphabet[(n >> 6) & 63];
408
- buffer[j++] = xt_fs_base64_alphabet[n & 63];
409
- i += 3;
410
- }
411
- if (length - i == 1) {
412
- uint32_t n = (uint32_t)data[i] << 16;
413
- buffer[j++] = xt_fs_base64_alphabet[(n >> 18) & 63];
414
- buffer[j++] = xt_fs_base64_alphabet[(n >> 12) & 63];
415
- buffer[j++] = '=';
416
- buffer[j++] = '=';
417
- } else if (length - i == 2) {
418
- uint32_t n = ((uint32_t)data[i] << 16) | ((uint32_t)data[i + 1] << 8);
419
- buffer[j++] = xt_fs_base64_alphabet[(n >> 18) & 63];
420
- buffer[j++] = xt_fs_base64_alphabet[(n >> 12) & 63];
421
- buffer[j++] = xt_fs_base64_alphabet[(n >> 6) & 63];
422
- buffer[j++] = '=';
423
- }
424
- xt_value result = xt_string_new(buffer, j);
425
- free(buffer);
426
- return result;
427
- }
428
-
429
- /* Encode bytes for `readFileSync` according to `encoding` (default raw UTF-8). */
430
- static inline xt_value xt_fs_encode_base64url(const unsigned char *data, size_t length) {
431
- size_t outLength = ((length + 2) / 3) * 4 + 1;
432
- char *buffer = (char *)malloc(outLength);
433
- if (!buffer) return xt_undefined();
434
- size_t i = 0, j = 0;
435
- while (i + 2 < length) {
436
- uint32_t n = ((uint32_t)data[i] << 16) | ((uint32_t)data[i + 1] << 8) | (uint32_t)data[i + 2];
437
- buffer[j++] = xt_fs_base64_alphabet[(n >> 18) & 63];
438
- buffer[j++] = xt_fs_base64_alphabet[(n >> 12) & 63];
439
- buffer[j++] = xt_fs_base64_alphabet[(n >> 6) & 63];
440
- buffer[j++] = xt_fs_base64_alphabet[n & 63];
441
- i += 3;
442
- }
443
- if (length - i == 1) {
444
- uint32_t n = (uint32_t)data[i] << 16;
445
- buffer[j++] = xt_fs_base64_alphabet[(n >> 18) & 63];
446
- buffer[j++] = xt_fs_base64_alphabet[(n >> 12) & 63];
447
- } else if (length - i == 2) {
448
- uint32_t n = ((uint32_t)data[i] << 16) | ((uint32_t)data[i + 1] << 8);
449
- buffer[j++] = xt_fs_base64_alphabet[(n >> 18) & 63];
450
- buffer[j++] = xt_fs_base64_alphabet[(n >> 12) & 63];
451
- buffer[j++] = xt_fs_base64_alphabet[(n >> 6) & 63];
452
- }
453
- for (size_t k = 0; k < j; k++) {
454
- if (buffer[k] == '+') buffer[k] = '-';
455
- else if (buffer[k] == '/') buffer[k] = '_';
456
- }
457
- xt_value result = xt_string_new(buffer, j);
458
- free(buffer);
459
- return result;
460
- }
461
-
462
- static inline xt_value xt_fs_encode_bytes(const unsigned char *data, size_t length, const char *encoding) {
463
- if (xt_fs_is_hex(encoding)) return xt_fs_encode_hex(data, length);
464
- if (xt_fs_is_base64(encoding)) return xt_fs_encode_base64(data, length);
465
- if (xt_fs_is_base64url(encoding)) return xt_fs_encode_base64url(data, length);
466
- return xt_string_new((const char *)data, length);
467
- }
468
-
469
- static inline int xt_fs_base64_value(char c) {
470
- if (c >= 'A' && c <= 'Z') return c - 'A';
471
- if (c >= 'a' && c <= 'z') return c - 'a' + 26;
472
- if (c >= '0' && c <= '9') return c - '0' + 52;
473
- if (c == '+' || c == '-') return 62;
474
- if (c == '/' || c == '_') return 63;
475
- return -1;
476
- }
477
-
478
- static inline int xt_fs_hex_value(char c) {
479
- if (c >= '0' && c <= '9') return c - '0';
480
- if (c >= 'a' && c <= 'f') return c - 'a' + 10;
481
- if (c >= 'A' && c <= 'F') return c - 'A' + 10;
482
- return -1;
483
- }
484
-
485
- /*
486
- * Decode text for `writeFileSync` according to `encoding`. Returns a malloc'd
487
- * byte buffer (never NULL unless allocation failed) and stores its length in
488
- * `*outLength`; the caller frees it.
489
- */
490
- static inline unsigned char *xt_fs_decode_text(const char *text, size_t length, const char *encoding, size_t *outLength) {
491
- unsigned char *bytes = NULL;
492
- if (xt_fs_is_base64(encoding) || xt_fs_is_base64url(encoding)) {
493
- size_t capacity = (length / 4 + 1) * 3;
494
- bytes = (unsigned char *)malloc(capacity + 1);
495
- if (!bytes) return NULL;
496
- size_t written = 0;
497
- int accumulator = 0, bits = 0;
498
- for (size_t i = 0; i < length; i++) {
499
- if (text[i] == '=') break;
500
- int value = xt_fs_base64_value(text[i]);
501
- if (value < 0) continue;
502
- accumulator = (accumulator << 6) | value;
503
- bits += 6;
504
- if (bits >= 8) {
505
- bits -= 8;
506
- bytes[written++] = (unsigned char)((accumulator >> bits) & 0xff);
507
- }
508
- }
509
- bytes[written] = '\0';
510
- *outLength = written;
511
- return bytes;
512
- }
513
- if (xt_fs_is_hex(encoding)) {
514
- bytes = (unsigned char *)malloc(length / 2 + 1);
515
- if (!bytes) return NULL;
516
- size_t written = 0;
517
- int high = -1;
518
- for (size_t i = 0; i < length; i++) {
519
- int value = xt_fs_hex_value(text[i]);
520
- if (value < 0) continue;
521
- if (high < 0) {
522
- high = value;
523
- } else {
524
- bytes[written++] = (unsigned char)((high << 4) | value);
525
- high = -1;
526
- }
527
- }
528
- bytes[written] = '\0';
529
- *outLength = written;
530
- return bytes;
531
- }
532
- bytes = (unsigned char *)malloc(length + 1);
533
- if (!bytes) return NULL;
534
- if (length > 0) memcpy(bytes, text, length);
535
- bytes[length] = '\0';
536
- *outLength = length;
537
- return bytes;
538
- }
539
-
540
- /*
541
- * Report a failed syscall. The fs module follows Node and *throws* a shaped
542
- * Error (the runtime now has catchable exceptions), so callers must not rely
543
- * on a return value after a failure.
544
- */
545
- static inline void xt_fs_error(const char *action, const char *path) {
546
- xt_fs_raise_errno(errno, action, path);
547
- }
25
+ #include "parts/platform.inc"
26
+ #include "parts/dir.inc"
27
+ #include "parts/errors.inc"
28
+ #include "parts/time.inc"
29
+ #include "parts/flags.inc"
30
+ #include "parts/builtins.inc"
31
+ #include "parts/promisify.inc"
32
+ #include "parts/buffer-bridge.inc"
33
+ #include "parts/encoding.inc"
548
34
 
549
35
  #endif /* XT_NODE_FS_COMMON_H */
@@ -0,0 +1,6 @@
1
+ /* -- Buffer bridge (defined in buffer/parts/prototype.inc) ---------------- */
2
+
3
+ int xt_node_is_buffer(xt_value value);
4
+ unsigned char *xt_node_buffer_bytes(xt_value value, size_t *outLength);
5
+ uint32_t xt_node_buffer_length(xt_value value);
6
+ void xt_node_buffer_set(xt_value value, uint32_t index, unsigned char byte);
@@ -0,0 +1,69 @@
1
+ /* -- shared object builders (defined in fs_ops.c) ------------------------- */
2
+
3
+ xt_value xt_node_stat_result(const xt_fs_stat_t *info);
4
+ xt_value xt_node_dirent_result(const char *dir, const char *name);
5
+
6
+ /* -- synchronous fs builtins (one translation unit per group) ------------- */
7
+
8
+ xt_value xt_node_read_text_file(int32_t argc, xt_value *argv);
9
+ xt_value xt_node_write_file(int32_t argc, xt_value *argv);
10
+ xt_value xt_node_append_file(int32_t argc, xt_value *argv);
11
+ xt_value xt_node_exists(int32_t argc, xt_value *argv);
12
+ xt_value xt_node_mkdir(int32_t argc, xt_value *argv);
13
+ xt_value xt_node_read_dir(int32_t argc, xt_value *argv);
14
+ xt_value xt_node_rm(int32_t argc, xt_value *argv);
15
+ xt_value xt_node_unlink(int32_t argc, xt_value *argv);
16
+ xt_value xt_node_rmdir(int32_t argc, xt_value *argv);
17
+ xt_value xt_node_rename(int32_t argc, xt_value *argv);
18
+ xt_value xt_node_copy_file(int32_t argc, xt_value *argv);
19
+ xt_value xt_node_realpath(int32_t argc, xt_value *argv);
20
+ xt_value xt_node_stat(int32_t argc, xt_value *argv);
21
+ xt_value xt_node_lstat(int32_t argc, xt_value *argv);
22
+ xt_value xt_node_cp(int32_t argc, xt_value *argv);
23
+
24
+ /* fd_ops.c */
25
+ xt_value xt_node_open(int32_t argc, xt_value *argv);
26
+ xt_value xt_node_close(int32_t argc, xt_value *argv);
27
+ xt_value xt_node_read(int32_t argc, xt_value *argv);
28
+ xt_value xt_node_write(int32_t argc, xt_value *argv);
29
+ xt_value xt_node_readv(int32_t argc, xt_value *argv);
30
+ xt_value xt_node_writev(int32_t argc, xt_value *argv);
31
+ xt_value xt_node_fstat(int32_t argc, xt_value *argv);
32
+ xt_value xt_node_fsync(int32_t argc, xt_value *argv);
33
+ xt_value xt_node_fdatasync(int32_t argc, xt_value *argv);
34
+ xt_value xt_node_ftruncate(int32_t argc, xt_value *argv);
35
+ xt_value xt_node_fchmod(int32_t argc, xt_value *argv);
36
+ xt_value xt_node_fchown(int32_t argc, xt_value *argv);
37
+ xt_value xt_node_futimes(int32_t argc, xt_value *argv);
38
+
39
+ /* meta_ops.c */
40
+ xt_value xt_node_access(int32_t argc, xt_value *argv);
41
+ xt_value xt_node_chmod(int32_t argc, xt_value *argv);
42
+ xt_value xt_node_chown(int32_t argc, xt_value *argv);
43
+ xt_value xt_node_lchmod(int32_t argc, xt_value *argv);
44
+ xt_value xt_node_lchown(int32_t argc, xt_value *argv);
45
+ xt_value xt_node_truncate(int32_t argc, xt_value *argv);
46
+ xt_value xt_node_utimes(int32_t argc, xt_value *argv);
47
+ xt_value xt_node_lutimes(int32_t argc, xt_value *argv);
48
+ xt_value xt_node_statfs(int32_t argc, xt_value *argv);
49
+ xt_value xt_node_mkdtemp(int32_t argc, xt_value *argv);
50
+
51
+ /* link_ops.c */
52
+ xt_value xt_node_link(int32_t argc, xt_value *argv);
53
+ xt_value xt_node_symlink(int32_t argc, xt_value *argv);
54
+ xt_value xt_node_readlink(int32_t argc, xt_value *argv);
55
+
56
+ /* dir.c */
57
+ xt_value xt_node_opendir(int32_t argc, xt_value *argv);
58
+
59
+ /* glob.c */
60
+ xt_value xt_node_glob(int32_t argc, xt_value *argv);
61
+
62
+ /* watch.c */
63
+ xt_value xt_node_watch(int32_t argc, xt_value *argv);
64
+ xt_value xt_node_watch_file(int32_t argc, xt_value *argv);
65
+ xt_value xt_node_unwatch_file(int32_t argc, xt_value *argv);
66
+
67
+ /* constants.c */
68
+ xt_value xt_fs_constants(void);
69
+ xt_value xt_fs_promises(void);
@@ -0,0 +1,47 @@
1
+ /* -- directory iteration -------------------------------------------------- */
2
+
3
+ #if defined(_WIN32)
4
+ /* Directory iteration backed by the CRT's _findfirst/_findnext. */
5
+ typedef struct {
6
+ intptr_t handle;
7
+ struct _finddata_t entry;
8
+ } xt_fs_dir;
9
+
10
+ static inline int xt_fs_dir_open(xt_fs_dir *dir, const char *path) {
11
+ size_t length = strlen(path);
12
+ char *pattern = (char *)malloc(length + 3);
13
+ if (!pattern) return 0;
14
+ memcpy(pattern, path, length);
15
+ pattern[length] = '/';
16
+ pattern[length + 1] = '*';
17
+ pattern[length + 2] = '\0';
18
+ dir->handle = _findfirst(pattern, &dir->entry);
19
+ free(pattern);
20
+ return dir->handle != -1;
21
+ }
22
+
23
+ static inline int xt_fs_dir_next(xt_fs_dir *dir) { return _findnext(dir->handle, &dir->entry) == 0; }
24
+ static inline const char *xt_fs_dir_name(xt_fs_dir *dir) { return dir->entry.name; }
25
+ static inline void xt_fs_dir_close(xt_fs_dir *dir) { _findclose(dir->handle); }
26
+ #else
27
+ #include <dirent.h>
28
+
29
+ typedef struct {
30
+ DIR *handle;
31
+ struct dirent *entry;
32
+ } xt_fs_dir;
33
+
34
+ static inline int xt_fs_dir_open(xt_fs_dir *dir, const char *path) {
35
+ dir->handle = opendir(path);
36
+ dir->entry = NULL;
37
+ return dir->handle != NULL;
38
+ }
39
+
40
+ static inline int xt_fs_dir_next(xt_fs_dir *dir) {
41
+ dir->entry = readdir(dir->handle);
42
+ return dir->entry != NULL;
43
+ }
44
+
45
+ static inline const char *xt_fs_dir_name(xt_fs_dir *dir) { return dir->entry->d_name; }
46
+ static inline void xt_fs_dir_close(xt_fs_dir *dir) { closedir(dir->handle); }
47
+ #endif