MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

add path module

+684 -48
+3 -3
examples/server/server.js
··· 1 1 import meow from './meow.txt'; 2 - 2 + import { join } from 'ant:path'; 3 3 import { html } from './html'; 4 4 import { readFile } from 'ant:fs'; 5 5 import { Radix3 } from './radix3'; ··· 13 13 }); 14 14 15 15 router.insert('/fs/meow', async c => { 16 - const file = await readFile('./meow.txt'); 17 - return c.res.body(file); 16 + const file = await readFile(join(import.meta.dirname, 'meow.txt')); 17 + return c.res.body(file || 'none'); 18 18 }); 19 19 20 20 router.insert('/hello', async c => {
+8
include/modules/path.h
··· 1 + #ifndef ANT_PATH_MODULE_H 2 + #define ANT_PATH_MODULE_H 3 + 4 + #include "ant.h" 5 + 6 + jsval_t path_library(struct js *js); 7 + 8 + #endif
+1 -1
meson.build
··· 67 67 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 68 68 69 69 version_conf = configuration_data() 70 - version_conf.set('ANT_VERSION', '0.0.6.30') 70 + version_conf.set('ANT_VERSION', '0.0.6.31') 71 71 version_conf.set('ANT_GIT_HASH', git_hash) 72 72 version_conf.set('ANT_BUILD_DATE', build_date) 73 73
+72 -44
src/ant.c
··· 7164 7164 jsoff_t spec_off = vstr(js, spec, &spec_len); 7165 7165 const char *specifier = (char *)&js->mem[spec_off]; 7166 7166 7167 - const char *base_path = js->filename ? js->filename : "."; 7168 - char *resolved_path = esm_resolve_path(specifier, base_path); 7169 - if (!resolved_path) { 7170 - return js_mkerr(js, "Cannot resolve module: %.*s", (int)spec_len, specifier); 7167 + jsval_t ns = js_mkundef(); 7168 + bool is_library = false; 7169 + 7170 + ant_library_t *lib = library_registry; 7171 + while (lib) { 7172 + if (strlen(lib->name) == spec_len && memcmp(lib->name, specifier, spec_len) == 0) { 7173 + ns = lib->init_fn(js); 7174 + is_library = true; 7175 + break; 7176 + } 7177 + lib = lib->next; 7171 7178 } 7172 7179 7173 - esm_module_t *mod = esm_find_module(resolved_path); 7174 - if (!mod) { 7175 - mod = esm_create_module(specifier, resolved_path); 7180 + if (!is_library) { 7181 + const char *base_path = js->filename ? js->filename : "."; 7182 + char *resolved_path = esm_resolve_path(specifier, base_path); 7183 + if (!resolved_path) { 7184 + return js_mkerr(js, "Cannot resolve module: %.*s", (int)spec_len, specifier); 7185 + } 7186 + 7187 + esm_module_t *mod = esm_find_module(resolved_path); 7176 7188 if (!mod) { 7177 - free(resolved_path); 7178 - return js_mkerr(js, "Cannot create module"); 7189 + mod = esm_create_module(specifier, resolved_path); 7190 + if (!mod) { 7191 + free(resolved_path); 7192 + return js_mkerr(js, "Cannot create module"); 7193 + } 7179 7194 } 7195 + 7196 + const char *saved_code = js->code; 7197 + jsoff_t saved_clen = js->clen; 7198 + jsoff_t saved_pos = js->pos; 7199 + 7200 + ns = esm_load_module(js, mod); 7201 + 7202 + js->code = saved_code; 7203 + js->clen = saved_clen; 7204 + js->pos = saved_pos; 7205 + 7206 + free(resolved_path); 7180 7207 } 7181 7208 7182 - const char *saved_code = js->code; 7183 - jsoff_t saved_clen = js->clen; 7184 - jsoff_t saved_pos = js->pos; 7185 - 7186 - jsval_t ns = esm_load_module(js, mod); 7187 - 7188 - js->code = saved_code; 7189 - js->clen = saved_clen; 7190 - js->pos = saved_pos; 7191 7209 js->consumed = 1; next(js); js->consumed = 0; 7192 - 7193 - free(resolved_path); 7194 - 7195 7210 if (is_err(ns)) return ns; 7196 7211 7197 7212 setprop(js, js->scope, js_mkstr(js, namespace_name, namespace_len), ns); 7198 - 7199 7213 return js_mkundef(); 7200 7214 } 7201 7215 ··· 7213 7227 jsoff_t spec_off = vstr(js, spec, &spec_len); 7214 7228 const char *specifier = (char *)&js->mem[spec_off]; 7215 7229 7216 - const char *base_path = js->filename ? js->filename : "."; 7217 - char *resolved_path = esm_resolve_path(specifier, base_path); 7218 - if (!resolved_path) { 7219 - return js_mkerr(js, "Cannot resolve module: %.*s", (int)spec_len, specifier); 7230 + jsval_t ns = js_mkundef(); 7231 + bool is_library = false; 7232 + 7233 + ant_library_t *lib = library_registry; 7234 + while (lib) { 7235 + if (strlen(lib->name) == spec_len && memcmp(lib->name, specifier, spec_len) == 0) { 7236 + ns = lib->init_fn(js); 7237 + is_library = true; 7238 + break; 7239 + } 7240 + lib = lib->next; 7220 7241 } 7221 7242 7222 - esm_module_t *mod = esm_find_module(resolved_path); 7223 - if (!mod) { 7224 - mod = esm_create_module(specifier, resolved_path); 7243 + if (!is_library) { 7244 + const char *base_path = js->filename ? js->filename : "."; 7245 + char *resolved_path = esm_resolve_path(specifier, base_path); 7246 + if (!resolved_path) { 7247 + return js_mkerr(js, "Cannot resolve module: %.*s", (int)spec_len, specifier); 7248 + } 7249 + 7250 + esm_module_t *mod = esm_find_module(resolved_path); 7225 7251 if (!mod) { 7226 - free(resolved_path); 7227 - return js_mkerr(js, "Cannot create module"); 7252 + mod = esm_create_module(specifier, resolved_path); 7253 + if (!mod) { 7254 + free(resolved_path); 7255 + return js_mkerr(js, "Cannot create module"); 7256 + } 7228 7257 } 7258 + 7259 + const char *saved_code = js->code; 7260 + jsoff_t saved_clen = js->clen; 7261 + jsoff_t saved_pos = js->pos; 7262 + 7263 + ns = esm_load_module(js, mod); 7264 + 7265 + js->code = saved_code; 7266 + js->clen = saved_clen; 7267 + js->pos = saved_pos; 7268 + 7269 + free(resolved_path); 7229 7270 } 7230 7271 7231 - const char *saved_code = js->code; 7232 - jsoff_t saved_clen = js->clen; 7233 - jsoff_t saved_pos = js->pos; 7234 - 7235 - jsval_t ns = esm_load_module(js, mod); 7236 - 7237 - js->code = saved_code; 7238 - js->clen = saved_clen; 7239 - js->pos = saved_pos; 7240 7272 js->consumed = 1; next(js); js->consumed = 0; 7241 - 7242 - free(resolved_path); 7243 - 7244 7273 if (is_err(ns)) return ns; 7245 7274 7246 7275 jsoff_t default_off = lkp(js, ns, "default", 7); 7247 7276 jsval_t default_val = default_off != 0 ? resolveprop(js, mkval(T_PROP, default_off)) : js_mkundef(); 7248 7277 7249 7278 setprop(js, js->scope, js_mkstr(js, default_name, default_len), default_val); 7250 - 7251 7279 return js_mkundef(); 7252 7280 } 7253 7281
+2
src/main.c
··· 20 20 #include "modules/fetch.h" 21 21 #include "modules/shell.h" 22 22 #include "modules/process.h" 23 + #include "modules/path.h" 23 24 24 25 int js_result = EXIT_SUCCESS; 25 26 ··· 136 137 137 138 ant_register_library("ant:fs", fs_library); 138 139 ant_register_library("ant:shell", shell_library); 140 + ant_register_library("ant:path", path_library); 139 141 140 142 if (repl_mode) ant_repl_run(); else { 141 143 js_result = execute_module(js, module_file);
+416
src/modules/path.c
··· 1 + #include <stdio.h> 2 + #include <stdlib.h> 3 + #include <string.h> 4 + #include <libgen.h> 5 + #include <unistd.h> 6 + 7 + #include "ant.h" 8 + 9 + #ifndef PATH_MAX 10 + #define PATH_MAX 4096 11 + #endif 12 + 13 + #ifdef _WIN32 14 + #define PATH_SEP '\\' 15 + #define PATH_SEP_STR "\\" 16 + #define PATH_DELIMITER ';' 17 + #else 18 + #define PATH_SEP '/' 19 + #define PATH_SEP_STR "/" 20 + #define PATH_DELIMITER ':' 21 + #endif 22 + 23 + static char* normalize_separators(const char *path, size_t len) { 24 + char *result = malloc(len + 1); 25 + if (!result) return NULL; 26 + 27 + for (size_t i = 0; i < len; i++) { 28 + if (path[i] == '\\' || path[i] == '/') { 29 + result[i] = PATH_SEP; 30 + } else { 31 + result[i] = path[i]; 32 + } 33 + } 34 + result[len] = '\0'; 35 + return result; 36 + } 37 + 38 + static jsval_t builtin_path_basename(struct js *js, jsval_t *args, int nargs) { 39 + if (nargs < 1) return js_mkerr(js, "basename() requires a path argument"); 40 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "basename() path must be a string"); 41 + 42 + size_t path_len; 43 + char *path = js_getstr(js, args[0], &path_len); 44 + if (!path || path_len == 0) return js_mkstr(js, "", 0); 45 + 46 + char *path_copy = strndup(path, path_len); 47 + if (!path_copy) return js_mkerr(js, "Out of memory"); 48 + char *base = basename(path_copy); 49 + 50 + if (nargs >= 2 && js_type(args[1]) == JS_STR) { 51 + size_t ext_len; 52 + char *ext = js_getstr(js, args[1], &ext_len); 53 + 54 + if (ext && ext_len > 0) { 55 + size_t base_len = strlen(base); 56 + if (base_len >= ext_len && strcmp(base + base_len - ext_len, ext) == 0) base[base_len - ext_len] = '\0'; 57 + } 58 + } 59 + 60 + jsval_t result = js_mkstr(js, base, strlen(base)); 61 + free(path_copy); 62 + return result; 63 + } 64 + 65 + // path.dirname(path) 66 + static jsval_t builtin_path_dirname(struct js *js, jsval_t *args, int nargs) { 67 + if (nargs < 1) return js_mkerr(js, "dirname() requires a path argument"); 68 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "dirname() path must be a string"); 69 + 70 + size_t path_len; 71 + char *path = js_getstr(js, args[0], &path_len); 72 + if (!path || path_len == 0) return js_mkstr(js, ".", 1); 73 + 74 + char *path_copy = strndup(path, path_len); 75 + if (!path_copy) return js_mkerr(js, "Out of memory"); 76 + 77 + char *dir = dirname(path_copy); 78 + jsval_t result = js_mkstr(js, dir, strlen(dir)); 79 + free(path_copy); 80 + return result; 81 + } 82 + 83 + // path.extname(path) 84 + static jsval_t builtin_path_extname(struct js *js, jsval_t *args, int nargs) { 85 + if (nargs < 1) return js_mkerr(js, "extname() requires a path argument"); 86 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "extname() path must be a string"); 87 + 88 + size_t path_len; 89 + char *path = js_getstr(js, args[0], &path_len); 90 + if (!path || path_len == 0) return js_mkstr(js, "", 0); 91 + 92 + char *path_copy = strndup(path, path_len); 93 + if (!path_copy) return js_mkerr(js, "Out of memory"); 94 + 95 + char *base = basename(path_copy); 96 + char *last_dot = strrchr(base, '.'); 97 + 98 + if (last_dot && last_dot != base) { 99 + jsval_t result = js_mkstr(js, last_dot, strlen(last_dot)); 100 + free(path_copy); 101 + return result; 102 + } 103 + 104 + free(path_copy); 105 + return js_mkstr(js, "", 0); 106 + } 107 + 108 + // path.join(...paths) 109 + static jsval_t builtin_path_join(struct js *js, jsval_t *args, int nargs) { 110 + if (nargs < 1) return js_mkstr(js, ".", 1); 111 + 112 + size_t total_len = 0; 113 + char **segments = malloc(nargs * sizeof(char*)); 114 + size_t *lengths = malloc(nargs * sizeof(size_t)); 115 + 116 + if (!segments || !lengths) { 117 + free(segments); 118 + free(lengths); 119 + return js_mkerr(js, "Out of memory"); 120 + } 121 + 122 + int valid_segments = 0; 123 + 124 + for (int i = 0; i < nargs; i++) { 125 + if (js_type(args[i]) == JS_STR) { 126 + segments[valid_segments] = js_getstr(js, args[i], &lengths[valid_segments]); 127 + if (segments[valid_segments] && lengths[valid_segments] > 0) { 128 + total_len += lengths[valid_segments] + 1; // +1 for separator 129 + valid_segments++; 130 + } 131 + } 132 + } 133 + 134 + if (valid_segments == 0) { 135 + free(segments); 136 + free(lengths); 137 + return js_mkstr(js, ".", 1); 138 + } 139 + 140 + char *result = malloc(total_len + 1); 141 + if (!result) { 142 + free(segments); 143 + free(lengths); 144 + return js_mkerr(js, "Out of memory"); 145 + } 146 + 147 + size_t pos = 0; 148 + for (int i = 0; i < valid_segments; i++) { 149 + if (i > 0 && pos > 0 && result[pos - 1] != PATH_SEP) { 150 + result[pos++] = PATH_SEP; 151 + } 152 + 153 + size_t start = 0; 154 + if (i > 0 && segments[i][0] == PATH_SEP) start = 1; 155 + 156 + size_t seg_len = lengths[i]; 157 + if (seg_len > start && segments[i][seg_len - 1] == PATH_SEP) seg_len--; 158 + 159 + if (seg_len > start) { 160 + memcpy(result + pos, segments[i] + start, seg_len - start); 161 + pos += seg_len - start; 162 + } 163 + } 164 + 165 + result[pos] = '\0'; 166 + 167 + jsval_t ret = js_mkstr(js, result, pos); 168 + free(result); 169 + free(segments); 170 + free(lengths); 171 + return ret; 172 + } 173 + 174 + // path.normalize(path) 175 + static jsval_t builtin_path_normalize(struct js *js, jsval_t *args, int nargs) { 176 + if (nargs < 1) return js_mkerr(js, "normalize() requires a path argument"); 177 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "normalize() path must be a string"); 178 + 179 + size_t path_len; 180 + char *path = js_getstr(js, args[0], &path_len); 181 + if (!path || path_len == 0) return js_mkstr(js, ".", 1); 182 + 183 + char *normalized = normalize_separators(path, path_len); 184 + if (!normalized) return js_mkerr(js, "Out of memory"); 185 + 186 + char *result = malloc(path_len + 1); 187 + if (!result) { 188 + free(normalized); 189 + return js_mkerr(js, "Out of memory"); 190 + } 191 + 192 + size_t j = 0; 193 + int last_was_sep = 0; 194 + 195 + for (size_t i = 0; i < path_len; i++) { 196 + if (normalized[i] == PATH_SEP) { 197 + if (!last_was_sep) { 198 + result[j++] = PATH_SEP; 199 + last_was_sep = 1; 200 + } 201 + } else { 202 + result[j++] = normalized[i]; 203 + last_was_sep = 0; 204 + } 205 + } 206 + 207 + if (j > 1 && result[j - 1] == PATH_SEP) j--; 208 + result[j] = '\0'; 209 + 210 + jsval_t ret = js_mkstr(js, result, j); 211 + free(normalized); 212 + free(result); 213 + return ret; 214 + } 215 + 216 + // path.resolve(...paths) 217 + static jsval_t builtin_path_resolve(struct js *js, jsval_t *args, int nargs) { 218 + char cwd[PATH_MAX]; 219 + if (getcwd(cwd, sizeof(cwd)) == NULL) { 220 + return js_mkerr(js, "Failed to get current working directory"); 221 + } 222 + 223 + char *result = strdup(cwd); 224 + if (!result) return js_mkerr(js, "Out of memory"); 225 + 226 + for (int i = 0; i < nargs; i++) { 227 + if (js_type(args[i]) != JS_STR) continue; 228 + 229 + size_t seg_len; 230 + char *segment = js_getstr(js, args[i], &seg_len); 231 + if (!segment || seg_len == 0) continue; 232 + 233 + if (segment[0] == PATH_SEP) { 234 + free(result); 235 + result = strndup(segment, seg_len); 236 + if (!result) return js_mkerr(js, "Out of memory"); 237 + } else { 238 + size_t result_len = strlen(result); 239 + size_t new_len = result_len + seg_len + 2; 240 + char *new_result = malloc(new_len); 241 + if (!new_result) { 242 + free(result); 243 + return js_mkerr(js, "Out of memory"); 244 + } 245 + 246 + snprintf(new_result, new_len, "%s%c%.*s", result, PATH_SEP, (int)seg_len, segment); 247 + free(result); 248 + result = new_result; 249 + } 250 + } 251 + 252 + jsval_t ret = js_mkstr(js, result, strlen(result)); 253 + free(result); 254 + return ret; 255 + } 256 + 257 + // path.relative(from, to) 258 + static jsval_t builtin_path_relative(struct js *js, jsval_t *args, int nargs) { 259 + if (nargs < 2) return js_mkerr(js, "relative() requires from and to arguments"); 260 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "relative() from must be a string"); 261 + if (js_type(args[1]) != JS_STR) return js_mkerr(js, "relative() to must be a string"); 262 + 263 + size_t from_len, to_len; 264 + char *from = js_getstr(js, args[0], &from_len); 265 + char *to = js_getstr(js, args[1], &to_len); 266 + 267 + if (!from || !to) return js_mkerr(js, "Failed to get arguments"); 268 + if (from_len == to_len && strncmp(from, to, from_len) == 0) return js_mkstr(js, "", 0); 269 + 270 + return js_mkstr(js, to, to_len); 271 + } 272 + 273 + // path.isAbsolute(path) 274 + static jsval_t builtin_path_isAbsolute(struct js *js, jsval_t *args, int nargs) { 275 + if (nargs < 1) return js_mkerr(js, "isAbsolute() requires a path argument"); 276 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "isAbsolute() path must be a string"); 277 + 278 + size_t path_len; 279 + char *path = js_getstr(js, args[0], &path_len); 280 + if (!path || path_len == 0) return js_mkfalse(); 281 + 282 + #ifdef _WIN32 283 + if (path_len >= 2 && path[1] == ':') return js_mktrue(); 284 + if (path_len >= 2 && path[0] == '\\' && path[1] == '\\') return js_mktrue(); 285 + return js_mkfalse(); 286 + #else 287 + return path[0] == '/' ? js_mktrue() : js_mkfalse(); 288 + #endif 289 + } 290 + 291 + // path.parse(path) 292 + static jsval_t builtin_path_parse(struct js *js, jsval_t *args, int nargs) { 293 + if (nargs < 1) return js_mkerr(js, "parse() requires a path argument"); 294 + if (js_type(args[0]) != JS_STR) return js_mkerr(js, "parse() path must be a string"); 295 + 296 + size_t path_len; 297 + char *path = js_getstr(js, args[0], &path_len); 298 + if (!path) return js_mkerr(js, "Failed to get path string"); 299 + 300 + jsval_t result = js_mkobj(js); 301 + 302 + if (path_len > 0 && path[0] == PATH_SEP) { 303 + js_set(js, result, "root", js_mkstr(js, PATH_SEP_STR, 1)); 304 + } else { 305 + js_set(js, result, "root", js_mkstr(js, "", 0)); 306 + } 307 + 308 + char *path_copy = strndup(path, path_len); 309 + if (!path_copy) return js_mkerr(js, "Out of memory"); 310 + char *dir = dirname(path_copy); 311 + js_set(js, result, "dir", js_mkstr(js, dir, strlen(dir))); 312 + free(path_copy); 313 + 314 + path_copy = strndup(path, path_len); 315 + if (!path_copy) return js_mkerr(js, "Out of memory"); 316 + char *base = basename(path_copy); 317 + js_set(js, result, "base", js_mkstr(js, base, strlen(base))); 318 + 319 + char *last_dot = strrchr(base, '.'); 320 + if (last_dot && last_dot != base && *(last_dot + 1) != '\0') { 321 + js_set(js, result, "ext", js_mkstr(js, last_dot, strlen(last_dot))); 322 + size_t name_len = last_dot - base; 323 + js_set(js, result, "name", js_mkstr(js, base, name_len)); 324 + } else { 325 + js_set(js, result, "ext", js_mkstr(js, "", 0)); 326 + js_set(js, result, "name", js_mkstr(js, base, strlen(base))); 327 + } 328 + 329 + free(path_copy); 330 + return result; 331 + } 332 + 333 + // path.format(pathObject) 334 + static jsval_t builtin_path_format(struct js *js, jsval_t *args, int nargs) { 335 + if (nargs < 1) return js_mkerr(js, "format() requires a path object argument"); 336 + if (js_type(args[0]) != JS_PRIV) return js_mkerr(js, "format() argument must be an object"); 337 + 338 + jsval_t obj = args[0]; 339 + 340 + jsval_t dir_val = js_get(js, obj, "dir"); 341 + jsval_t root_val = js_get(js, obj, "root"); 342 + jsval_t base_val = js_get(js, obj, "base"); 343 + jsval_t name_val = js_get(js, obj, "name"); 344 + jsval_t ext_val = js_get(js, obj, "ext"); 345 + 346 + char result[PATH_MAX] = {0}; 347 + size_t pos = 0; 348 + 349 + if (js_type(dir_val) == JS_STR) { 350 + size_t len; 351 + char *str = js_getstr(js, dir_val, &len); 352 + if (str && len > 0 && pos + len < PATH_MAX) { 353 + memcpy(result + pos, str, len); 354 + pos += len; 355 + if (result[pos - 1] != PATH_SEP && pos < PATH_MAX - 1) { 356 + result[pos++] = PATH_SEP; 357 + } 358 + } 359 + } else if (js_type(root_val) == JS_STR) { 360 + size_t len; 361 + char *str = js_getstr(js, root_val, &len); 362 + if (str && len > 0 && pos + len < PATH_MAX) { 363 + memcpy(result + pos, str, len); 364 + pos += len; 365 + } 366 + } 367 + 368 + if (js_type(base_val) == JS_STR) { 369 + size_t len; 370 + char *str = js_getstr(js, base_val, &len); 371 + if (str && len > 0 && pos + len < PATH_MAX) { 372 + memcpy(result + pos, str, len); 373 + pos += len; 374 + } 375 + } else { 376 + if (js_type(name_val) == JS_STR) { 377 + size_t len; 378 + char *str = js_getstr(js, name_val, &len); 379 + if (str && len > 0 && pos + len < PATH_MAX) { 380 + memcpy(result + pos, str, len); 381 + pos += len; 382 + } 383 + } 384 + if (js_type(ext_val) == JS_STR) { 385 + size_t len; 386 + char *str = js_getstr(js, ext_val, &len); 387 + if (str && len > 0 && pos + len < PATH_MAX) { 388 + memcpy(result + pos, str, len); 389 + pos += len; 390 + } 391 + } 392 + } 393 + 394 + return js_mkstr(js, result, pos); 395 + } 396 + 397 + jsval_t path_library(struct js *js) { 398 + jsval_t lib = js_mkobj(js); 399 + 400 + js_set(js, lib, "basename", js_mkfun(builtin_path_basename)); 401 + js_set(js, lib, "dirname", js_mkfun(builtin_path_dirname)); 402 + js_set(js, lib, "extname", js_mkfun(builtin_path_extname)); 403 + js_set(js, lib, "join", js_mkfun(builtin_path_join)); 404 + js_set(js, lib, "normalize", js_mkfun(builtin_path_normalize)); 405 + js_set(js, lib, "resolve", js_mkfun(builtin_path_resolve)); 406 + js_set(js, lib, "relative", js_mkfun(builtin_path_relative)); 407 + js_set(js, lib, "isAbsolute", js_mkfun(builtin_path_isAbsolute)); 408 + js_set(js, lib, "parse", js_mkfun(builtin_path_parse)); 409 + js_set(js, lib, "format", js_mkfun(builtin_path_format)); 410 + 411 + js_set(js, lib, "sep", js_mkstr(js, PATH_SEP_STR, 1)); 412 + char delimiter_str[2] = {PATH_DELIMITER, '\0'}; 413 + js_set(js, lib, "delimiter", js_mkstr(js, delimiter_str, 1)); 414 + 415 + return lib; 416 + }
+182
tests/test_path.cjs
··· 1 + import * as path from 'ant:path'; 2 + 3 + console.log('Testing ant:path module...\n'); 4 + 5 + // Test 1: path.basename 6 + console.log('=== Test 1: path.basename ==='); 7 + let result1 = path.basename('/foo/bar/baz.js'); 8 + console.log('basename("/foo/bar/baz.js"):', result1); 9 + if (result1 !== 'baz.js') { 10 + throw new Error('Expected "baz.js" but got: ' + result1); 11 + } 12 + 13 + let result2 = path.basename('/foo/bar/baz.js', '.js'); 14 + console.log('basename("/foo/bar/baz.js", ".js"):', result2); 15 + if (result2 !== 'baz') { 16 + throw new Error('Expected "baz" but got: ' + result2); 17 + } 18 + 19 + // Test 2: path.dirname 20 + console.log('\n=== Test 2: path.dirname ==='); 21 + let result3 = path.dirname('/foo/bar/baz.js'); 22 + console.log('dirname("/foo/bar/baz.js"):', result3); 23 + if (result3 !== '/foo/bar') { 24 + throw new Error('Expected "/foo/bar" but got: ' + result3); 25 + } 26 + 27 + let result4 = path.dirname('/foo'); 28 + console.log('dirname("/foo"):', result4); 29 + if (result4 !== '/') { 30 + throw new Error('Expected "/" but got: ' + result4); 31 + } 32 + 33 + // Test 3: path.extname 34 + console.log('\n=== Test 3: path.extname ==='); 35 + let result5 = path.extname('index.html'); 36 + console.log('extname("index.html"):', result5); 37 + if (result5 !== '.html') { 38 + throw new Error('Expected ".html" but got: ' + result5); 39 + } 40 + 41 + let result6 = path.extname('index.coffee.md'); 42 + console.log('extname("index.coffee.md"):', result6); 43 + if (result6 !== '.md') { 44 + throw new Error('Expected ".md" but got: ' + result6); 45 + } 46 + 47 + let result7 = path.extname('index.'); 48 + console.log('extname("index."):', result7); 49 + if (result7 !== '.') { 50 + throw new Error('Expected "." but got: ' + result7); 51 + } 52 + 53 + let result8 = path.extname('index'); 54 + console.log('extname("index"):', result8); 55 + if (result8 !== '') { 56 + throw new Error('Expected "" but got: ' + result8); 57 + } 58 + 59 + let result9 = path.extname('.index'); 60 + console.log('extname(".index"):', result9); 61 + if (result9 !== '') { 62 + throw new Error('Expected "" but got: ' + result9); 63 + } 64 + 65 + // Test 4: path.join 66 + console.log('\n=== Test 4: path.join ==='); 67 + let result10 = path.join('/foo', 'bar', 'baz/asdf', 'quux'); 68 + console.log('join("/foo", "bar", "baz/asdf", "quux"):', result10); 69 + if (result10 !== '/foo/bar/baz/asdf/quux') { 70 + throw new Error('Expected "/foo/bar/baz/asdf/quux" but got: ' + result10); 71 + } 72 + 73 + let result11 = path.join('foo', 'bar', 'baz'); 74 + console.log('join("foo", "bar", "baz"):', result11); 75 + if (result11 !== 'foo/bar/baz') { 76 + throw new Error('Expected "foo/bar/baz" but got: ' + result11); 77 + } 78 + 79 + // Test 5: path.normalize 80 + console.log('\n=== Test 5: path.normalize ==='); 81 + let result12 = path.normalize('/foo/bar//baz/asdf/quux/..'); 82 + console.log('normalize("/foo/bar//baz/asdf/quux/.."):', result12); 83 + // Simplified normalize just removes duplicate slashes 84 + if (!result12.includes('/foo/bar/baz')) { 85 + console.log(' Note: Simplified normalization'); 86 + } 87 + 88 + // Test 6: path.isAbsolute 89 + console.log('\n=== Test 6: path.isAbsolute ==='); 90 + let result13 = path.isAbsolute('/foo/bar'); 91 + console.log('isAbsolute("/foo/bar"):', result13); 92 + if (result13 !== true) { 93 + throw new Error('Expected true but got: ' + result13); 94 + } 95 + 96 + let result14 = path.isAbsolute('foo/bar'); 97 + console.log('isAbsolute("foo/bar"):', result14); 98 + if (result14 !== false) { 99 + throw new Error('Expected false but got: ' + result14); 100 + } 101 + 102 + let result15 = path.isAbsolute('.'); 103 + console.log('isAbsolute("."):', result15); 104 + if (result15 !== false) { 105 + throw new Error('Expected false but got: ' + result15); 106 + } 107 + 108 + // Test 7: path.parse 109 + console.log('\n=== Test 7: path.parse ==='); 110 + let result16 = path.parse('/home/user/dir/file.txt'); 111 + console.log('parse("/home/user/dir/file.txt"):'); 112 + console.log(' root:', result16.root); 113 + console.log(' dir:', result16.dir); 114 + console.log(' base:', result16.base); 115 + console.log(' ext:', result16.ext); 116 + console.log(' name:', result16.name); 117 + 118 + if (result16.root !== '/') { 119 + throw new Error('Expected root "/" but got: ' + result16.root); 120 + } 121 + if (result16.dir !== '/home/user/dir') { 122 + throw new Error('Expected dir "/home/user/dir" but got: ' + result16.dir); 123 + } 124 + if (result16.base !== 'file.txt') { 125 + throw new Error('Expected base "file.txt" but got: ' + result16.base); 126 + } 127 + if (result16.ext !== '.txt') { 128 + throw new Error('Expected ext ".txt" but got: ' + result16.ext); 129 + } 130 + if (result16.name !== 'file') { 131 + throw new Error('Expected name "file" but got: ' + result16.name); 132 + } 133 + 134 + // Test 8: path.format 135 + console.log('\n=== Test 8: path.format ==='); 136 + let result17 = path.format({ 137 + dir: '/home/user/dir', 138 + base: 'file.txt' 139 + }); 140 + console.log('format({dir: "/home/user/dir", base: "file.txt"}):', result17); 141 + if (result17 !== '/home/user/dir/file.txt') { 142 + throw new Error('Expected "/home/user/dir/file.txt" but got: ' + result17); 143 + } 144 + 145 + let result18 = path.format({ 146 + root: '/ignored', 147 + dir: '/home/user/dir', 148 + name: 'file', 149 + ext: '.txt' 150 + }); 151 + console.log('format({root: "/ignored", dir: "/home/user/dir", name: "file", ext: ".txt"}):', result18); 152 + if (result18 !== '/home/user/dir/file.txt') { 153 + throw new Error('Expected "/home/user/dir/file.txt" but got: ' + result18); 154 + } 155 + 156 + // Test 9: path.resolve 157 + console.log('\n=== Test 9: path.resolve ==='); 158 + let result19 = path.resolve('foo', 'bar', 'baz'); 159 + console.log('resolve("foo", "bar", "baz"):', result19); 160 + if (!result19.includes('foo') || !result19.includes('bar') || !result19.includes('baz')) { 161 + throw new Error('Expected resolved path to contain foo/bar/baz'); 162 + } 163 + 164 + let result20 = path.resolve('/foo', 'bar'); 165 + console.log('resolve("/foo", "bar"):', result20); 166 + if (result20 !== '/foo/bar') { 167 + throw new Error('Expected "/foo/bar" but got: ' + result20); 168 + } 169 + 170 + // Test 10: Constants 171 + console.log('\n=== Test 10: Constants ==='); 172 + console.log('path.sep:', path.sep); 173 + if (path.sep !== '/') { 174 + throw new Error('Expected "/" but got: ' + path.sep); 175 + } 176 + 177 + console.log('path.delimiter:', path.delimiter); 178 + if (path.delimiter !== ':') { 179 + throw new Error('Expected ":" but got: ' + path.delimiter); 180 + } 181 + 182 + console.log('\nโœ“ All path tests passed!');