diff --git a/docs/content/docs/limitations.mdx b/docs/content/docs/limitations.mdx index f38159f35..f8e2c0f1c 100644 --- a/docs/content/docs/limitations.mdx +++ b/docs/content/docs/limitations.mdx @@ -252,7 +252,7 @@ Use [Native FFI](/docs/ffi#replacing-a-node-api-addon) to call a plain C ABI fun The `wasm32-wasi` executable target supports async/await, promises, generators, timers, portable event-loop work, stdin/readline, filesystem callbacks and promises. -WASI Preview 1 does not provide sockets, process spawning, OS signals, network interfaces, or filesystem notifications. Networking/fetch, child processes, signal APIs, `os.networkInterfaces()`, and `fs.watch` are rejected before linking with `SC3002`. `--sanitize` and native FFI are unavailable. +WASI Preview 1 does not provide sockets, process spawning, OS signals, network interfaces, or filesystem notifications. Networking/fetch, child processes, signal APIs, `os.networkInterfaces()`, the `os` host facts without a WASI equivalent (`cpus()`, `hostname()`, `freemem()`, `loadavg()`, `uptime()`, `getPriority()`), and `fs.watch` are rejected before linking with `SC3002`. `--sanitize` and native FFI are unavailable. Library mode emits an async-free Wasm reactor with named host imports. Native runtime localization and thread instances are unsupported. Each Wasm instance owns independent state. Filesystem access is limited to directories opened by the host; `scriptc run` exposes the current working directory and `/tmp`. See [Platform Support](/docs/platforms) for build and run details. diff --git a/docs/content/docs/platforms.mdx b/docs/content/docs/platforms.mdx index 71c4c4d07..b4f817670 100644 --- a/docs/content/docs/platforms.mdx +++ b/docs/content/docs/platforms.mdx @@ -79,7 +79,7 @@ hello, world Without `-o`, the module is written to `.scriptc/hello.wasm`. `scriptc run` runs it with Node.js's WASI implementation, so it needs Node.js 24 or later on your `PATH`. It passes through stdio and environment variables, makes the current directory available as `/`, and maps the host's temporary directory to `/tmp`. You can run a built module in any other WASI Preview 1 runtime too. -WASI modules support the same language features as native executables, including async functions, promises, generators, timers, stdin and readline, and filesystem callbacks and promises. WASI Preview 1 has no sockets, process spawning, signals, network interfaces, or file watching, so networking and `fetch`, child processes, signal APIs, `os.networkInterfaces()`, and `fs.watch` fail the build with `SC3002`. `--sanitize` and native FFI aren't available for WASI. +WASI modules support the same language features as native executables, including async functions, promises, generators, timers, stdin and readline, and filesystem callbacks and promises. WASI Preview 1 has no sockets, process spawning, signals, network interfaces, or file watching, so networking and `fetch`, child processes, signal APIs, `os.networkInterfaces()`, the `os` host facts without a WASI equivalent (`cpus()`, `hostname()`, `freemem()`, `loadavg()`, `uptime()`, `getPriority()`), and `fs.watch` fail the build with `SC3002`. `--sanitize` and native FFI aren't available for WASI. To build a module that a web or native application calls into, see [WebAssembly Modules](/docs/wasm). diff --git a/docs/src/generated/node-v24-compatibility-meta.json b/docs/src/generated/node-v24-compatibility-meta.json index 2e07a9891..4276802cd 100644 --- a/docs/src/generated/node-v24-compatibility-meta.json +++ b/docs/src/generated/node-v24-compatibility-meta.json @@ -2,6 +2,6 @@ "schemaVersion": 3, "nodeVersion": "24.15.0", "nodeCommit": "848430679556aed0bd073f2bc263331ad84fa119", - "artifactVersion": "a83d6e1dfee84eea66b5", + "artifactVersion": "d94b8161bbee649b9890", "rowCount": 3662 } diff --git a/docs/src/generated/node-v24-compatibility.json b/docs/src/generated/node-v24-compatibility.json index f556680cc..7f62476e4 100644 --- a/docs/src/generated/node-v24-compatibility.json +++ b/docs/src/generated/node-v24-compatibility.json @@ -494,9 +494,9 @@ "apiEntries": 24, "static": { "supported": 0, - "partial": 11, + "partial": 23, "refused": 0, - "not-implemented": 13, + "not-implemented": 1, "by-design": 0, "unreviewed": 0, "not-applicable": 0 @@ -509,9 +509,9 @@ "apiEntries": 17, "static": { "supported": 0, - "partial": 14, + "partial": 16, "refused": 0, - "not-implemented": 3, + "not-implemented": 1, "by-design": 0, "unreviewed": 0, "not-applicable": 0 @@ -49456,9 +49456,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49479,9 +49479,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49502,9 +49502,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49525,9 +49525,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49548,9 +49548,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49594,9 +49594,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49617,9 +49617,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49640,9 +49640,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49824,9 +49824,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49870,9 +49870,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49916,9 +49916,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -49939,9 +49939,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -50054,9 +50054,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -50169,9 +50169,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { diff --git a/internal/compatibility/generated/node-v24-backlog.json b/internal/compatibility/generated/node-v24-backlog.json index 85f48d094..55c256e1f 100644 --- a/internal/compatibility/generated/node-v24-backlog.json +++ b/internal/compatibility/generated/node-v24-backlog.json @@ -8,8 +8,8 @@ "tiers": { "static": { "replace-refusal": 40, - "verify-gap": 2398, - "audit-partial": 768, + "verify-gap": 2384, + "audit-partial": 782, "classify": 2, "implement": 80 } @@ -48814,12 +48814,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.arch", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -48839,12 +48841,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.cpus", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -48864,12 +48868,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.endianness", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -48889,12 +48895,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.freemem", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -48914,12 +48922,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.getPriority", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -48967,12 +48977,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.hostname", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -48992,12 +49004,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.loadavg", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -49017,12 +49031,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.machine", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -49235,12 +49251,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.uptime", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -49288,12 +49306,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.version", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -49341,12 +49361,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.constants", + "tests": [ + "tests/corpus/5141-os-constants.ts" + ] } } }, @@ -49366,12 +49388,14 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:os", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.os.devNull", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] } } }, @@ -49484,12 +49508,15 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:path", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.path.format", + "tests": [ + "tests/corpus/5142-path-parse-format.ts", + "packages/runtime/test/path.test.ts" + ] } } }, @@ -49627,12 +49654,15 @@ "priority": "high", "tiers": { "static": { - "status": "not-implemented", - "action": "verify-gap", - "verification": "registry-gap", - "confidence": "low", - "source": "compiler-unmatched:path", - "tests": [] + "status": "partial", + "action": "audit-partial", + "verification": "test-backed", + "confidence": "high", + "source": "surface-manifest:node-builtin.path.parse", + "tests": [ + "tests/corpus/5142-path-parse-format.ts", + "packages/runtime/test/path.test.ts" + ] } } }, diff --git a/internal/compatibility/generated/node-v24-internal.json b/internal/compatibility/generated/node-v24-internal.json index 66c8fcfea..600d7a1db 100644 --- a/internal/compatibility/generated/node-v24-internal.json +++ b/internal/compatibility/generated/node-v24-internal.json @@ -521,9 +521,9 @@ "apiEntries": 24, "static": { "supported": 0, - "partial": 11, + "partial": 23, "refused": 0, - "not-implemented": 13, + "not-implemented": 1, "by-design": 0, "unreviewed": 0, "not-applicable": 0 @@ -536,9 +536,9 @@ "apiEntries": 17, "static": { "supported": 0, - "partial": 14, + "partial": 16, "refused": 0, - "not-implemented": 3, + "not-implemented": 1, "by-design": 0, "unreviewed": 0, "not-applicable": 0 @@ -68631,7 +68631,9 @@ "tests": [ "tests/corpus/1480-os-network-interfaces.ts", "tests/corpus/2917-builtin-callable-widths.ts", - "tests/corpus/4598-os-available-parallelism.ts" + "tests/corpus/4598-os-available-parallelism.ts", + "tests/corpus/5140-os-host-facts.ts", + "tests/corpus/5141-os-constants.ts" ] }, "anchorSource": "chapter" @@ -68864,8 +68866,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.arch", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -68887,8 +68892,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.cpus", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -68910,8 +68918,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.endianness", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -68933,8 +68944,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.freemem", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -68956,8 +68970,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.getPriority", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -69006,8 +69023,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.hostname", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -69029,8 +69049,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.loadavg", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -69052,8 +69075,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.machine", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -69260,8 +69286,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.uptime", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -69310,8 +69339,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.version", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "exact" }, @@ -69360,8 +69392,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.constants", + "tests": [ + "tests/corpus/5141-os-constants.ts" + ] }, "anchorSource": "chapter" }, @@ -69383,8 +69418,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:os" + "status": "partial", + "evidence": "surface-manifest:node-builtin.os.devNull", + "tests": [ + "tests/corpus/5140-os-host-facts.ts" + ] }, "anchorSource": "chapter" }, @@ -69409,10 +69447,12 @@ "status": "partial", "evidence": "derived:descendants", "tests": [ + "packages/runtime/test/path.test.ts", "tests/corpus/2915-path-function-values.ts", "tests/corpus/2916-path-function-values-cjs.ts", "tests/corpus/2917-builtin-callable-widths.ts", "tests/corpus/2918-builtin-callable-widths-cjs.ts", + "tests/corpus/5142-path-parse-format.ts", "tests/corpus/957-builtins-namespace.ts" ] }, @@ -69549,8 +69589,12 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:path" + "status": "partial", + "evidence": "surface-manifest:node-builtin.path.format", + "tests": [ + "tests/corpus/5142-path-parse-format.ts", + "packages/runtime/test/path.test.ts" + ] }, "anchorSource": "exact" }, @@ -69685,8 +69729,12 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:path" + "status": "partial", + "evidence": "surface-manifest:node-builtin.path.parse", + "tests": [ + "tests/corpus/5142-path-parse-format.ts", + "packages/runtime/test/path.test.ts" + ] }, "anchorSource": "exact" }, diff --git a/internal/compatibility/static-support.json b/internal/compatibility/static-support.json index 7376b475d..8a1969d6f 100644 --- a/internal/compatibility/static-support.json +++ b/internal/compatibility/static-support.json @@ -81,7 +81,25 @@ "node-builtin.net": ["tests/corpus/2500-net-autosel-timeout.ts", "tests/corpus/2596-net-arg-ladders.cjs"], "node-builtin.os": ["tests/corpus/1480-os-network-interfaces.ts", "tests/corpus/2917-builtin-callable-widths.ts"], "node-builtin.os.availableParallelism": ["tests/corpus/4598-os-available-parallelism.ts"], + "node-builtin.os.arch": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.cpus": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.devNull": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.endianness": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.freemem": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.getPriority": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.hostname": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.loadavg": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.machine": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.uptime": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.version": ["tests/corpus/5140-os-host-facts.ts"], + "node-builtin.os.constants": ["tests/corpus/5141-os-constants.ts"], "node-builtin.path": ["tests/corpus/957-builtins-namespace.ts", "tests/corpus/2915-path-function-values.ts", "tests/corpus/2916-path-function-values-cjs.ts", "tests/corpus/2917-builtin-callable-widths.ts", "tests/corpus/2918-builtin-callable-widths-cjs.ts"], + "node-builtin.path.parse": ["tests/corpus/5142-path-parse-format.ts", "packages/runtime/test/path.test.ts"], + "node-builtin.path.format": ["tests/corpus/5142-path-parse-format.ts", "packages/runtime/test/path.test.ts"], + "node-builtin.path.posix.parse": ["tests/corpus/5142-path-parse-format.ts", "packages/runtime/test/path.test.ts"], + "node-builtin.path.posix.format": ["tests/corpus/5142-path-parse-format.ts", "packages/runtime/test/path.test.ts"], + "node-builtin.path.win32.parse": ["tests/corpus/5142-path-parse-format.ts", "packages/runtime/test/path.test.ts"], + "node-builtin.path.win32.format": ["tests/corpus/5142-path-parse-format.ts", "packages/runtime/test/path.test.ts"], "node-builtin.perf_hooks": ["tests/corpus/957-builtins-namespace.ts"], "node-builtin.process": ["tests/corpus/990-process-basics.ts", "tests/corpus/2314-process-introspection.ts"], "node-builtin.process.hrtime": ["tests/corpus/process-hrtime.js"], diff --git a/packages/compiler/ambient/scriptc-node-fallback.d.ts b/packages/compiler/ambient/scriptc-node-fallback.d.ts index 0b347fcf0..d533b2305 100644 --- a/packages/compiler/ambient/scriptc-node-fallback.d.ts +++ b/packages/compiler/ambient/scriptc-node-fallback.d.ts @@ -1600,6 +1600,24 @@ declare module "path" { export function isAbsolute(path: string): boolean; export function relative(from: string, to: string): string; export function toNamespacedPath(path: string): string; + /* parse() splits a path into its root, directory, base, extension and + * name; format() joins those fields back (Node's `||` defaults). */ + export interface ParsedPath { + root: string; + dir: string; + base: string; + ext: string; + name: string; + } + export interface FormatInputPathObject { + root?: string | undefined; + dir?: string | undefined; + base?: string | undefined; + ext?: string | undefined; + name?: string | undefined; + } + export function parse(path: string): ParsedPath; + export function format(pathObject: FormatInputPathObject): string; /* The union @types/node declares: the bare module answers the TARGET * platform's value (a compile-time constant — "\\"/";" under a win32 * triple, "/"/":" everywhere else). */ @@ -1625,6 +1643,8 @@ declare module "path/posix" { export function isAbsolute(path: string): boolean; export function relative(from: string, to: string): string; export function toNamespacedPath(path: string): string; + export function parse(path: string): import("path").ParsedPath; + export function format(pathObject: import("path").FormatInputPathObject): string; export const sep: "/"; export const delimiter: ":"; } @@ -1641,6 +1661,8 @@ declare module "path/win32" { export function isAbsolute(path: string): boolean; export function relative(from: string, to: string): string; export function toNamespacedPath(path: string): string; + export function parse(path: string): import("path").ParsedPath; + export function format(pathObject: import("path").FormatInputPathObject): string; export const sep: "\\"; export const delimiter: ";"; } @@ -1698,6 +1720,237 @@ declare module "os" { } export type NetworkInterfaceInfo = NetworkInterfaceInfoIPv4 | NetworkInterfaceInfoIPv6; export function networkInterfaces(): { [name: string]: NetworkInterfaceInfo[] | undefined }; + /* Host facts, libuv's answers: model/speed/times per logical CPU, the + * host name, the 1/5/15-minute load averages, uptime in seconds, free + * memory in bytes, process.arch, uname's machine and version fields, + * the byte order, and a process's scheduling priority (an omitted pid + * is the current process). Shapes mirror @types/node's. */ + export interface CpuInfo { + model: string; + speed: number; + times: { + user: number; + nice: number; + sys: number; + idle: number; + irq: number; + }; + } + export function cpus(): CpuInfo[]; + export function hostname(): string; + export function loadavg(): number[]; + export function uptime(): number; + export function freemem(): number; + export function arch(): string; + export function machine(): string; + export function version(): string; + export function endianness(): "BE" | "LE"; + export function getPriority(pid?: number): number; + /* The TARGET platform's null device ("\\\\.\\nul" under a win32 triple). */ + export const devNull: string; + /* The platform's constants: null-prototype objects with read-only + * members, `signals` frozen (Node's internalBinding('constants').os). */ + export type SignalConstants = { + [ + key in + | "SIGABRT" + | "SIGALRM" + | "SIGBUS" + | "SIGCHLD" + | "SIGCONT" + | "SIGFPE" + | "SIGHUP" + | "SIGILL" + | "SIGINT" + | "SIGIO" + | "SIGIOT" + | "SIGKILL" + | "SIGPIPE" + | "SIGPOLL" + | "SIGPROF" + | "SIGPWR" + | "SIGQUIT" + | "SIGSEGV" + | "SIGSTKFLT" + | "SIGSTOP" + | "SIGSYS" + | "SIGTERM" + | "SIGTRAP" + | "SIGTSTP" + | "SIGTTIN" + | "SIGTTOU" + | "SIGUNUSED" + | "SIGURG" + | "SIGUSR1" + | "SIGUSR2" + | "SIGVTALRM" + | "SIGWINCH" + | "SIGXCPU" + | "SIGXFSZ" + | "SIGBREAK" + | "SIGLOST" + | "SIGINFO" + ]: number; + }; + export namespace constants { + const UV_UDP_REUSEADDR: number; + namespace signals {} + const signals: SignalConstants; + namespace errno { + const E2BIG: number; + const EACCES: number; + const EADDRINUSE: number; + const EADDRNOTAVAIL: number; + const EAFNOSUPPORT: number; + const EAGAIN: number; + const EALREADY: number; + const EBADF: number; + const EBADMSG: number; + const EBUSY: number; + const ECANCELED: number; + const ECHILD: number; + const ECONNABORTED: number; + const ECONNREFUSED: number; + const ECONNRESET: number; + const EDEADLK: number; + const EDESTADDRREQ: number; + const EDOM: number; + const EDQUOT: number; + const EEXIST: number; + const EFAULT: number; + const EFBIG: number; + const EHOSTUNREACH: number; + const EIDRM: number; + const EILSEQ: number; + const EINPROGRESS: number; + const EINTR: number; + const EINVAL: number; + const EIO: number; + const EISCONN: number; + const EISDIR: number; + const ELOOP: number; + const EMFILE: number; + const EMLINK: number; + const EMSGSIZE: number; + const EMULTIHOP: number; + const ENAMETOOLONG: number; + const ENETDOWN: number; + const ENETRESET: number; + const ENETUNREACH: number; + const ENFILE: number; + const ENOBUFS: number; + const ENODATA: number; + const ENODEV: number; + const ENOENT: number; + const ENOEXEC: number; + const ENOLCK: number; + const ENOLINK: number; + const ENOMEM: number; + const ENOMSG: number; + const ENOPROTOOPT: number; + const ENOSPC: number; + const ENOSR: number; + const ENOSTR: number; + const ENOSYS: number; + const ENOTCONN: number; + const ENOTDIR: number; + const ENOTEMPTY: number; + const ENOTSOCK: number; + const ENOTSUP: number; + const ENOTTY: number; + const ENXIO: number; + const EOPNOTSUPP: number; + const EOVERFLOW: number; + const EPERM: number; + const EPIPE: number; + const EPROTO: number; + const EPROTONOSUPPORT: number; + const EPROTOTYPE: number; + const ERANGE: number; + const EROFS: number; + const ESPIPE: number; + const ESRCH: number; + const ESTALE: number; + const ETIME: number; + const ETIMEDOUT: number; + const ETXTBSY: number; + const EWOULDBLOCK: number; + const EXDEV: number; + const WSAEINTR: number; + const WSAEBADF: number; + const WSAEACCES: number; + const WSAEFAULT: number; + const WSAEINVAL: number; + const WSAEMFILE: number; + const WSAEWOULDBLOCK: number; + const WSAEINPROGRESS: number; + const WSAEALREADY: number; + const WSAENOTSOCK: number; + const WSAEDESTADDRREQ: number; + const WSAEMSGSIZE: number; + const WSAEPROTOTYPE: number; + const WSAENOPROTOOPT: number; + const WSAEPROTONOSUPPORT: number; + const WSAESOCKTNOSUPPORT: number; + const WSAEOPNOTSUPP: number; + const WSAEPFNOSUPPORT: number; + const WSAEAFNOSUPPORT: number; + const WSAEADDRINUSE: number; + const WSAEADDRNOTAVAIL: number; + const WSAENETDOWN: number; + const WSAENETUNREACH: number; + const WSAENETRESET: number; + const WSAECONNABORTED: number; + const WSAECONNRESET: number; + const WSAENOBUFS: number; + const WSAEISCONN: number; + const WSAENOTCONN: number; + const WSAESHUTDOWN: number; + const WSAETOOMANYREFS: number; + const WSAETIMEDOUT: number; + const WSAECONNREFUSED: number; + const WSAELOOP: number; + const WSAENAMETOOLONG: number; + const WSAEHOSTDOWN: number; + const WSAEHOSTUNREACH: number; + const WSAENOTEMPTY: number; + const WSAEPROCLIM: number; + const WSAEUSERS: number; + const WSAEDQUOT: number; + const WSAESTALE: number; + const WSAEREMOTE: number; + const WSASYSNOTREADY: number; + const WSAVERNOTSUPPORTED: number; + const WSANOTINITIALISED: number; + const WSAEDISCON: number; + const WSAENOMORE: number; + const WSAECANCELLED: number; + const WSAEINVALIDPROCTABLE: number; + const WSAEINVALIDPROVIDER: number; + const WSAEPROVIDERFAILEDINIT: number; + const WSASYSCALLFAILURE: number; + const WSASERVICE_NOT_FOUND: number; + const WSATYPE_NOT_FOUND: number; + const WSA_E_NO_MORE: number; + const WSA_E_CANCELLED: number; + const WSAEREFUSED: number; + } + namespace dlopen { + const RTLD_LAZY: number; + const RTLD_NOW: number; + const RTLD_GLOBAL: number; + const RTLD_LOCAL: number; + const RTLD_DEEPBIND: number; + } + namespace priority { + const PRIORITY_LOW: number; + const PRIORITY_BELOW_NORMAL: number; + const PRIORITY_NORMAL: number; + const PRIORITY_ABOVE_NORMAL: number; + const PRIORITY_HIGH: number; + const PRIORITY_HIGHEST: number; + } + } } declare module "node:os" { export * from "os"; diff --git a/packages/compiler/src/backend/llvm/lib-shared.ts b/packages/compiler/src/backend/llvm/lib-shared.ts index df8206511..a05c145e4 100644 --- a/packages/compiler/src/backend/llvm/lib-shared.ts +++ b/packages/compiler/src/backend/llvm/lib-shared.ts @@ -150,6 +150,10 @@ export const LIB_FN_SYMS: Record = { "path.win32Dirname": "scr_path_win32_dirname", "path.win32Basename": "scr_path_win32_basename", "path.win32Extname": "scr_path_win32_extname", + "path.parse": "scr_path_parse", + "path.win32Parse": "scr_path_win32_parse", + "path.format": "scr_path_format", + "path.win32Format": "scr_path_win32_format", "path.win32IsAbsolute": "scr_path_win32_is_absolute", "path.win32Relative": "scr_path_win32_relative", "path.win32ToNamespacedPath": "scr_path_win32_to_namespaced_path", @@ -157,6 +161,18 @@ export const LIB_FN_SYMS: Record = { "os.type": "scr_os_type", "os.totalmem": "scr_os_totalmem", "os.availableParallelism": "scr_os_available_parallelism", + "os.hostname": "scr_os_hostname", + "os.machine": "scr_os_machine", + "os.version": "scr_os_version", + "os.endianness": "scr_os_endianness", + "os.freemem": "scr_os_freemem", + "os.uptime": "scr_os_uptime", + "os.loadavg": "scr_os_loadavg", + "os.getPriority": "scr_os_get_priority", + "os.cpusTake": "scr_os_cpus_take", + "os.cpusModel": "scr_os_cpus_model", + "os.cpusField": "scr_os_cpus_field", + "os.constants": "scr_os_constants", "os.release": "scr_os_release", "os.userName": "scr_os_user_name", "os.userShell": "scr_os_user_shell", diff --git a/packages/compiler/src/backend/native/runtime-inputs.ts b/packages/compiler/src/backend/native/runtime-inputs.ts index 403088321..ce75e7108 100644 --- a/packages/compiler/src/backend/native/runtime-inputs.ts +++ b/packages/compiler/src/backend/native/runtime-inputs.ts @@ -56,6 +56,7 @@ export const EXECUTABLE_RUNTIME_SOURCES = [ "scr_console.c", "scr_lib.c", "scr_path.c", + "scr_os.c", "scr_url.c", "scr_url_params.c", "scr_json.c", diff --git a/packages/compiler/src/backend/target-diagnostics.test.ts b/packages/compiler/src/backend/target-diagnostics.test.ts index fb9713795..59efb77b3 100644 --- a/packages/compiler/src/backend/target-diagnostics.test.ts +++ b/packages/compiler/src/backend/target-diagnostics.test.ts @@ -152,3 +152,17 @@ test("actual constructors retain host diagnostics while stored class values do n fenceSpeculativeWasiFunctions(stored); expect(moduleWasiUnavailableSurface(stored)).toBeNull(); }); + +test.each([ + ["os.cpusTake", "CPU enumeration"], + ["os.hostname", "the host name"], + ["os.freemem", "system memory statistics"], + ["os.loadavg", "system load averages"], + ["os.uptime", "system uptime"], + ["os.getPriority", "process scheduling priority"], +] as const)("os host fact %s has no WASI lowering", (libFn, surface) => { + const read: IrExpr = { kind: "libCall", fn: libFn, args: [], type: VOID, loc }; + const mod = module(); + mod.functions = [fn("%main", [read])]; + expect(moduleWasiUnavailableSurface(mod)?.surface).toContain(surface); +}); diff --git a/packages/compiler/src/backend/target-diagnostics.ts b/packages/compiler/src/backend/target-diagnostics.ts index daf9311d9..6407029c0 100644 --- a/packages/compiler/src/backend/target-diagnostics.ts +++ b/packages/compiler/src/backend/target-diagnostics.ts @@ -121,6 +121,16 @@ export function targetRefusalDiag(target: string, surface: string, loc: SrcLoc): }; } +/** node:os host facts WASI Preview 1 has no interface for. */ +const WASI_UNAVAILABLE_HOST_FACTS: ReadonlyMap = new Map([ + ["os.cpusTake", "CPU enumeration (WASI Preview 1 has no processor API)"], + ["os.hostname", "the host name (WASI Preview 1 has no host-name API)"], + ["os.freemem", "system memory statistics (WASI Preview 1 has no memory API)"], + ["os.loadavg", "system load averages (WASI Preview 1 has no load API)"], + ["os.uptime", "system uptime (WASI Preview 1 has no boot-time API)"], + ["os.getPriority", "process scheduling priority (WASI Preview 1 has no priority API)"], +]); + export function moduleWasiUnavailableSurface( mod: IrModule, ): { surface: string; loc: SrcLoc } | null { @@ -185,6 +195,11 @@ export function moduleWasiUnavailableSurface( }; return false; } + const hostFact = WASI_UNAVAILABLE_HOST_FACTS.get(node.fn); + if (hostFact !== undefined) { + found = { surface: hostFact, loc }; + return false; + } for (const [prefix, surface] of prefixes) { if (node.fn.startsWith(prefix)) { found = { surface, loc }; diff --git a/packages/compiler/src/frontend/lowering/builtins/module-calls.ts b/packages/compiler/src/frontend/lowering/builtins/module-calls.ts index e229a3937..cfbfa96eb 100644 --- a/packages/compiler/src/frontend/lowering/builtins/module-calls.ts +++ b/packages/compiler/src/frontend/lowering/builtins/module-calls.ts @@ -33,7 +33,14 @@ import { lowerProcessLoadEnvFile } from "./environment.js"; import { lowerFsWatchCall, lowerFsReaddirTypesCall } from "./filesystem.js"; import { lowerZlibModuleCall } from "./compression.js"; import { lowerForkCall } from "./child-process.js"; -import { lowerOsNetworkInterfacesCall, lowerOsUserInfoCall } from "./operating-system.js"; +import { + lowerOsCpusCall, + lowerOsGetPriorityCall, + lowerOsNetworkInterfacesCall, + lowerOsUserInfoCall, + lowerPathFormatCall, + lowerPathParseCall, +} from "./operating-system.js"; import { lowerQuerystringParseCall, lowerQuerystringStringifyCall } from "./querystring.js"; export function lowerBuiltinModuleCall( @@ -128,6 +135,24 @@ export function lowerBuiltinModuleCall( if (bi.module === "os" && bi.member === "userInfo") { return lowerOsUserInfoCall(lowerer, expr, loc); } + if (bi.module === "os" && bi.member === "cpus") { + return lowerOsCpusCall(lowerer, expr, loc); + } + if (bi.module === "os" && bi.member === "getPriority") { + return lowerOsGetPriorityCall(lowerer, expr, loc); + } + // path.parse/path.format: the bare module is the TARGET platform's + // family, the namespaces their own. + if ( + (bi.module === "path" || bi.module === "path/posix" || bi.module === "path/win32") && + (bi.member === "parse" || bi.member === "format") + ) { + const win32 = + bi.module === "path/win32" || (bi.module === "path" && lowerer.targetPlatform === "win32"); + return bi.member === "parse" + ? lowerPathParseCall(lowerer, expr, win32, loc) + : lowerPathFormatCall(lowerer, expr, win32, loc); + } // node:querystring — parse/stringify are entirely special-cased (the // sep/eq/options completions, parse's call-site-shaped dictionary // result, stringify's dyn-crossing object argument); decode/encode diff --git a/packages/compiler/src/frontend/lowering/builtins/operating-system.ts b/packages/compiler/src/frontend/lowering/builtins/operating-system.ts index 6e251e95f..051981f09 100644 --- a/packages/compiler/src/frontend/lowering/builtins/operating-system.ts +++ b/packages/compiler/src/frontend/lowering/builtins/operating-system.ts @@ -1,6 +1,18 @@ +import { numLit, strLit, varRef } from "../../../ir/build.js"; import * as ts from "../../ts7/adapter.js"; import { type Lowerer } from "../lowerer.js"; -import { F64, type IrExpr, type IrType, STRING, type SrcLoc } from "../../../ir/ir.js"; +import { + BOOL, + F64, + type IrExpr, + type IrStmt, + type IrType, + STRING, + type SrcLoc, + UNDEFINED_T, + arrayOf, + typeKey, +} from "../../../ir/ir.js"; /** `os.userInfo()` — the passwd-entry snapshot, Node's uv_os_get_passwd * behind the call site's own mapped record shape: username = pw_name, @@ -159,3 +171,407 @@ export function lowerOsNetworkInterfacesCall( if (!saw4 || !saw6) fence(); return { kind: "libCall", fn: "os.networkInterfaces", args: [], type: result, loc }; } + +/** `os.cpus()` — one uv_cpu_info snapshot as the call site's CpuInfo[]: + * os.cpusTake reads every CPU and answers the count, and a lifted helper + * builds one { model, speed, times: { user, nice, sys, idle, irq } } + * record per CPU from the snapshot accessors, in the mapped shapes' own + * field order. Other result shapes fence. */ +export function lowerOsCpusCall(lowerer: Lowerer, call: ts.CallExpression, loc: SrcLoc): IrExpr { + if (call.arguments.length !== 0) { + lowerer.noLowering( + `cpus with ${call.arguments.length} arguments`, + call, + "cpus() takes no arguments", + ); + } + const fence: () => never = () => + lowerer.noLowering( + "cpus() where the result is not the CpuInfo array", + call, + "{ model, speed, times: { user, nice, sys, idle, irq } }[] is the supported result shape", + ); + const result = lowerer.mapTypeOf(lowerer.typeOf(call)); + if (result?.kind !== "array" || result.elem.kind !== "record") fence(); + const info = result.elem; + const infoShape = lowerer.shapes.get(info.shapeId); + if (!infoShape || infoShape.tuple || infoShape.indexValue || infoShape.fields.length !== 3) + fence(); + const timesField = infoShape.fields.find((f) => f.name === "times"); + const timesT = timesField?.type; + if (timesT?.kind !== "record") fence(); + const timesShape = lowerer.shapes.get(timesT.shapeId); + const TIMES = ["user", "nice", "sys", "idle", "irq"]; + if ( + !timesShape || + timesShape.tuple || + timesShape.indexValue || + timesShape.fields.length !== TIMES.length || + timesShape.fields.some((f) => !TIMES.includes(f.name) || f.type.kind !== "f64") + ) + fence(); + if ( + infoShape.fields.find((f) => f.name === "model")?.type.kind !== "string" || + infoShape.fields.find((f) => f.name === "speed")?.type.kind !== "f64" + ) + fence(); + const key = `os.cpus:${typeKey(result)}`; + let helper = lowerer.valueHelpers.get(key); + if (!helper) { + helper = `%os.cpus.${lowerer.valueHelpers.size}`; + lowerer.valueHelpers.set(key, helper); + const index = varRef("i.0", F64, loc); + const field = (k: number): IrExpr => ({ + kind: "libCall", + fn: "os.cpusField", + args: [index, numLit(k, loc)], + type: F64, + loc, + }); + const times: IrExpr = { + kind: "recordLit", + fields: timesShape.fields.map((f) => ({ + name: f.name, + value: field(1 + TIMES.indexOf(f.name)), + })), + type: timesT, + loc, + }; + const record: IrExpr = { + kind: "recordLit", + fields: infoShape.fields.map((f) => ({ + name: f.name, + value: + f.name === "model" + ? { kind: "libCall", fn: "os.cpusModel", args: [index], type: STRING, loc } + : f.name === "speed" + ? field(0) + : times, + })), + type: info, + loc, + }; + const out = varRef("out.0", result, loc); + const count = varRef("n.0", F64, loc); + const body: IrStmt[] = [ + { + kind: "varDecl", + localId: "n.0", + init: { kind: "libCall", fn: "os.cpusTake", args: [], type: F64, loc }, + loc, + }, + { + kind: "varDecl", + localId: "out.0", + init: { kind: "arrayLit", elems: [], type: result, loc }, + loc, + }, + { + kind: "for", + init: { kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc }, + cond: { kind: "bin", op: "<", left: index, right: count, type: BOOL, loc }, + update: { + kind: "assign", + localId: "i.0", + value: { kind: "bin", op: "+", left: index, right: numLit(1, loc), type: F64, loc }, + loc, + }, + body: [ + { + kind: "exprStmt", + expr: { + kind: "arrIntrinsic", + method: "push", + receiver: out, + args: [record], + type: F64, + loc, + }, + loc, + }, + ], + loc, + }, + { kind: "return", value: out, loc }, + ]; + lowerer.liftedFns.push({ + name: helper, + params: [], + returnType: result, + locals: [ + { id: "n.0", name: "n", type: F64, mutable: false }, + { id: "out.0", name: "out", type: result, mutable: false }, + { id: "i.0", name: "i", type: F64, mutable: true }, + ], + body, + loc, + }); + } + return { kind: "call", callee: helper, args: [], type: result, loc }; +} + +const PATH_FIELDS = ["root", "dir", "base", "ext", "name"]; + +/** `path.parse(p)` — the runtime's [root, dir, base, ext, name] parts as + * the call site's ParsedPath record (a lifted helper per shape). Other + * result shapes fence. */ +export function lowerPathParseCall( + lowerer: Lowerer, + call: ts.CallExpression, + win32: boolean, + loc: SrcLoc, +): IrExpr { + const arg = call.arguments[0]; + if (call.arguments.length !== 1 || !arg || ts.isSpreadElement(arg)) { + lowerer.noLowering("path.parse without exactly one path", call, "parse(path) takes one string"); + } + const result = lowerer.mapTypeOf(lowerer.typeOf(call)); + const shape = result?.kind === "record" ? lowerer.shapes.get(result.shapeId) : undefined; + if ( + result?.kind !== "record" || + !shape || + shape.tuple || + shape.indexValue || + shape.fields.length !== PATH_FIELDS.length || + shape.fields.some((f) => !PATH_FIELDS.includes(f.name) || f.type.kind !== "string") + ) { + lowerer.noLowering( + "path.parse where the result is not the ParsedPath record", + call, + "{ root, dir, base, ext, name } is the supported result shape", + ); + } + const fn = win32 ? "path.win32Parse" : "path.parse"; + const key = `${fn}:${typeKey(result)}`; + let helper = lowerer.valueHelpers.get(key); + if (!helper) { + helper = `%path.parse.${lowerer.valueHelpers.size}`; + lowerer.valueHelpers.set(key, helper); + const parts = varRef("parts.0", arrayOf(STRING), loc); + lowerer.liftedFns.push({ + name: helper, + params: [{ localId: "path.0", name: "path", type: STRING }], + returnType: result, + locals: [ + { id: "path.0", name: "path", type: STRING, mutable: false }, + { id: "parts.0", name: "parts", type: arrayOf(STRING), mutable: false }, + ], + body: [ + { + kind: "varDecl", + localId: "parts.0", + init: { + kind: "libCall", + fn, + args: [varRef("path.0", STRING, loc)], + type: arrayOf(STRING), + loc, + }, + loc, + }, + { + kind: "return", + value: { + kind: "recordLit", + fields: shape.fields.map((f) => ({ + name: f.name, + value: { + kind: "arrayGet", + arr: parts, + index: numLit(PATH_FIELDS.indexOf(f.name), loc), + type: STRING, + loc, + }, + })), + type: result, + loc, + }, + loc, + }, + ], + loc, + }); + } + return { + kind: "call", + callee: helper, + args: [lowerer.lowerExprExpecting(arg, STRING)], + type: result, + loc, + }; +} + +/** `path.format(pathObject)` — the object's root, dir, base, name and ext + * (each a string or an optional string; absent fields and undefined read + * as "", which Node's `||` treats alike) passed to the runtime's format. + * Other argument shapes fence. */ +export function lowerPathFormatCall( + lowerer: Lowerer, + call: ts.CallExpression, + win32: boolean, + loc: SrcLoc, +): IrExpr { + const arg = call.arguments[0]; + if (call.arguments.length !== 1 || !arg || ts.isSpreadElement(arg)) { + lowerer.noLowering( + "path.format without exactly one object", + call, + "format(pathObject) takes one object", + ); + } + const fence: () => never = () => + lowerer.noLowering( + "path.format with this argument type", + arg, + "an object whose root, dir, base, name and ext are strings or optional strings", + ); + const value = lowerer.lowerExpr(arg); + if (value.type.kind !== "record") fence(); + const recordT = value.type; + const shape = lowerer.shapes.get(recordT.shapeId); + if (!shape || shape.tuple || shape.indexValue) fence(); + const fieldTypes = new Map(); + for (const f of shape.fields) { + if (!PATH_FIELDS.includes(f.name)) continue; + const ok = + f.type.kind === "string" || + (f.type.kind === "union" && + (lowerer.unions + .get(f.type.unionId) + ?.arms.every((a) => a.kind === "string" || a.kind === "undefinedT") ?? + false)); + if (!ok) fence(); + fieldTypes.set(f.name, f.type); + } + const fn = win32 ? "path.win32Format" : "path.format"; + const key = `${fn}:${typeKey(recordT)}`; + let helper = lowerer.valueHelpers.get(key); + if (!helper) { + helper = `%path.format.${lowerer.valueHelpers.size}`; + lowerer.valueHelpers.set(key, helper); + const object = varRef("object.0", recordT, loc); + const read = (name: string): IrExpr => { + const type = fieldTypes.get(name); + if (!type) return strLit("", loc); + const get: IrExpr = { + kind: "recordGet", + obj: object, + shapeId: recordT.shapeId, + field: name, + type, + loc, + }; + if (type.kind === "string") return get; + const unionId = (type as IrType & { kind: "union" }).unionId; + return { + kind: "ternary", + cond: { + kind: "unionIsTag", + unionId, + tag: lowerer.armTag(unionId, UNDEFINED_T), + negated: false, + value: get, + type: BOOL, + loc, + }, + then: strLit("", loc), + else_: { + kind: "unionNarrow", + unionId, + tag: lowerer.armTag(unionId, STRING), + value: get, + type: STRING, + loc, + }, + type: STRING, + loc, + }; + }; + lowerer.liftedFns.push({ + name: helper, + params: [{ localId: "object.0", name: "object", type: recordT }], + returnType: STRING, + locals: [{ id: "object.0", name: "object", type: recordT, mutable: false }], + body: [ + { + kind: "return", + value: { + kind: "libCall", + fn, + args: ["root", "dir", "base", "name", "ext"].map(read), + type: STRING, + loc, + }, + loc, + }, + ], + loc, + }); + } + return { kind: "call", callee: helper, args: [value], type: STRING, loc }; +} + +/** `os.getPriority(pid?)` — an omitted or undefined pid is 0 (Node's + * `if (pid === undefined) pid = 0`); the runtime validates the rest. */ +export function lowerOsGetPriorityCall( + lowerer: Lowerer, + call: ts.CallExpression, + loc: SrcLoc, +): IrExpr { + const arg = call.arguments[0]; + if (call.arguments.length > 1 || (arg && ts.isSpreadElement(arg))) { + lowerer.noLowering( + "getPriority with these arguments", + call, + "getPriority(pid?) takes one number", + ); + } + let pid: IrExpr = numLit(0, loc); + if (arg) { + const value = lowerer.lowerExpr(arg); + if (value.type.kind === "f64") { + pid = value; + } else if ( + value.type.kind === "union" && + lowerer.armTag(value.type.unionId, UNDEFINED_T) >= 0 && + lowerer.armTag(value.type.unionId, F64) >= 0 && + lowerer.unions.get(value.type.unionId)?.arms.length === 2 + ) { + const unionId = value.type.unionId; + const temp = lowerer.declareHiddenLocal("%pid", value.type); + const ref = varRef(temp.id, value.type, loc); + pid = { + kind: "seqExpr", + stmts: [{ kind: "varDecl", localId: temp.id, init: value, loc }], + result: { + kind: "ternary", + cond: { + kind: "unionIsTag", + unionId, + tag: lowerer.armTag(unionId, UNDEFINED_T), + negated: false, + value: ref, + type: BOOL, + loc, + }, + then: numLit(0, loc), + else_: { + kind: "unionNarrow", + unionId, + tag: lowerer.armTag(unionId, F64), + value: ref, + type: F64, + loc, + }, + type: F64, + loc, + }, + type: F64, + loc, + }; + } else { + pid = lowerer.lowerExprExpecting(arg, F64); + } + } + return { kind: "libCall", fn: "os.getPriority", args: [pid], type: F64, loc }; +} diff --git a/packages/compiler/src/frontend/lowering/lower-exprs.ts b/packages/compiler/src/frontend/lowering/lower-exprs.ts index 757318b26..b35d1633b 100644 --- a/packages/compiler/src/frontend/lowering/lower-exprs.ts +++ b/packages/compiler/src/frontend/lowering/lower-exprs.ts @@ -155,6 +155,7 @@ import { mixinFnOfCallee } from "./lower-mixins.js"; import { isConstAssertionTypeNode, isGenericCallableMemberType, + isOsConstantsType, isParseArgsDynTypeName, underConstAssertion, unitOnlyUnion, @@ -1135,6 +1136,9 @@ function lowerExprInner(lowerer: Lowerer, expr: ts.Expression): IrExpr { if (bi.module === "http" && bi.member === "STATUS_CODES") { return { kind: "libCall", fn: "http.statusCodes", args: [], type: DYN, loc }; } + if (bi.module === "os" && bi.member === "constants") { + return { kind: "libCall", fn: "os.constants", args: [], type: DYN, loc }; + } // tls.rootCertificates: a runtime-valued module constant (the // cached bundled-CA array) — the one member read that lowers // to a libCall instead of a baked literal. @@ -2419,10 +2423,15 @@ function lowerExprInner(lowerer: Lowerer, expr: ts.Expression): IrExpr { segmentDataSymbol?.name === "SegmentData" && lowerer.isStdlibSymbol(segmentDataSymbol) && ["segment", "index", "input", "isWordLike"].includes(expr.name.text); + // os.constants members vary by platform (the declared groups list + // every platform's names): a number member reads as `number | + // undefined`, like an array element, and a group stays checked. + const osConstants = isOsConstantsType(lowerer.typeOf(expr.expression), lowerer); if ( isParseArgsDynProperty(lowerer, expr) || isStatFsDynProperty(lowerer, expr) || - segmentDataProperty + segmentDataProperty || + osConstants ) { const recv = lowerer.lowerExpr(expr.expression); if (recv.type.kind === "dyn") { @@ -2433,17 +2442,20 @@ function lowerExprInner(lowerer: Lowerer, expr: ts.Expression): IrExpr { loc: locOf(expr.name), }; const opt = hasOptionalChainGuard(expr.expression); - return lowerer.maybeNarrow( - { - kind: "dynKeyGet", - key, - ...(opt ? { optional: true as const } : {}), - value: recv, - type: DYN, - loc, - }, - expr, - ); + const read: IrExpr = { + kind: "dynKeyGet", + key, + ...(opt ? { optional: true as const } : {}), + value: recv, + type: DYN, + loc, + }; + if (osConstants) { + return lowerer.mapTypeOf(lowerer.typeOf(expr))?.kind === "f64" + ? lowerer.coerceToExpected(read, lowerer.withUndefinedArm(F64)) + : read; + } + return lowerer.maybeNarrow(read, expr); } } // A member read through a NULLISH generic binding (`const i: I = { result: STRING, valueParams: [{ mode: "required", type: STRING }], }, + // Special-cased (lowerPathParseCall / lowerPathFormatCall): the + // ParsedPath record and the pathObject argument follow the call site's + // mapped shapes. + parse: { fn: "path.parse", params: [STRING], result: VOID }, + format: { fn: "path.format", params: [], result: STRING }, }; /** The win32 twins (scr_path.c's Node-v24 path.win32 port, byte-for-byte): @@ -987,6 +992,11 @@ const PATH_WIN32_MODULE_FNS: Record = { result: STRING, valueParams: [{ mode: "required", type: STRING }], }, + // Special-cased (lowerPathParseCall / lowerPathFormatCall): the + // ParsedPath record and the pathObject argument follow the call site's + // mapped shapes. + parse: { fn: "path.win32Parse", params: [STRING], result: VOID }, + format: { fn: "path.win32Format", params: [], result: STRING }, }; export const BUILTIN_MODULE_FNS: Record< @@ -1270,6 +1280,28 @@ export const BUILTIN_MODULE_FNS: Record< result: F64, valueParams: [], }, + // os.arch() IS process.arch, like platform(). + arch: { fn: "process.arch", params: [], result: STRING, valueParams: [] }, + hostname: { fn: "os.hostname", params: [], result: STRING, valueParams: [] }, + // uv_os_uname's machine and version fields, read once at module load + // in Node (they never change while a process runs). + machine: { fn: "os.machine", params: [], result: STRING, valueParams: [] }, + version: { fn: "os.version", params: [], result: STRING, valueParams: [] }, + endianness: { fn: "os.endianness", params: [], result: STRING, valueParams: [] }, + freemem: { fn: "os.freemem", params: [], result: F64, valueParams: [] }, + uptime: { fn: "os.uptime", params: [], result: F64, valueParams: [] }, + loadavg: { fn: "os.loadavg", params: [], result: arrayOf(F64), valueParams: [] }, + // An omitted (or undefined) pid is 0, the current process + // (lowerOsGetPriorityCall completes it). + getPriority: { + fn: "os.getPriority", + params: [F64], + result: F64, + valueParams: [{ mode: "optional", type: F64, defaultValue: 0 }], + }, + // Special-cased (lowerOsCpusCall): the call site's CpuInfo[] assembles + // from one uv_cpu_info snapshot. + cpus: { fn: "os.cpusTake", params: [], result: VOID }, // Entirely special-cased (lowerOsNetworkInterfacesCall): the result is // the call site's mapped Dict shape, verified // structurally there — this entry only routes the dispatch. @@ -1613,7 +1645,7 @@ export const BUILTIN_MODULE_CONSTS: Record< path: { sep: "/", delimiter: ":" }, "path/posix": { sep: "/", delimiter: ":" }, "path/win32": { sep: "\\", delimiter: ";" }, - os: { EOL: "\n" }, + os: { EOL: "\n", devNull: "/dev/null" }, worker_threads: { isMainThread: true, threadId: 0 }, cluster: { isPrimary: true, isMaster: true, isWorker: false }, }; @@ -1692,6 +1724,8 @@ export const BUILTIN_MODULE_FN_ALIASES: Record< os: { // lowerOsUserInfoCall assembles the record from scalar libCalls. userInfo: ["os.userHomedir", "os.userShell"], + // lowerOsCpusCall reads the cpusTake snapshot through its accessors. + cpus: ["os.cpusModel", "os.cpusField"], }, }; @@ -2106,6 +2140,15 @@ export const AMBIENT_SURFACE_FNS: readonly AmbientSurfaceRow[] = [ fns: ["tlsca.set"], note: "replaces the default set and the client trust anchors for the rest of the process", }, + // os.constants is a VALUE read (lowerNamespaceBuiltinProperty and the + // named-import path): the platform's null-prototype constants object. + { + id: "node-builtin.os.constants", + kind: "node-builtin", + name: "os.constants", + fns: ["os.constants"], + note: "the platform's dlopen, errno, signals and priority groups; members a platform lacks read as undefined", + }, ]; /** The win32-target overrides of the bare modules' constants: path's @@ -2116,7 +2159,7 @@ const WIN32_TARGET_CONSTS: Record< Record | undefined > = { path: BUILTIN_MODULE_CONSTS["path/win32"], - os: { EOL: "\r\n" }, + os: { EOL: "\r\n", devNull: "\\\\.\\nul" }, }; /** BUILTIN_MODULE_FNS with the platform-conditional modules bound per diff --git a/packages/compiler/src/frontend/type-mapper.ts b/packages/compiler/src/frontend/type-mapper.ts index 50773fc7b..93a923078 100644 --- a/packages/compiler/src/frontend/type-mapper.ts +++ b/packages/compiler/src/frontend/type-mapper.ts @@ -1050,6 +1050,49 @@ let mapTypeDepth = 0; * stay fenced instead of interning a per-context-wrong shape). */ let contextResolutions = 0; +/** os.constants and its groups — @types/node's `namespace constants` + * (errno, dlopen, priority) and SignalConstants, and the fallback's twins: + * the runtime's checked-dynamic constants object, whose members vary by + * platform. */ +export function isOsConstantsType( + type: ts.Type, + ctx: Pick, +): boolean { + return ( + isOsConstantsSymbol(type.getAliasSymbol(), ctx, true) || + isOsConstantsSymbol(type.getSymbol(), ctx, true) + ); +} + +/** A symbol declared as os.constants or one of its groups (a namespace, or + * with `types`, the SignalConstants alias; without it, the `signals` + * constant). The binding-symbol form needs no type query. */ +export function isOsConstantsSymbol( + symbol: ts.Symbol | null | undefined, + ctx: Pick, + types = false, +): boolean { + if (!symbol) return false; + for (const d of ctx.checker.declarationsOf(symbol)) { + const alias = types && ts.isTypeAliasDeclaration(d) && d.name.text === "SignalConstants"; + const signals = + !types && ts.isVariableDeclaration(d) && ts.isIdentifier(d.name) && d.name.text === "signals"; + if (!(alias || signals || ts.isModuleDeclaration(d)) || !ctx.isStdlibFile(d.getSourceFile())) + continue; + let inConstants = ts.isModuleDeclaration(d) && d.name.text === "constants"; + for (let n: ts.Node | undefined = d.parent; n; n = n.parent) { + if (!ts.isModuleDeclaration(n)) continue; + if (ts.isStringLiteral(n.name)) { + if ((n.name.text === "os" || n.name.text === "node:os") && (alias || inConstants)) + return true; + break; + } + if (n.name.text === "constants") inConstants = true; + } + } + return false; +} + /** worker_threads' Worker and MessagePort: owned runtime handles that keep * their live object representation (DYN) wherever they are stored. */ function isWorkerHandleSymbol( @@ -1164,6 +1207,7 @@ function mapTypeInner(type: ts.Type, ctx: TypeMapperCtx): IrType | null { ) { return { kind: "object", className: "%Error" }; } + if (isOsConstantsType(type, ctx)) return DYN; // Immutable (@scriptc/types) is a deep-readonly view: the value is // still the T it maps. const immutableSource = immutableSourceType(type, ctx); @@ -2989,6 +3033,66 @@ function mapTypeInner(type: ts.Type, ctx: TypeMapperCtx): IrType | null { // string arm. Key order is Node's runtime insertion order (node_os.cc // builds uid, gid, username, homedir, shell), so Object.keys over the // record answers exactly Node. + // os.CpuInfo (os.cpus()'s element), path.ParsedPath (path.parse()'s + // result) and path.FormatInputPathObject (path.format()'s argument): + // stdlib data interfaces interned explicitly, the AddressInfo pattern. + // Key order is Node's own (lib/os.js builds { model, speed, times: + // { user, nice, sys, idle, irq } }; path.parse builds { root, dir, base, + // ext, name }). + const cpuTimes = (): IrType => ({ + kind: "record", + shapeId: ctx.shapes.intern( + ["idle", "irq", "nice", "sys", "user"].map((name) => ({ name, type: F64 })), + false, + undefined, + ["user", "nice", "sys", "idle", "irq"], + ), + }); + if ( + psym && + checker + .declarationsOf(psym) + .some( + (d) => + ts.isTypeLiteralNode(d) && + ts.isPropertySignature(d.parent) && + ts.isIdentifier(d.parent.name) && + d.parent.name.text === "times" && + ts.isInterfaceDeclaration(d.parent.parent) && + d.parent.parent.name.text === "CpuInfo" && + ctx.isStdlibFile(d.getSourceFile()), + ) + ) + return cpuTimes(); + if (isStdlibInterface("CpuInfo")) { + const times = cpuTimes(); + return { + kind: "record", + shapeId: ctx.shapes.intern( + [ + { name: "model", type: STRING }, + { name: "speed", type: F64 }, + { name: "times", type: times }, + ], + false, + undefined, + ["model", "speed", "times"], + ), + }; + } + if (isStdlibInterface("ParsedPath") || isStdlibInterface("FormatInputPathObject")) { + const field = psym!.name === "ParsedPath" ? STRING : withUndefinedArm(STRING, ctx.unions); + if (!field) return null; + return { + kind: "record", + shapeId: ctx.shapes.intern( + ["base", "dir", "ext", "name", "root"].map((name) => ({ name, type: field })), + false, + undefined, + ["root", "dir", "base", "ext", "name"], + ), + }; + } if (isStdlibInterface("UserInfo")) { const args = checker.getTypeArguments(widened as ts.TypeReference); if (args.length > 1) return null; diff --git a/packages/compiler/src/ir/builtin-effects.ts b/packages/compiler/src/ir/builtin-effects.ts index 5284bd4f1..1c9fb9beb 100644 --- a/packages/compiler/src/ir/builtin-effects.ts +++ b/packages/compiler/src/ir/builtin-effects.ts @@ -460,6 +460,7 @@ export const MAY_THROW_LIB_FNS: ReadonlySet = new Set([ "dyn.getOwnPropertyDescriptor", "dyn.arrayProtoCall", "process.chdir", + "os.getPriority", "process.umask", "process.loadEnvFile", "fs.realpathSync", diff --git a/packages/compiler/src/ir/builtin-signatures.ts b/packages/compiler/src/ir/builtin-signatures.ts index dd9cb27be..769b87ab2 100644 --- a/packages/compiler/src/ir/builtin-signatures.ts +++ b/packages/compiler/src/ir/builtin-signatures.ts @@ -399,6 +399,13 @@ export const LIB_FN_SIGS = defineLibFnSignatures({ "path.win32IsAbsolute": { argTypes: [STRING], result: BOOL }, "path.win32Relative": { argTypes: [STRING, STRING], result: STRING }, "path.win32ToNamespacedPath": { argTypes: [STRING], result: STRING }, + /** path.parse: [root, dir, base, ext, name] as a fresh string[] (the + * frontend builds the ParsedPath record); path.format: the pathObject's + * root, dir, base, name and ext with undefined spelled "". */ + "path.parse": { argTypes: [STRING], result: arrayOf(STRING) }, + "path.win32Parse": { argTypes: [STRING], result: arrayOf(STRING) }, + "path.format": { argTypes: [STRING, STRING, STRING, STRING, STRING], result: STRING }, + "path.win32Format": { argTypes: [STRING, STRING, STRING, STRING, STRING], result: STRING }, /** node:os: homedir is $HOME else getpwuid(3); tmpdir is Node's env * cascade ($TMPDIR/$TMP/$TEMP else /tmp, one trailing slash trimmed). * os.platform() lowers to process.platform — one implementation. */ @@ -414,6 +421,29 @@ export const LIB_FN_SIGS = defineLibFnSignatures({ "os.totalmem": { argTypes: [], result: F64 }, /** os.availableParallelism(): CPUs the process may use (libuv's answer), >= 1. Never throws. */ "os.availableParallelism": { argTypes: [], result: F64 }, + /** os.hostname/machine/version/endianness, freemem, uptime and loadavg: + * libuv's answers (uname's machine and version fields, gethostname, + * "LE"/"BE", free memory in bytes, uptime in seconds, the three load + * averages). Fresh results; never throw. */ + "os.hostname": { argTypes: [], result: STRING }, + "os.machine": { argTypes: [], result: STRING }, + "os.version": { argTypes: [], result: STRING }, + "os.endianness": { argTypes: [], result: STRING }, + "os.freemem": { argTypes: [], result: F64 }, + "os.uptime": { argTypes: [], result: F64 }, + "os.loadavg": { argTypes: [], result: arrayOf(F64) }, + /** os.getPriority(pid): validateInt32 (RangeError ERR_OUT_OF_RANGE), + * then the priority; a failure throws Node's SystemError. */ + "os.getPriority": { argTypes: [F64], result: F64 }, + /** os.cpus(): cpusTake snapshots every CPU and answers the count; + * cpusModel(i) and cpusField(i, k) (k: 0 speed, 1 user, 2 nice, 3 sys, + * 4 idle, 5 irq) read the snapshot. Never throw. */ + "os.cpusTake": { argTypes: [], result: F64 }, + "os.cpusModel": { argTypes: [F64], result: STRING }, + "os.cpusField": { argTypes: [F64, F64], result: F64 }, + /** os.constants: the per-thread null-prototype constants object (dlopen, + * errno, signals, priority, UV_UDP_REUSEADDR). Never throws. */ + "os.constants": { argTypes: [], result: DYN }, /** umask(2): arg < 0 reads without setting (umask has no read-only form * — set 0, restore); otherwise sets and answers the PREVIOUS mask. * Never throws. */ diff --git a/packages/compiler/surface-manifest.json b/packages/compiler/surface-manifest.json index b2057bd70..1fd2b5b07 100644 --- a/packages/compiler/surface-manifest.json +++ b/packages/compiler/surface-manifest.json @@ -1318,18 +1318,80 @@ "status": "static", "note": "constant value read" }, + { + "id": "node-builtin.os.arch", + "kind": "node-builtin", + "name": "os.arch", + "status": "static" + }, { "id": "node-builtin.os.availableParallelism", "kind": "node-builtin", "name": "os.availableParallelism", "status": "static" }, + { + "id": "node-builtin.os.constants", + "kind": "node-builtin", + "name": "os.constants", + "status": "static", + "note": "the platform's dlopen, errno, signals and priority groups; members a platform lacks read as undefined" + }, + { + "id": "node-builtin.os.cpus", + "kind": "node-builtin", + "name": "os.cpus", + "status": "static" + }, + { + "id": "node-builtin.os.devNull", + "kind": "node-builtin", + "name": "os.devNull", + "status": "static", + "note": "constant value read" + }, + { + "id": "node-builtin.os.endianness", + "kind": "node-builtin", + "name": "os.endianness", + "status": "static" + }, + { + "id": "node-builtin.os.freemem", + "kind": "node-builtin", + "name": "os.freemem", + "status": "static" + }, + { + "id": "node-builtin.os.getPriority", + "kind": "node-builtin", + "name": "os.getPriority", + "status": "static" + }, { "id": "node-builtin.os.homedir", "kind": "node-builtin", "name": "os.homedir", "status": "static" }, + { + "id": "node-builtin.os.hostname", + "kind": "node-builtin", + "name": "os.hostname", + "status": "static" + }, + { + "id": "node-builtin.os.loadavg", + "kind": "node-builtin", + "name": "os.loadavg", + "status": "static" + }, + { + "id": "node-builtin.os.machine", + "kind": "node-builtin", + "name": "os.machine", + "status": "static" + }, { "id": "node-builtin.os.networkInterfaces", "kind": "node-builtin", @@ -1366,12 +1428,24 @@ "name": "os.type", "status": "static" }, + { + "id": "node-builtin.os.uptime", + "kind": "node-builtin", + "name": "os.uptime", + "status": "static" + }, { "id": "node-builtin.os.userInfo", "kind": "node-builtin", "name": "os.userInfo", "status": "static" }, + { + "id": "node-builtin.os.version", + "kind": "node-builtin", + "name": "os.version", + "status": "static" + }, { "id": "node-builtin.path", "kind": "node-builtin", @@ -1404,6 +1478,12 @@ "name": "path.extname", "status": "static" }, + { + "id": "node-builtin.path.format", + "kind": "node-builtin", + "name": "path.format", + "status": "static" + }, { "id": "node-builtin.path.isAbsolute", "kind": "node-builtin", @@ -1422,6 +1502,12 @@ "name": "path.normalize", "status": "static" }, + { + "id": "node-builtin.path.parse", + "kind": "node-builtin", + "name": "path.parse", + "status": "static" + }, { "id": "node-builtin.path.posix", "kind": "node-builtin", @@ -1454,6 +1540,12 @@ "name": "path/posix.extname", "status": "static" }, + { + "id": "node-builtin.path.posix.format", + "kind": "node-builtin", + "name": "path/posix.format", + "status": "static" + }, { "id": "node-builtin.path.posix.isAbsolute", "kind": "node-builtin", @@ -1472,6 +1564,12 @@ "name": "path/posix.normalize", "status": "static" }, + { + "id": "node-builtin.path.posix.parse", + "kind": "node-builtin", + "name": "path/posix.parse", + "status": "static" + }, { "id": "node-builtin.path.posix.relative", "kind": "node-builtin", @@ -1554,6 +1652,12 @@ "name": "path/win32.extname", "status": "static" }, + { + "id": "node-builtin.path.win32.format", + "kind": "node-builtin", + "name": "path/win32.format", + "status": "static" + }, { "id": "node-builtin.path.win32.isAbsolute", "kind": "node-builtin", @@ -1572,6 +1676,12 @@ "name": "path/win32.normalize", "status": "static" }, + { + "id": "node-builtin.path.win32.parse", + "kind": "node-builtin", + "name": "path/win32.parse", + "status": "static" + }, { "id": "node-builtin.path.win32.relative", "kind": "node-builtin", diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/5140-os-host-facts.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/5140-os-host-facts.ts.json new file mode 100644 index 000000000..51995ea82 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/5140-os-host-facts.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/5140-os-host-facts.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/5141-os-constants.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/5141-os-constants.ts.json new file mode 100644 index 000000000..10b9e0b55 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/5141-os-constants.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/5141-os-constants.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/5142-path-parse-format.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/5142-path-parse-format.ts.json new file mode 100644 index 000000000..a56cda8d5 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/5142-path-parse-format.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/5142-path-parse-format.ts" + ], + "diags": [] +} diff --git a/packages/runtime-darwin-arm64/runtime-pack-matrix.mjs b/packages/runtime-darwin-arm64/runtime-pack-matrix.mjs index b57cdb8f0..a0e7d554c 100644 --- a/packages/runtime-darwin-arm64/runtime-pack-matrix.mjs +++ b/packages/runtime-darwin-arm64/runtime-pack-matrix.mjs @@ -31,6 +31,7 @@ const BASE_RUNTIME_SOURCES = [ "scr_console.c", "scr_lib.c", "scr_path.c", + "scr_os.c", "scr_url.c", "scr_url_params.c", "scr_json.c", diff --git a/packages/runtime-pack-common/runtime-pack-matrix.mjs b/packages/runtime-pack-common/runtime-pack-matrix.mjs index 70072e085..1c3b33462 100644 --- a/packages/runtime-pack-common/runtime-pack-matrix.mjs +++ b/packages/runtime-pack-common/runtime-pack-matrix.mjs @@ -29,6 +29,7 @@ const BASE_RUNTIME_SOURCES = [ "scr_console.c", "scr_lib.c", "scr_path.c", + "scr_os.c", "scr_url.c", "scr_url_params.c", "scr_json.c", diff --git a/packages/runtime/src/scr_os.c b/packages/runtime/src/scr_os.c new file mode 100644 index 000000000..0bc50fb3f --- /dev/null +++ b/packages/runtime/src/scr_os.c @@ -0,0 +1,1288 @@ +/* node:os host facts: hostname, machine, version, endianness, freemem, + * uptime, loadavg, getPriority, cpus and constants. Each answer follows the + * libuv 1.51 routine Node delegates to, platform by platform; strings come + * back +1 fresh and nothing here throws except getPriority. */ +#if defined(__linux__) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE 1 /* memmem */ +#endif +#include "scr_runtime.h" +#include "scr_system_errors.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include /* BEFORE windows.h (which pulls winsock 1 otherwise) */ +#include +#elif !defined(__wasi__) +#include +#include +#include +#include +#include +#endif +#ifdef __linux__ +#include +#endif +#ifdef __APPLE__ +#include +#include +#endif + +/* ── shared helpers ─────────────────────────────────────────────────── */ + +static void scr_os_oom(void) { scr_trap("scriptc: out of memory\n"); } + +#ifdef _WIN32 +/* UTF-16 to a fresh UTF-8 string (n units, or NUL-terminated when n < 0). */ +static ScrStr *scr_os_utf16(const WCHAR *text, int n) { + int bytes = WideCharToMultiByte(CP_UTF8, 0, text, n, NULL, 0, NULL, NULL); + if (bytes <= 0) return scr_str_new("", 0); + char *buf = malloc((size_t)bytes); + if (!buf) scr_os_oom(); + WideCharToMultiByte(CP_UTF8, 0, text, n, buf, bytes, NULL, NULL); + size_t len = (size_t)bytes; + if (n < 0 && len > 0) len--; /* the converted NUL */ + ScrStr *out = scr_str_new(buf, len); + free(buf); + return out; +} +#endif + +#ifdef __linux__ +/* libuv's uv__slurp: one read of at most cap - 1 bytes, NUL-terminated. */ +static bool scr_os_read_file(const char *path, char *buf, size_t cap) { + int fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) return false; + ssize_t n; + do + n = read(fd, buf, cap - 1); + while (n < 0 && errno == EINTR); + close(fd); + if (n < 0) return false; + buf[n] = '\0'; + return true; +} +#endif + +/* ── uname, hostname, endianness ────────────────────────────────────── + * Node reads uv_os_uname once at module load; the fields are 256-byte + * buffers there, so longer values fail rather than truncate. */ + +#if !defined(_WIN32) && !defined(__wasi__) +static ScrStr *scr_os_uname_field(int which) { + struct utsname u; + if (uname(&u) != 0) return scr_str_new("", 0); + const char *field = which == 0 ? u.machine : u.version; + size_t len = strlen(field); + return len < 256 ? scr_str_new(field, len) : scr_str_new("", 0); +} +#endif + +ScrStr *scr_os_machine(void) { +#ifdef _WIN32 + /* uv_os_uname's processor-architecture switch; it has no ARM64 case. */ + SYSTEM_INFO info; + GetSystemInfo(&info); + switch (info.wProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_AMD64: return scr_str_new("x86_64", 6); + case PROCESSOR_ARCHITECTURE_IA64: return scr_str_new("ia64", 4); + case PROCESSOR_ARCHITECTURE_INTEL: { + char machine[5] = "i386"; + if (info.wProcessorLevel > 3) machine[1] = (char)('0' + (info.wProcessorLevel < 6 ? info.wProcessorLevel : 6)); + return scr_str_new(machine, 4); + } + case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: return scr_str_new("i686", 4); + case PROCESSOR_ARCHITECTURE_ARM: return scr_str_new("arm", 3); + default: return scr_str_new("unknown", 7); + } +#elif defined(__wasi__) + return scr_str_new("wasm32", 6); +#else + return scr_os_uname_field(0); +#endif +} + +ScrStr *scr_os_version(void) { +#ifdef _WIN32 + /* uv_os_uname: the registry ProductName, with Windows 11 builds (>= + * 22000) relabelled from "Windows 10", then the service pack text. */ + typedef LONG(WINAPI * RtlGetVersionFn)(PRTL_OSVERSIONINFOW); + RTL_OSVERSIONINFOW info; + memset(&info, 0, sizeof info); + info.dwOSVersionInfoSize = sizeof info; + HMODULE ntdll = GetModuleHandleA("ntdll.dll"); + RtlGetVersionFn get = ntdll ? (RtlGetVersionFn)(void *)GetProcAddress(ntdll, "RtlGetVersion") : NULL; + if (get) get(&info); + WCHAR product[256]; + DWORD size = sizeof product; + HKEY key; + ScrStr *version = scr_str_new("", 0); + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, + KEY_QUERY_VALUE | KEY_WOW64_64KEY, &key) == ERROR_SUCCESS) { + LSTATUS r = RegGetValueW(key, NULL, L"ProductName", RRF_RT_REG_SZ, NULL, product, &size); + RegCloseKey(key); + if (r == ERROR_SUCCESS) { + if (info.dwMajorVersion == 10 && info.dwBuildNumber >= 22000 && size >= sizeof L"Windows 10" && + wcsncmp(product, L"Windows 10", 10) == 0) + product[9] = L'1'; + scr_str_release(version); + version = scr_os_utf16(product, -1); + } + } + if (info.szCSDVersion[0] != L'\0') { + ScrStr *pack = scr_os_utf16(info.szCSDVersion, -1); + ScrJsonBuf b; + scr_jb_init(&b); + scr_jb_put_str(&b, version); + if (version->len > 0) scr_jb_putc(&b, ' '); + scr_jb_put_str(&b, pack); + scr_str_release(pack); + scr_str_release(version); + version = scr_jb_finish(&b); + } + return version; +#elif defined(__wasi__) + return scr_str_new("", 0); +#else + return scr_os_uname_field(1); +#endif +} + +ScrStr *scr_os_hostname(void) { +#ifdef _WIN32 + WCHAR buf[257]; + typedef int(WSAAPI * GetHostNameWFn)(PWSTR, int); + HMODULE ws2 = LoadLibraryA("ws2_32.dll"); + GetHostNameWFn get = ws2 ? (GetHostNameWFn)(void *)GetProcAddress(ws2, "GetHostNameW") : NULL; + if (get) { + WSADATA wsa; + WSAStartup(MAKEWORD(2, 2), &wsa); + if (get(buf, 257) == 0) return scr_os_utf16(buf, -1); + } + return scr_str_new("", 0); +#elif defined(__wasi__) + return scr_str_new("localhost", 9); +#else + char buf[257]; /* UV_MAXHOSTNAMESIZE */ + if (gethostname(buf, sizeof buf) != 0) return scr_str_new("", 0); + buf[sizeof buf - 1] = '\0'; + return scr_str_new(buf, strlen(buf)); +#endif +} + +ScrStr *scr_os_endianness(void) { + const uint16_t probe = 1; + return *(const uint8_t *)&probe ? scr_str_new("LE", 2) : scr_str_new("BE", 2); +} + +/* ── memory, uptime, load ───────────────────────────────────────────── */ + +double scr_os_freemem(void) { +#ifdef _WIN32 + MEMORYSTATUSEX status; + status.dwLength = sizeof status; + return GlobalMemoryStatusEx(&status) ? (double)status.ullAvailPhys : 0; +#elif defined(__linux__) + /* MemAvailable from /proc/meminfo, else sysinfo's free RAM. */ + char buf[4096]; + if (scr_os_read_file("/proc/meminfo", buf, sizeof buf)) { + const char *p = strstr(buf, "MemAvailable:"); + if (p) { + unsigned long long kb = 0; + sscanf(p + 13, "%llu kB", &kb); + if (kb != 0) return (double)(kb * 1024); + } + } + struct sysinfo info; + if (sysinfo(&info) == 0) return (double)((unsigned long long)info.freeram * info.mem_unit); + return 0; +#elif defined(__APPLE__) + vm_statistics_data_t info; + mach_msg_type_number_t count = sizeof info / sizeof(integer_t); + if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&info, &count) != KERN_SUCCESS) + return 0; + return (double)((uint64_t)info.free_count * (uint64_t)sysconf(_SC_PAGESIZE)); +#else + return 0; +#endif +} + +double scr_os_uptime(void) { +#ifdef _WIN32 + return (double)GetTickCount64() / 1000.0; +#elif defined(__linux__) + /* /proc/uptime's first field (fractional seconds), else CLOCK_BOOTTIME's + * whole seconds. */ + char buf[128]; + double uptime; + if (scr_os_read_file("/proc/uptime", buf, sizeof buf) && sscanf(buf, "%lf", &uptime) == 1) + return uptime; + struct timespec now; + if (clock_gettime(CLOCK_BOOTTIME, &now) != 0) return 0; + return (double)now.tv_sec; +#elif defined(__APPLE__) + struct timeval boot; + size_t size = sizeof boot; + int which[] = { CTL_KERN, KERN_BOOTTIME }; + if (sysctl(which, 2, &boot, &size, NULL, 0) != 0) return 0; + return (double)(time(NULL) - boot.tv_sec); +#else + return 0; +#endif +} + +ScrArr *scr_os_loadavg(void) { + double avg[3] = { 0, 0, 0 }; +#if defined(__linux__) + char buf[128]; + if (!scr_os_read_file("/proc/loadavg", buf, sizeof buf) || + sscanf(buf, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]) != 3) { + struct sysinfo info; + if (sysinfo(&info) == 0) { + avg[0] = (double)info.loads[0] / 65536.0; + avg[1] = (double)info.loads[1] / 65536.0; + avg[2] = (double)info.loads[2] / 65536.0; + } + } +#elif defined(__APPLE__) + struct loadavg info; + size_t size = sizeof info; + int which[] = { CTL_VM, VM_LOADAVG }; + if (sysctl(which, 2, &info, &size, NULL, 0) == 0) { + avg[0] = (double)info.ldavg[0] / info.fscale; + avg[1] = (double)info.ldavg[1] / info.fscale; + avg[2] = (double)info.ldavg[2] / info.fscale; + } +#endif + ScrArr *out = scr_arr_new(SCR_ELEM_F64, 3); + for (int i = 0; i < 3; i++) scr_arr_push_f64(out, avg[i]); + return out; +} + +/* ── getPriority ────────────────────────────────────────────────────── + * validateInt32(pid, 'pid') (an omitted pid is 0 at the call site), then + * uv_os_getpriority; a failure is Node's ERR_SYSTEM_ERROR. */ + +enum { SCR_OS_PRIORITY_LOW = 19, SCR_OS_PRIORITY_BELOW_NORMAL = 10, SCR_OS_PRIORITY_NORMAL = 0, + SCR_OS_PRIORITY_ABOVE_NORMAL = -7, SCR_OS_PRIORITY_HIGH = -14, SCR_OS_PRIORITY_HIGHEST = -20 }; + +typedef struct { int value; const char *name; const char *message; } ScrOsUvError; +#define SCR_OS_UV_ERROR(name, message) { SCR_NODE_UV__##name, #name, message }, +static const ScrOsUvError scr_os_uv_errors[] = { SCR_NODE_UV_ERRNO_MAP(SCR_OS_UV_ERROR) }; +#undef SCR_OS_UV_ERROR + +static void scr_os_system_error(const char *syscall, int uv_code) { + const char *name = "UNKNOWN", *message = "unknown error"; + for (size_t i = 0; i < sizeof scr_os_uv_errors / sizeof scr_os_uv_errors[0]; i++) { + if (scr_os_uv_errors[i].value == uv_code) { + name = scr_os_uv_errors[i].name; + message = scr_os_uv_errors[i].message; + break; + } + } + char text[256]; + int n = snprintf(text, sizeof text, "A system error occurred: %s returned %s (%s)", syscall, name, message); + ScrStr *msg = scr_str_new(text, n < 0 ? 0 : (size_t)n); + ScrStr *error_name = scr_str_new("SystemError", 11); + scr_throw_error_named(error_name, msg); + ScrExcCell *cell = scr_exc_current_cell(); + if (cell->kind == SCR_EXC_OBJ) scr_error_set_code((ScrError *)cell->payload, "ERR_SYSTEM_ERROR"); +} + +static bool scr_os_validate_int32(const char *name, double value) { + if (isfinite(value) && trunc(value) == value) { + if (value >= -2147483648.0 && value <= 2147483647.0) return true; + } + char received[48]; + scr_num_received(value, received); + char text[192]; + int n = isfinite(value) && trunc(value) == value + ? snprintf(text, sizeof text, + "The value of \"%s\" is out of range. It must be >= -2147483648 && <= 2147483647. Received %s", + name, received) + : snprintf(text, sizeof text, "The value of \"%s\" is out of range. It must be an integer. Received %s", + name, received); + scr_throw_error_msg_code(SCR_ERR_RANGE, text, n < 0 ? 0 : (size_t)n, "ERR_OUT_OF_RANGE"); + return false; +} + +double scr_os_get_priority(double pid) { + if (!scr_os_validate_int32("pid", pid)) return 0; +#ifdef _WIN32 + HANDLE handle = pid == 0 ? GetCurrentProcess() + : OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)(int)pid); + if (handle == NULL) { + DWORD err = GetLastError(); + scr_os_system_error("uv_os_getpriority", err == ERROR_ACCESS_DENIED ? SCR_NODE_UV__EPERM + : err == ERROR_INVALID_PARAMETER ? SCR_NODE_UV__EINVAL + : SCR_NODE_UV__UNKNOWN); + return 0; + } + DWORD klass = GetPriorityClass(handle); + if (pid != 0) CloseHandle(handle); + if (klass == 0) { + scr_os_system_error("uv_os_getpriority", SCR_NODE_UV__UNKNOWN); + return 0; + } + if (klass == REALTIME_PRIORITY_CLASS) return SCR_OS_PRIORITY_HIGHEST; + if (klass == HIGH_PRIORITY_CLASS) return SCR_OS_PRIORITY_HIGH; + if (klass == ABOVE_NORMAL_PRIORITY_CLASS) return SCR_OS_PRIORITY_ABOVE_NORMAL; + if (klass == NORMAL_PRIORITY_CLASS) return SCR_OS_PRIORITY_NORMAL; + if (klass == BELOW_NORMAL_PRIORITY_CLASS) return SCR_OS_PRIORITY_BELOW_NORMAL; + return SCR_OS_PRIORITY_LOW; +#elif defined(__wasi__) + scr_os_system_error("uv_os_getpriority", SCR_NODE_UV__ENOSYS); + return 0; +#else + errno = 0; + int r = getpriority(PRIO_PROCESS, (id_t)(int)pid); + if (r == -1 && errno != 0) { + scr_os_system_error("uv_os_getpriority", SCR_NODE_UV__ERR(errno)); + return 0; + } + return r; +#endif +} + +/* ── cpus ───────────────────────────────────────────────────────────── + * uv_cpu_info, snapshotted once per os.cpus() call: scr_os_cpus_take + * reads every CPU and answers the count; the accessors read that + * snapshot (the compiler builds the CpuInfo records from them). Field k: + * 0 speed, 1 user, 2 nice, 3 sys, 4 idle, 5 irq. A failed read is the + * empty list (Node's `getCPUs() || []`). */ + +typedef struct { + ScrStr *model; + double fields[6]; +} ScrOsCpu; + +static SCR_TL ScrOsCpu *scr_os_cpus; +static SCR_TL size_t scr_os_cpus_len; +static SCR_TL bool scr_os_cpus_armed; + +static void scr_os_cpus_clear(void) { + for (size_t i = 0; i < scr_os_cpus_len; i++) scr_str_release(scr_os_cpus[i].model); + free(scr_os_cpus); + scr_os_cpus = NULL; + scr_os_cpus_len = 0; +} + +#if defined(__linux__) || defined(__APPLE__) +/* V8's OneByteString: each byte is one Latin-1 code point. */ +static ScrStr *scr_os_latin1(const char *p, size_t n) { + size_t extra = 0; + for (size_t i = 0; i < n; i++) extra += (unsigned char)p[i] >= 0x80; + if (extra == 0) return scr_str_new(p, n); + char *buf = malloc(n + extra); + if (!buf) scr_os_oom(); + size_t w = 0; + for (size_t i = 0; i < n; i++) { + unsigned char c = (unsigned char)p[i]; + if (c < 0x80) { + buf[w++] = (char)c; + } else { + buf[w++] = (char)(0xC0 | (c >> 6)); + buf[w++] = (char)(0x80 | (c & 0x3F)); + } + } + ScrStr *out = scr_str_new(buf, w); + free(buf); + return out; +} +#endif + +static ScrOsCpu *scr_os_cpus_alloc(size_t n) { + ScrOsCpu *cpus = calloc(n ? n : 1, sizeof *cpus); + if (!cpus) scr_os_oom(); + return cpus; +} + +#if defined(__linux__) +/* libuv's /proc/cpuinfo model markers, and the arm64 part-number names. */ +#if defined(__PPC__) +#define SCR_OS_MODEL_MARKER "cpu\t\t: " +#define SCR_OS_MODEL_MARKER2 "" +#elif defined(__arm__) +#define SCR_OS_MODEL_MARKER "model name\t: " +#define SCR_OS_MODEL_MARKER2 "Processor\t: " +#elif defined(__aarch64__) +#define SCR_OS_MODEL_MARKER "CPU part\t: " +#define SCR_OS_MODEL_MARKER2 "" +#elif defined(__mips__) +#define SCR_OS_MODEL_MARKER "cpu model\t\t: " +#define SCR_OS_MODEL_MARKER2 "" +#elif defined(__loongarch__) +#define SCR_OS_MODEL_MARKER "cpu family\t\t: " +#define SCR_OS_MODEL_MARKER2 "" +#else +#define SCR_OS_MODEL_MARKER "model name\t: " +#define SCR_OS_MODEL_MARKER2 "" +#endif +static const char scr_os_cpu_parts[] = +#ifdef __aarch64__ + "0x811\nARM810\n" "0x920\nARM920\n" "0x922\nARM922\n" + "0x926\nARM926\n" "0x940\nARM940\n" "0x946\nARM946\n" + "0x966\nARM966\n" "0xa20\nARM1020\n" "0xa22\nARM1022\n" + "0xa26\nARM1026\n" "0xb02\nARM11 MPCore\n" "0xb36\nARM1136\n" + "0xb56\nARM1156\n" "0xb76\nARM1176\n" "0xc05\nCortex-A5\n" + "0xc07\nCortex-A7\n" "0xc08\nCortex-A8\n" "0xc09\nCortex-A9\n" + "0xc0d\nCortex-A17\n" /* Originally A12 */ + "0xc0f\nCortex-A15\n" "0xc0e\nCortex-A17\n" "0xc14\nCortex-R4\n" + "0xc15\nCortex-R5\n" "0xc17\nCortex-R7\n" "0xc18\nCortex-R8\n" + "0xc20\nCortex-M0\n" "0xc21\nCortex-M1\n" "0xc23\nCortex-M3\n" + "0xc24\nCortex-M4\n" "0xc27\nCortex-M7\n" "0xc60\nCortex-M0+\n" + "0xd01\nCortex-A32\n" "0xd03\nCortex-A53\n" "0xd04\nCortex-A35\n" + "0xd05\nCortex-A55\n" "0xd06\nCortex-A65\n" "0xd07\nCortex-A57\n" + "0xd08\nCortex-A72\n" "0xd09\nCortex-A73\n" "0xd0a\nCortex-A75\n" + "0xd0b\nCortex-A76\n" "0xd0c\nNeoverse-N1\n" "0xd0d\nCortex-A77\n" + "0xd0e\nCortex-A76AE\n" "0xd13\nCortex-R52\n" "0xd20\nCortex-M23\n" + "0xd21\nCortex-M33\n" "0xd41\nCortex-A78\n" "0xd42\nCortex-A78AE\n" + "0xd4a\nNeoverse-E1\n" "0xd4b\nCortex-A78C\n" +#endif + ""; + +static size_t scr_os_cpus_read(ScrOsCpu **out) { + enum { MAX_CPUS = 8192 }; + struct cpu { unsigned long long freq, user, nice, sys, idle, irq; unsigned model; }; + struct cpu *cpus = calloc(MAX_CPUS, sizeof *cpus); + unsigned char *bitmap = calloc(MAX_CPUS / 8, 1); + if (!cpus || !bitmap) scr_os_oom(); + char models[8][64]; + char buf[1024]; + memset(models, 0, sizeof models); + snprintf(models[0], sizeof models[0], "unknown"); + unsigned maxcpu = 0, cpu; + size_t n = 0; + FILE *fp = fopen("/proc/stat", "re"); + if (fp == NULL) goto done; + if (fgets(buf, sizeof buf, fp) == NULL) { + fclose(fp); + goto done; + } + for (;;) { + struct cpu t; + unsigned long long skip; + memset(&t, 0, sizeof t); + if (fscanf(fp, "cpu%u %llu %llu %llu %llu %llu %llu", &cpu, &t.user, &t.nice, &t.sys, &t.idle, + &skip, &t.irq) != 7) + break; + if (fgets(buf, sizeof buf, fp) == NULL) break; + if (cpu >= MAX_CPUS) continue; + cpus[cpu] = t; + bitmap[cpu >> 3] |= (unsigned char)(1 << (cpu & 7)); + if (cpu >= maxcpu) maxcpu = cpu + 1; + } + fclose(fp); + /* Model names: libuv's scan, including its matching rule (a model slot + * matches when the name starts with its text; the first empty slot + * matches anything, and the slot after the match is used). */ + fp = fopen("/proc/cpuinfo", "re"); + if (fp != NULL) { + for (;;) { + if (fscanf(fp, "processor\t: %u\n", &cpu) != 1) break; + const char *p = NULL; + while (fgets(buf, sizeof buf, fp)) { + if (!strncmp(buf, SCR_OS_MODEL_MARKER, sizeof SCR_OS_MODEL_MARKER - 1)) { + p = buf + sizeof SCR_OS_MODEL_MARKER - 1; + break; + } + if (!*SCR_OS_MODEL_MARKER2) continue; + if (!strncmp(buf, SCR_OS_MODEL_MARKER2, sizeof SCR_OS_MODEL_MARKER2 - 1)) { + p = buf + sizeof SCR_OS_MODEL_MARKER2 - 1; + break; + } + } + if (p != NULL) { + int len = (int)strcspn(p, "\n"); + if (*scr_os_cpu_parts) { + const char *hit = memmem(scr_os_cpu_parts, sizeof scr_os_cpu_parts - 1, p, (size_t)len + 1); + p = hit == NULL ? "unknown" : hit + len + 1; + len = (int)strcspn(p, "\n"); + } + int found = 0; + char (*model)[64]; + for (model = models; !found && model < models + 8; model++) + found = !strncmp(p, *model, strlen(*model)); + if (found) { + if (**model == '\0') snprintf(*model, sizeof *model, "%.*s", len, p); + if (cpu < maxcpu) cpus[cpu].model = (unsigned)(model - models); + } + } + while (fgets(buf, sizeof buf, fp)) + if (*buf == '\n') break; + } + fclose(fp); + } + for (cpu = 0; cpu < maxcpu; cpu++) { + if (!(bitmap[cpu >> 3] & (1 << (cpu & 7)))) continue; + n++; + snprintf(buf, sizeof buf, "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", cpu); + fp = fopen(buf, "re"); + if (fp == NULL) continue; + if (fscanf(fp, "%llu", &cpus[cpu].freq) != 1) cpus[cpu].freq = 0; + fclose(fp); + } + *out = scr_os_cpus_alloc(n); + size_t i = 0; + for (cpu = 0; cpu < maxcpu; cpu++) { + if (!(bitmap[cpu >> 3] & (1 << (cpu & 7)))) continue; + const struct cpu *c = &cpus[cpu]; + const char *name = c->model < 8 ? models[c->model] : models[0]; + (*out)[i].model = scr_os_latin1(name, strlen(name)); + (*out)[i].fields[0] = (double)(c->freq / 1000); + /* sysconf(_SC_CLK_TCK) is fixed at 100: the multiplier is always 10. */ + (*out)[i].fields[1] = (double)(10 * c->user); + (*out)[i].fields[2] = (double)(10 * c->nice); + (*out)[i].fields[3] = (double)(10 * c->sys); + (*out)[i].fields[4] = (double)(10 * c->idle); + (*out)[i].fields[5] = (double)(10 * c->irq); + i++; + } +done: + free(cpus); + free(bitmap); + return n; +} +#elif defined(__APPLE__) +static size_t scr_os_cpus_read(ScrOsCpu **out) { + unsigned ticks = (unsigned)sysconf(_SC_CLK_TCK); + uint64_t multiplier = (uint64_t)1000L / ticks; + char model[512]; + size_t size = sizeof model; + if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) && + sysctlbyname("hw.model", &model, &size, NULL, 0)) + return 0; + uint64_t speed = 0; + size = sizeof speed; + sysctlbyname("hw.cpufrequency", &speed, &size, NULL, 0); + if (speed == 0) speed = 2400000000U; + natural_t count; + mach_msg_type_number_t msg_type; + processor_cpu_load_info_data_t *info; + if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &count, + (processor_info_array_t *)&info, &msg_type) != KERN_SUCCESS) + return 0; + *out = scr_os_cpus_alloc(count); + for (natural_t i = 0; i < count; i++) { + (*out)[i].model = scr_os_latin1(model, strlen(model)); + (*out)[i].fields[0] = (double)(int)(speed / 1000000); + (*out)[i].fields[1] = (double)((uint64_t)info[i].cpu_ticks[0] * multiplier); + (*out)[i].fields[2] = (double)((uint64_t)info[i].cpu_ticks[3] * multiplier); + (*out)[i].fields[3] = (double)((uint64_t)info[i].cpu_ticks[1] * multiplier); + (*out)[i].fields[4] = (double)((uint64_t)info[i].cpu_ticks[2] * multiplier); + (*out)[i].fields[5] = 0; + } + vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); + return count; +} +#elif defined(_WIN32) +typedef struct { + LARGE_INTEGER IdleTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER DpcTime; + LARGE_INTEGER InterruptTime; + ULONG InterruptCount; +} ScrOsProcessorTimes; + +static size_t scr_os_cpus_read(ScrOsCpu **out) { + typedef LONG(NTAPI * QueryFn)(int, PVOID, ULONG, PULONG); + HMODULE ntdll = GetModuleHandleA("ntdll.dll"); + QueryFn query = ntdll ? (QueryFn)(void *)GetProcAddress(ntdll, "NtQuerySystemInformation") : NULL; + if (query == NULL) return 0; + SYSTEM_INFO system; + GetSystemInfo(&system); + DWORD count = system.dwNumberOfProcessors; + ScrOsProcessorTimes *times = calloc(count ? count : 1, sizeof *times); + if (!times) scr_os_oom(); + ULONG got = 0; + /* SystemProcessorPerformanceInformation */ + if (query(8, times, (ULONG)(count * sizeof *times), &got) < 0) { + free(times); + return 0; + } + ScrOsCpu *cpus = scr_os_cpus_alloc(count); + for (DWORD i = 0; i < count; i++) { + WCHAR key_name[128]; + _snwprintf(key_name, 128, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", (int)i); + HKEY key; + DWORD speed = 0, speed_size = sizeof speed; + WCHAR brand[256]; + DWORD brand_size = sizeof brand; + bool ok = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_name, 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS; + if (ok) { + ok = RegQueryValueExW(key, L"~MHz", NULL, NULL, (BYTE *)&speed, &speed_size) == ERROR_SUCCESS && + RegQueryValueExW(key, L"ProcessorNameString", NULL, NULL, (BYTE *)brand, &brand_size) == ERROR_SUCCESS; + RegCloseKey(key); + } + if (!ok) { + for (DWORD j = 0; j < i; j++) scr_str_release(cpus[j].model); + free(cpus); + free(times); + return 0; + } + cpus[i].model = scr_os_utf16(brand, (int)(brand_size / sizeof(WCHAR))); + if (cpus[i].model->len > 0 && cpus[i].model->data[cpus[i].model->len - 1] == '\0') { + ScrStr *trimmed = scr_str_new(cpus[i].model->data, cpus[i].model->len - 1); + scr_str_release(cpus[i].model); + cpus[i].model = trimmed; + } + cpus[i].fields[0] = (double)speed; + cpus[i].fields[1] = (double)(times[i].UserTime.QuadPart / 10000); + cpus[i].fields[2] = 0; + cpus[i].fields[3] = (double)((times[i].KernelTime.QuadPart - times[i].IdleTime.QuadPart) / 10000); + cpus[i].fields[4] = (double)(times[i].IdleTime.QuadPart / 10000); + cpus[i].fields[5] = (double)(times[i].InterruptTime.QuadPart / 10000); + } + free(times); + *out = cpus; + return count; +} +#else +static size_t scr_os_cpus_read(ScrOsCpu **out) { + *out = scr_os_cpus_alloc(0); + return 0; +} +#endif + +double scr_os_cpus_take(void) { + scr_os_cpus_clear(); + if (!scr_os_cpus_armed) { + scr_os_cpus_armed = true; + scr_atexit(scr_os_cpus_clear); + } + ScrOsCpu *cpus = NULL; + size_t n = scr_os_cpus_read(&cpus); + scr_os_cpus = cpus; + scr_os_cpus_len = cpus ? n : 0; + return (double)scr_os_cpus_len; +} + +ScrStr *scr_os_cpus_model(double i) { + size_t k = (size_t)i; + return k < scr_os_cpus_len ? scr_str_retain(scr_os_cpus[k].model) : scr_str_new("", 0); +} + +double scr_os_cpus_field(double i, double field) { + size_t k = (size_t)i, f = (size_t)field; + return k < scr_os_cpus_len && f < 6 ? scr_os_cpus[k].fields[f] : 0; +} + +/* ── constants ──────────────────────────────────────────────────────── + * internalBinding('constants').os: null-prototype objects whose numeric + * members are read-only and non-configurable, in node_constants.cc's + * order and with its #ifdef guards over the platform headers; libuv + * supplies the priority values and, on Windows, SIGHUP/SIGKILL/SIGWINCH. + * lib/os.js freezes `signals`. One object per thread: os.constants is + * the same value on every read. */ + +#ifdef _WIN32 +#ifndef SIGHUP +#define SIGHUP 1 +#endif +#ifndef SIGKILL +#define SIGKILL 9 +#endif +#ifndef SIGWINCH +#define SIGWINCH 28 +#endif +#endif + +static void scr_os_constant(ScrDyn *o, const char *name, double value) { + scr_dyn_obj_set(o, name, strlen(name), scr_dyn_new_num(value)); + ScrDynEntry *entry = &o->v.obj.entries[o->v.obj.len - 1]; + entry->writable = false; + entry->configurable = false; +} +#define SCR_OS_CONSTANT(o, name) scr_os_constant((o), #name, (double)(name)) + +static void scr_os_errno_constants(ScrDyn *o) { +#ifdef E2BIG + SCR_OS_CONSTANT(o, E2BIG); +#endif +#ifdef EACCES + SCR_OS_CONSTANT(o, EACCES); +#endif +#ifdef EADDRINUSE + SCR_OS_CONSTANT(o, EADDRINUSE); +#endif +#ifdef EADDRNOTAVAIL + SCR_OS_CONSTANT(o, EADDRNOTAVAIL); +#endif +#ifdef EAFNOSUPPORT + SCR_OS_CONSTANT(o, EAFNOSUPPORT); +#endif +#ifdef EAGAIN + SCR_OS_CONSTANT(o, EAGAIN); +#endif +#ifdef EALREADY + SCR_OS_CONSTANT(o, EALREADY); +#endif +#ifdef EBADF + SCR_OS_CONSTANT(o, EBADF); +#endif +#ifdef EBADMSG + SCR_OS_CONSTANT(o, EBADMSG); +#endif +#ifdef EBUSY + SCR_OS_CONSTANT(o, EBUSY); +#endif +#ifdef ECANCELED + SCR_OS_CONSTANT(o, ECANCELED); +#endif +#ifdef ECHILD + SCR_OS_CONSTANT(o, ECHILD); +#endif +#ifdef ECONNABORTED + SCR_OS_CONSTANT(o, ECONNABORTED); +#endif +#ifdef ECONNREFUSED + SCR_OS_CONSTANT(o, ECONNREFUSED); +#endif +#ifdef ECONNRESET + SCR_OS_CONSTANT(o, ECONNRESET); +#endif +#ifdef EDEADLK + SCR_OS_CONSTANT(o, EDEADLK); +#endif +#ifdef EDESTADDRREQ + SCR_OS_CONSTANT(o, EDESTADDRREQ); +#endif +#ifdef EDOM + SCR_OS_CONSTANT(o, EDOM); +#endif +#ifdef EDQUOT + SCR_OS_CONSTANT(o, EDQUOT); +#endif +#ifdef EEXIST + SCR_OS_CONSTANT(o, EEXIST); +#endif +#ifdef EFAULT + SCR_OS_CONSTANT(o, EFAULT); +#endif +#ifdef EFBIG + SCR_OS_CONSTANT(o, EFBIG); +#endif +#ifdef EHOSTUNREACH + SCR_OS_CONSTANT(o, EHOSTUNREACH); +#endif +#ifdef EIDRM + SCR_OS_CONSTANT(o, EIDRM); +#endif +#ifdef EILSEQ + SCR_OS_CONSTANT(o, EILSEQ); +#endif +#ifdef EINPROGRESS + SCR_OS_CONSTANT(o, EINPROGRESS); +#endif +#ifdef EINTR + SCR_OS_CONSTANT(o, EINTR); +#endif +#ifdef EINVAL + SCR_OS_CONSTANT(o, EINVAL); +#endif +#ifdef EIO + SCR_OS_CONSTANT(o, EIO); +#endif +#ifdef EISCONN + SCR_OS_CONSTANT(o, EISCONN); +#endif +#ifdef EISDIR + SCR_OS_CONSTANT(o, EISDIR); +#endif +#ifdef ELOOP + SCR_OS_CONSTANT(o, ELOOP); +#endif +#ifdef EMFILE + SCR_OS_CONSTANT(o, EMFILE); +#endif +#ifdef EMLINK + SCR_OS_CONSTANT(o, EMLINK); +#endif +#ifdef EMSGSIZE + SCR_OS_CONSTANT(o, EMSGSIZE); +#endif +#ifdef EMULTIHOP + SCR_OS_CONSTANT(o, EMULTIHOP); +#endif +#ifdef ENAMETOOLONG + SCR_OS_CONSTANT(o, ENAMETOOLONG); +#endif +#ifdef ENETDOWN + SCR_OS_CONSTANT(o, ENETDOWN); +#endif +#ifdef ENETRESET + SCR_OS_CONSTANT(o, ENETRESET); +#endif +#ifdef ENETUNREACH + SCR_OS_CONSTANT(o, ENETUNREACH); +#endif +#ifdef ENFILE + SCR_OS_CONSTANT(o, ENFILE); +#endif +#ifdef ENOBUFS + SCR_OS_CONSTANT(o, ENOBUFS); +#endif +#ifdef ENODATA + SCR_OS_CONSTANT(o, ENODATA); +#endif +#ifdef ENODEV + SCR_OS_CONSTANT(o, ENODEV); +#endif +#ifdef ENOENT + SCR_OS_CONSTANT(o, ENOENT); +#endif +#ifdef ENOEXEC + SCR_OS_CONSTANT(o, ENOEXEC); +#endif +#ifdef ENOLCK + SCR_OS_CONSTANT(o, ENOLCK); +#endif +#ifdef ENOLINK + SCR_OS_CONSTANT(o, ENOLINK); +#endif +#ifdef ENOMEM + SCR_OS_CONSTANT(o, ENOMEM); +#endif +#ifdef ENOMSG + SCR_OS_CONSTANT(o, ENOMSG); +#endif +#ifdef ENOPROTOOPT + SCR_OS_CONSTANT(o, ENOPROTOOPT); +#endif +#ifdef ENOSPC + SCR_OS_CONSTANT(o, ENOSPC); +#endif +#ifdef ENOSR + SCR_OS_CONSTANT(o, ENOSR); +#endif +#ifdef ENOSTR + SCR_OS_CONSTANT(o, ENOSTR); +#endif +#ifdef ENOSYS + SCR_OS_CONSTANT(o, ENOSYS); +#endif +#ifdef ENOTCONN + SCR_OS_CONSTANT(o, ENOTCONN); +#endif +#ifdef ENOTDIR + SCR_OS_CONSTANT(o, ENOTDIR); +#endif +#ifdef ENOTEMPTY + SCR_OS_CONSTANT(o, ENOTEMPTY); +#endif +#ifdef ENOTSOCK + SCR_OS_CONSTANT(o, ENOTSOCK); +#endif +#ifdef ENOTSUP + SCR_OS_CONSTANT(o, ENOTSUP); +#endif +#ifdef ENOTTY + SCR_OS_CONSTANT(o, ENOTTY); +#endif +#ifdef ENXIO + SCR_OS_CONSTANT(o, ENXIO); +#endif +#ifdef EOPNOTSUPP + SCR_OS_CONSTANT(o, EOPNOTSUPP); +#endif +#ifdef EOVERFLOW + SCR_OS_CONSTANT(o, EOVERFLOW); +#endif +#ifdef EPERM + SCR_OS_CONSTANT(o, EPERM); +#endif +#ifdef EPIPE + SCR_OS_CONSTANT(o, EPIPE); +#endif +#ifdef EPROTO + SCR_OS_CONSTANT(o, EPROTO); +#endif +#ifdef EPROTONOSUPPORT + SCR_OS_CONSTANT(o, EPROTONOSUPPORT); +#endif +#ifdef EPROTOTYPE + SCR_OS_CONSTANT(o, EPROTOTYPE); +#endif +#ifdef ERANGE + SCR_OS_CONSTANT(o, ERANGE); +#endif +#ifdef EROFS + SCR_OS_CONSTANT(o, EROFS); +#endif +#ifdef ESPIPE + SCR_OS_CONSTANT(o, ESPIPE); +#endif +#ifdef ESRCH + SCR_OS_CONSTANT(o, ESRCH); +#endif +#ifdef ESTALE + SCR_OS_CONSTANT(o, ESTALE); +#endif +#ifdef ETIME + SCR_OS_CONSTANT(o, ETIME); +#endif +#ifdef ETIMEDOUT + SCR_OS_CONSTANT(o, ETIMEDOUT); +#endif +#ifdef ETXTBSY + SCR_OS_CONSTANT(o, ETXTBSY); +#endif +#ifdef EWOULDBLOCK + SCR_OS_CONSTANT(o, EWOULDBLOCK); +#endif +#ifdef EXDEV + SCR_OS_CONSTANT(o, EXDEV); +#endif +#ifdef WSAEINTR + SCR_OS_CONSTANT(o, WSAEINTR); +#endif +#ifdef WSAEBADF + SCR_OS_CONSTANT(o, WSAEBADF); +#endif +#ifdef WSAEACCES + SCR_OS_CONSTANT(o, WSAEACCES); +#endif +#ifdef WSAEFAULT + SCR_OS_CONSTANT(o, WSAEFAULT); +#endif +#ifdef WSAEINVAL + SCR_OS_CONSTANT(o, WSAEINVAL); +#endif +#ifdef WSAEMFILE + SCR_OS_CONSTANT(o, WSAEMFILE); +#endif +#ifdef WSAEWOULDBLOCK + SCR_OS_CONSTANT(o, WSAEWOULDBLOCK); +#endif +#ifdef WSAEINPROGRESS + SCR_OS_CONSTANT(o, WSAEINPROGRESS); +#endif +#ifdef WSAEALREADY + SCR_OS_CONSTANT(o, WSAEALREADY); +#endif +#ifdef WSAENOTSOCK + SCR_OS_CONSTANT(o, WSAENOTSOCK); +#endif +#ifdef WSAEDESTADDRREQ + SCR_OS_CONSTANT(o, WSAEDESTADDRREQ); +#endif +#ifdef WSAEMSGSIZE + SCR_OS_CONSTANT(o, WSAEMSGSIZE); +#endif +#ifdef WSAEPROTOTYPE + SCR_OS_CONSTANT(o, WSAEPROTOTYPE); +#endif +#ifdef WSAENOPROTOOPT + SCR_OS_CONSTANT(o, WSAENOPROTOOPT); +#endif +#ifdef WSAEPROTONOSUPPORT + SCR_OS_CONSTANT(o, WSAEPROTONOSUPPORT); +#endif +#ifdef WSAESOCKTNOSUPPORT + SCR_OS_CONSTANT(o, WSAESOCKTNOSUPPORT); +#endif +#ifdef WSAEOPNOTSUPP + SCR_OS_CONSTANT(o, WSAEOPNOTSUPP); +#endif +#ifdef WSAEPFNOSUPPORT + SCR_OS_CONSTANT(o, WSAEPFNOSUPPORT); +#endif +#ifdef WSAEAFNOSUPPORT + SCR_OS_CONSTANT(o, WSAEAFNOSUPPORT); +#endif +#ifdef WSAEADDRINUSE + SCR_OS_CONSTANT(o, WSAEADDRINUSE); +#endif +#ifdef WSAEADDRNOTAVAIL + SCR_OS_CONSTANT(o, WSAEADDRNOTAVAIL); +#endif +#ifdef WSAENETDOWN + SCR_OS_CONSTANT(o, WSAENETDOWN); +#endif +#ifdef WSAENETUNREACH + SCR_OS_CONSTANT(o, WSAENETUNREACH); +#endif +#ifdef WSAENETRESET + SCR_OS_CONSTANT(o, WSAENETRESET); +#endif +#ifdef WSAECONNABORTED + SCR_OS_CONSTANT(o, WSAECONNABORTED); +#endif +#ifdef WSAECONNRESET + SCR_OS_CONSTANT(o, WSAECONNRESET); +#endif +#ifdef WSAENOBUFS + SCR_OS_CONSTANT(o, WSAENOBUFS); +#endif +#ifdef WSAEISCONN + SCR_OS_CONSTANT(o, WSAEISCONN); +#endif +#ifdef WSAENOTCONN + SCR_OS_CONSTANT(o, WSAENOTCONN); +#endif +#ifdef WSAESHUTDOWN + SCR_OS_CONSTANT(o, WSAESHUTDOWN); +#endif +#ifdef WSAETOOMANYREFS + SCR_OS_CONSTANT(o, WSAETOOMANYREFS); +#endif +#ifdef WSAETIMEDOUT + SCR_OS_CONSTANT(o, WSAETIMEDOUT); +#endif +#ifdef WSAECONNREFUSED + SCR_OS_CONSTANT(o, WSAECONNREFUSED); +#endif +#ifdef WSAELOOP + SCR_OS_CONSTANT(o, WSAELOOP); +#endif +#ifdef WSAENAMETOOLONG + SCR_OS_CONSTANT(o, WSAENAMETOOLONG); +#endif +#ifdef WSAEHOSTDOWN + SCR_OS_CONSTANT(o, WSAEHOSTDOWN); +#endif +#ifdef WSAEHOSTUNREACH + SCR_OS_CONSTANT(o, WSAEHOSTUNREACH); +#endif +#ifdef WSAENOTEMPTY + SCR_OS_CONSTANT(o, WSAENOTEMPTY); +#endif +#ifdef WSAEPROCLIM + SCR_OS_CONSTANT(o, WSAEPROCLIM); +#endif +#ifdef WSAEUSERS + SCR_OS_CONSTANT(o, WSAEUSERS); +#endif +#ifdef WSAEDQUOT + SCR_OS_CONSTANT(o, WSAEDQUOT); +#endif +#ifdef WSAESTALE + SCR_OS_CONSTANT(o, WSAESTALE); +#endif +#ifdef WSAEREMOTE + SCR_OS_CONSTANT(o, WSAEREMOTE); +#endif +#ifdef WSASYSNOTREADY + SCR_OS_CONSTANT(o, WSASYSNOTREADY); +#endif +#ifdef WSAVERNOTSUPPORTED + SCR_OS_CONSTANT(o, WSAVERNOTSUPPORTED); +#endif +#ifdef WSANOTINITIALISED + SCR_OS_CONSTANT(o, WSANOTINITIALISED); +#endif +#ifdef WSAEDISCON + SCR_OS_CONSTANT(o, WSAEDISCON); +#endif +#ifdef WSAENOMORE + SCR_OS_CONSTANT(o, WSAENOMORE); +#endif +#ifdef WSAECANCELLED + SCR_OS_CONSTANT(o, WSAECANCELLED); +#endif +#ifdef WSAEINVALIDPROCTABLE + SCR_OS_CONSTANT(o, WSAEINVALIDPROCTABLE); +#endif +#ifdef WSAEINVALIDPROVIDER + SCR_OS_CONSTANT(o, WSAEINVALIDPROVIDER); +#endif +#ifdef WSAEPROVIDERFAILEDINIT + SCR_OS_CONSTANT(o, WSAEPROVIDERFAILEDINIT); +#endif +#ifdef WSASYSCALLFAILURE + SCR_OS_CONSTANT(o, WSASYSCALLFAILURE); +#endif +#ifdef WSASERVICE_NOT_FOUND + SCR_OS_CONSTANT(o, WSASERVICE_NOT_FOUND); +#endif +#ifdef WSATYPE_NOT_FOUND + SCR_OS_CONSTANT(o, WSATYPE_NOT_FOUND); +#endif +#ifdef WSA_E_NO_MORE + SCR_OS_CONSTANT(o, WSA_E_NO_MORE); +#endif +#ifdef WSA_E_CANCELLED + SCR_OS_CONSTANT(o, WSA_E_CANCELLED); +#endif +#ifdef WSAEREFUSED + SCR_OS_CONSTANT(o, WSAEREFUSED); +#endif +} + +static void scr_os_signal_constants(ScrDyn *o) { +#ifdef SIGHUP + SCR_OS_CONSTANT(o, SIGHUP); +#endif +#ifdef SIGINT + SCR_OS_CONSTANT(o, SIGINT); +#endif +#ifdef SIGQUIT + SCR_OS_CONSTANT(o, SIGQUIT); +#endif +#ifdef SIGILL + SCR_OS_CONSTANT(o, SIGILL); +#endif +#ifdef SIGTRAP + SCR_OS_CONSTANT(o, SIGTRAP); +#endif +#ifdef SIGABRT + SCR_OS_CONSTANT(o, SIGABRT); +#endif +#ifdef SIGIOT + SCR_OS_CONSTANT(o, SIGIOT); +#endif +#ifdef SIGBUS + SCR_OS_CONSTANT(o, SIGBUS); +#endif +#ifdef SIGFPE + SCR_OS_CONSTANT(o, SIGFPE); +#endif +#ifdef SIGKILL + SCR_OS_CONSTANT(o, SIGKILL); +#endif +#ifdef SIGUSR1 + SCR_OS_CONSTANT(o, SIGUSR1); +#endif +#ifdef SIGSEGV + SCR_OS_CONSTANT(o, SIGSEGV); +#endif +#ifdef SIGUSR2 + SCR_OS_CONSTANT(o, SIGUSR2); +#endif +#ifdef SIGPIPE + SCR_OS_CONSTANT(o, SIGPIPE); +#endif +#ifdef SIGALRM + SCR_OS_CONSTANT(o, SIGALRM); +#endif +#ifdef SIGTERM + SCR_OS_CONSTANT(o, SIGTERM); +#endif +#ifdef SIGCHLD + SCR_OS_CONSTANT(o, SIGCHLD); +#endif +#ifdef SIGSTKFLT + SCR_OS_CONSTANT(o, SIGSTKFLT); +#endif +#ifdef SIGCONT + SCR_OS_CONSTANT(o, SIGCONT); +#endif +#ifdef SIGSTOP + SCR_OS_CONSTANT(o, SIGSTOP); +#endif +#ifdef SIGTSTP + SCR_OS_CONSTANT(o, SIGTSTP); +#endif +#ifdef SIGBREAK + SCR_OS_CONSTANT(o, SIGBREAK); +#endif +#ifdef SIGTTIN + SCR_OS_CONSTANT(o, SIGTTIN); +#endif +#ifdef SIGTTOU + SCR_OS_CONSTANT(o, SIGTTOU); +#endif +#ifdef SIGURG + SCR_OS_CONSTANT(o, SIGURG); +#endif +#ifdef SIGXCPU + SCR_OS_CONSTANT(o, SIGXCPU); +#endif +#ifdef SIGXFSZ + SCR_OS_CONSTANT(o, SIGXFSZ); +#endif +#ifdef SIGVTALRM + SCR_OS_CONSTANT(o, SIGVTALRM); +#endif +#ifdef SIGPROF + SCR_OS_CONSTANT(o, SIGPROF); +#endif +#ifdef SIGWINCH + SCR_OS_CONSTANT(o, SIGWINCH); +#endif +#ifdef SIGIO + SCR_OS_CONSTANT(o, SIGIO); +#endif +#ifdef SIGPOLL + SCR_OS_CONSTANT(o, SIGPOLL); +#endif +#ifdef SIGLOST + SCR_OS_CONSTANT(o, SIGLOST); +#endif +#ifdef SIGPWR + SCR_OS_CONSTANT(o, SIGPWR); +#endif +#ifdef SIGINFO + SCR_OS_CONSTANT(o, SIGINFO); +#endif +#ifdef SIGSYS + SCR_OS_CONSTANT(o, SIGSYS); +#endif +#ifdef SIGUNUSED + SCR_OS_CONSTANT(o, SIGUNUSED); +#endif +} + +static void scr_os_dlopen_constants(ScrDyn *o) { +#if !defined(_WIN32) && !defined(__wasi__) +#ifdef RTLD_LAZY + SCR_OS_CONSTANT(o, RTLD_LAZY); +#endif +#ifdef RTLD_NOW + SCR_OS_CONSTANT(o, RTLD_NOW); +#endif +#ifdef RTLD_GLOBAL + SCR_OS_CONSTANT(o, RTLD_GLOBAL); +#endif +#ifdef RTLD_LOCAL + SCR_OS_CONSTANT(o, RTLD_LOCAL); +#endif +#ifdef RTLD_DEEPBIND + SCR_OS_CONSTANT(o, RTLD_DEEPBIND); +#endif +#else + (void)o; +#endif +} + +static SCR_TL ScrDyn *scr_os_constants_value; +static void scr_os_constants_clear(void) { + ScrDyn *value = scr_os_constants_value; + scr_os_constants_value = NULL; + scr_dyn_release(value); +} + +ScrDyn *scr_os_constants(void) { + if (scr_os_constants_value) return scr_dyn_retain(scr_os_constants_value); + ScrDyn *os = scr_dyn_new_obj_null_proto(); + ScrDyn *dlopen = scr_dyn_new_obj_null_proto(); + ScrDyn *errnos = scr_dyn_new_obj_null_proto(); + ScrDyn *signals = scr_dyn_new_obj_null_proto(); + ScrDyn *priority = scr_dyn_new_obj_null_proto(); + scr_os_errno_constants(errnos); + scr_os_signal_constants(signals); + scr_os_constant(priority, "PRIORITY_LOW", SCR_OS_PRIORITY_LOW); + scr_os_constant(priority, "PRIORITY_BELOW_NORMAL", SCR_OS_PRIORITY_BELOW_NORMAL); + scr_os_constant(priority, "PRIORITY_NORMAL", SCR_OS_PRIORITY_NORMAL); + scr_os_constant(priority, "PRIORITY_ABOVE_NORMAL", SCR_OS_PRIORITY_ABOVE_NORMAL); + scr_os_constant(priority, "PRIORITY_HIGH", SCR_OS_PRIORITY_HIGH); + scr_os_constant(priority, "PRIORITY_HIGHEST", SCR_OS_PRIORITY_HIGHEST); + scr_os_dlopen_constants(dlopen); + scr_os_constant(os, "UV_UDP_REUSEADDR", 4); + scr_dyn_obj_set(os, "dlopen", 6, dlopen); + scr_dyn_obj_set(os, "errno", 5, errnos); + scr_dyn_release(scr_dyn_freeze(signals)); + scr_dyn_obj_set(os, "signals", 7, signals); + scr_dyn_obj_set(os, "priority", 8, priority); + scr_os_constants_value = os; + scr_atexit(scr_os_constants_clear); + return scr_dyn_retain(os); +} diff --git a/packages/runtime/src/scr_path.c b/packages/runtime/src/scr_path.c index 019680103..139cca7a7 100644 --- a/packages/runtime/src/scr_path.c +++ b/packages/runtime/src/scr_path.c @@ -1279,3 +1279,206 @@ ScrStr *scr_path_win32_extname(ScrStr *path) { } return scr_str_new(p + start_dot, (size_t)(end - start_dot)); } + +/* ── parse and format ───────────────────────────────────────────────── + * parse answers a fresh string[] [root, dir, base, ext, name] (the + * compiler builds the ParsedPath record from it); format takes the five + * fields with undefined spelled "" (Node reads each through `||`). */ + +static ScrArr *scr_path_parts(const char *p, long root[2], long dir[2], long base[2], long ext[2], + long name[2]) { + ScrArr *out = scr_arr_new(SCR_ELEM_STR, 5); + long *spans[5] = { root, dir, base, ext, name }; + for (int k = 0; k < 5; k++) + scr_arr_push_ref(out, scr_str_new(p + spans[k][0], (size_t)(spans[k][1] - spans[k][0]))); + return out; +} + +ScrArr *scr_path_parse(ScrStr *path) { + const char *p = path->data; + long len = (long)path->len; + long root[2] = { 0, 0 }, dir[2] = { 0, 0 }, base[2] = { 0, 0 }, ext[2] = { 0, 0 }, + name[2] = { 0, 0 }; + if (len == 0) return scr_path_parts(p, root, dir, base, ext, name); + bool absolute = p[0] == '/'; + long start = 0; + if (absolute) { + root[1] = 1; + start = 1; + } + long start_dot = -1, start_part = 0, end = -1; + bool matched_slash = true; + int pre_dot_state = 0; + for (long i = len - 1; i >= start; --i) { + char code = p[i]; + if (code == '/') { + if (!matched_slash) { + start_part = i + 1; + break; + } + continue; + } + if (end == -1) { + matched_slash = false; + end = i + 1; + } + if (code == '.') { + if (start_dot == -1) start_dot = i; + else if (pre_dot_state != 1) pre_dot_state = 1; + } else if (start_dot != -1) { + pre_dot_state = -1; + } + } + if (end != -1) { + long from = start_part == 0 && absolute ? 1 : start_part; + if (start_dot == -1 || pre_dot_state == 0 || + (pre_dot_state == 1 && start_dot == end - 1 && start_dot == start_part + 1)) { + base[0] = name[0] = from; + base[1] = name[1] = end; + } else { + name[0] = from; + name[1] = start_dot; + base[0] = from; + base[1] = end; + ext[0] = start_dot; + ext[1] = end; + } + } + if (start_part > 0) { + dir[1] = start_part - 1; + } else if (absolute) { + dir[1] = 1; + } + return scr_path_parts(p, root, dir, base, ext, name); +} + +ScrArr *scr_path_win32_parse(ScrStr *path) { + const char *p = path->data; + long len = (long)path->len; + long root[2] = { 0, 0 }, dir[2] = { 0, 0 }, base[2] = { 0, 0 }, ext[2] = { 0, 0 }, + name[2] = { 0, 0 }; + if (len == 0) return scr_path_parts(p, root, dir, base, ext, name); + long root_end = 0; + char code = p[0]; + if (len == 1) { + if (scr_path_w32_is_sep(code)) { + root[1] = dir[1] = 1; + } else { + base[1] = name[1] = 1; + } + return scr_path_parts(p, root, dir, base, ext, name); + } + if (scr_path_w32_is_sep(code)) { + /* A possible UNC root. */ + root_end = 1; + if (scr_path_w32_is_sep(p[1])) { + long j = 2, last = j; + while (j < len && !scr_path_w32_is_sep(p[j])) j++; + if (j < len && j != last) { + last = j; + while (j < len && scr_path_w32_is_sep(p[j])) j++; + if (j < len && j != last) { + last = j; + while (j < len && !scr_path_w32_is_sep(p[j])) j++; + if (j == len) root_end = j; + else if (j != last) root_end = j + 1; + } + } + } + } else if (scr_path_w32_is_device_root(code) && p[1] == ':') { + /* A possible device root. */ + if (len <= 2) { + root[1] = dir[1] = len; + return scr_path_parts(p, root, dir, base, ext, name); + } + root_end = 2; + if (scr_path_w32_is_sep(p[2])) { + if (len == 3) { + root[1] = dir[1] = len; + return scr_path_parts(p, root, dir, base, ext, name); + } + root_end = 3; + } + } + if (root_end > 0) root[1] = root_end; + long start_dot = -1, start_part = root_end, end = -1; + bool matched_slash = true; + int pre_dot_state = 0; + for (long i = len - 1; i >= root_end; --i) { + code = p[i]; + if (scr_path_w32_is_sep(code)) { + if (!matched_slash) { + start_part = i + 1; + break; + } + continue; + } + if (end == -1) { + matched_slash = false; + end = i + 1; + } + if (code == '.') { + if (start_dot == -1) start_dot = i; + else if (pre_dot_state != 1) pre_dot_state = 1; + } else if (start_dot != -1) { + pre_dot_state = -1; + } + } + if (end != -1) { + if (start_dot == -1 || pre_dot_state == 0 || + (pre_dot_state == 1 && start_dot == end - 1 && start_dot == start_part + 1)) { + base[0] = name[0] = start_part; + base[1] = name[1] = end; + } else { + name[0] = start_part; + name[1] = start_dot; + base[0] = start_part; + base[1] = end; + ext[0] = start_dot; + ext[1] = end; + } + } + /* A root directory keeps the whole root (`C:\abc` -> `C:\`); deeper + * directories drop the trailing separator. */ + if (start_part > 0 && start_part != root_end) { + dir[1] = start_part - 1; + } else { + dir[0] = root[0]; + dir[1] = root[1]; + } + return scr_path_parts(p, root, dir, base, ext, name); +} + +static ScrStr *scr_path_format_with(char sep, ScrStr *root, ScrStr *dir, ScrStr *base, ScrStr *name, + ScrStr *ext) { + /* dir = pathObject.dir || pathObject.root; base = pathObject.base || + * `${name || ''}${formatExt(ext)}`. */ + ScrStr *d = dir->len > 0 ? dir : root; + PathBuf b; + pb_init(&b); + if (d->len > 0) { + pb_append(&b, d->data, d->len); + /* `${dir}${sep}${base}` unless dir is the root itself. */ + bool is_root = d->len == root->len && memcmp(d->data, root->data, d->len) == 0; + if (!is_root) pb_push(&b, sep); + } + if (base->len > 0) { + pb_append(&b, base->data, base->len); + } else { + pb_append(&b, name->data, name->len); + if (ext->len > 0) { + if (ext->data[0] != '.') pb_push(&b, '.'); + pb_append(&b, ext->data, ext->len); + } + } + return pb_take(&b); +} + +ScrStr *scr_path_format(ScrStr *root, ScrStr *dir, ScrStr *base, ScrStr *name, ScrStr *ext) { + return scr_path_format_with('/', root, dir, base, name, ext); +} + +ScrStr *scr_path_win32_format(ScrStr *root, ScrStr *dir, ScrStr *base, ScrStr *name, + ScrStr *ext) { + return scr_path_format_with('\\', root, dir, base, name, ext); +} diff --git a/packages/runtime/src/scr_runtime.h b/packages/runtime/src/scr_runtime.h index 17fd53dd1..fcd787655 100644 --- a/packages/runtime/src/scr_runtime.h +++ b/packages/runtime/src/scr_runtime.h @@ -4198,6 +4198,14 @@ ScrStr *scr_path_win32_extname(ScrStr *path); bool scr_path_win32_is_absolute(ScrStr *path); ScrStr *scr_path_win32_relative(ScrStr *from, ScrStr *to); ScrStr *scr_path_win32_to_namespaced_path(ScrStr *path); +/* path.parse / path.format for both families: parse answers a fresh + * string[] [root, dir, base, ext, name]; format takes the pathObject + * fields with undefined spelled "" (Node reads each through `||`). */ +ScrArr *scr_path_parse(ScrStr *path); +ScrArr *scr_path_win32_parse(ScrStr *path); +ScrStr *scr_path_format(ScrStr *root, ScrStr *dir, ScrStr *base, ScrStr *name, ScrStr *ext); +ScrStr *scr_path_win32_format(ScrStr *root, ScrStr *dir, ScrStr *base, ScrStr *name, + ScrStr *ext); /* fs.openSync(path, flags) → the raw fd as f64 (Node's string flag * grammar; unknown flags throw Node's ERR_INVALID_ARG_VALUE TypeError @@ -4439,6 +4447,26 @@ ScrStr *scr_os_tmpdir(void); ScrStr *scr_os_release(void); /* uname(2) release — +1 fresh */ ScrStr *scr_os_type(void); /* uname(2) sysname — +1 fresh */ double scr_os_totalmem(void); /* total physical memory, bytes */ +/* node:os host facts (scr_os.c), libuv's answers: uname machine/version, + * the host name, "LE"/"BE", free memory in bytes, uptime in seconds and + * the 1/5/15-minute load averages (+1 fresh results; never throw). */ +ScrStr *scr_os_machine(void); +ScrStr *scr_os_version(void); +ScrStr *scr_os_hostname(void); +ScrStr *scr_os_endianness(void); +double scr_os_freemem(void); +double scr_os_uptime(void); +ScrArr *scr_os_loadavg(void); +/* os.getPriority(pid): validateInt32, then the scheduling priority; + * failures throw Node's RangeError or SystemError (ERR_SYSTEM_ERROR). */ +double scr_os_get_priority(double pid); +/* os.cpus(): take answers the CPU count of a fresh snapshot; model and + * field (0 speed, 1 user, 2 nice, 3 sys, 4 idle, 5 irq) read it. */ +double scr_os_cpus_take(void); +ScrStr *scr_os_cpus_model(double i); +double scr_os_cpus_field(double i, double field); +/* os.constants: the per-thread null-prototype constants object (+1). */ +ScrDyn *scr_os_constants(void); double scr_os_available_parallelism(void); /* uv_available_parallelism: CPUs this process may use, >= 1 */ /* os.userInfo()'s field trio (pw_name / pw_shell / pw_dir — the passwd * home, not the $HOME cascade). +1 fresh; abort on lookup failure. */ diff --git a/packages/runtime/test/gen-path-cases.mjs b/packages/runtime/test/gen-path-cases.mjs index d561140e3..93cba123c 100644 --- a/packages/runtime/test/gen-path-cases.mjs +++ b/packages/runtime/test/gen-path-cases.mjs @@ -218,6 +218,32 @@ for (const p of paths) { emit("isAbsolute", [p], String(win32.isAbsolute(p))); emit("toNamespacedPath", [p], win32.toNamespacedPath(p)); emit("resolve1", [p], win32.resolve(p)); + // parse's five fields joined by U+0001, and format over them. + const parsed = win32.parse(p); + const fields = [parsed.root, parsed.dir, parsed.base, parsed.ext, parsed.name]; + emit("parse", [p], fields.join("\u0001")); + emit( + "format", + [parsed.root, parsed.dir, parsed.base, parsed.name, parsed.ext], + win32.format(parsed), + ); +} + +// ── format's `||` defaults over field subsets ──────────────────────── +for (const root of ["", "C:\\", "\\"]) { + for (const dir of ["", "C:\\", "d", "C:\\d"]) { + for (const base of ["", "b.x"]) { + for (const name of ["", "n"]) { + for (const ext of ["", "e", ".e"]) { + emit( + "format", + [root, dir, base, name, ext], + win32.format({ root, dir, base, name, ext }), + ); + } + } + } + } } // ── basename with a suffix ─────────────────────────────────────────── diff --git a/packages/runtime/test/path-cases.txt b/packages/runtime/test/path-cases.txt index 76afc058b..3664935f9 100644 --- a/packages/runtime/test/path-cases.txt +++ b/packages/runtime/test/path-cases.txt @@ -5,6 +5,8 @@ extname - - isAbsolute - 66616c7365 toNamespacedPath - - resolve1 - 5c +parse - 01010101 +format - - - - - - normalize 2e 2e dirname 2e 2e basename 2e 2e @@ -12,6 +14,8 @@ extname 2e - isAbsolute 2e 66616c7365 toNamespacedPath 2e 2e resolve1 2e 5c +parse 2e 01012e01012e +format - - 2e 2e - 2e normalize 2e2e 2e2e dirname 2e2e 2e basename 2e2e 2e2e @@ -19,6 +23,8 @@ extname 2e2e - isAbsolute 2e2e 66616c7365 toNamespacedPath 2e2e 2e2e resolve1 2e2e 5c +parse 2e2e 01012e2e01012e2e +format - - 2e2e 2e2e - 2e2e normalize 2e2e2e 2e2e2e dirname 2e2e2e 2e basename 2e2e2e 2e2e2e @@ -26,6 +32,8 @@ extname 2e2e2e 2e isAbsolute 2e2e2e 66616c7365 toNamespacedPath 2e2e2e 5c2e2e2e resolve1 2e2e2e 5c2e2e2e +parse 2e2e2e 01012e2e2e012e012e2e +format - - 2e2e2e 2e2e 2e 2e2e2e normalize 2e2f 2e5c dirname 2e2f 2e basename 2e2f 2e @@ -33,6 +41,8 @@ extname 2e2f - isAbsolute 2e2f 66616c7365 toNamespacedPath 2e2f 2e2f resolve1 2e2f 5c +parse 2e2f 01012e01012e +format - - 2e 2e - 2e normalize 2e2e2f 2e2e5c dirname 2e2e2f 2e basename 2e2e2f 2e2e @@ -40,6 +50,8 @@ extname 2e2e2f - isAbsolute 2e2e2f 66616c7365 toNamespacedPath 2e2e2f 2e2e2f resolve1 2e2e2f 5c +parse 2e2e2f 01012e2e01012e2e +format - - 2e2e 2e2e - 2e2e normalize 2e5c 2e5c dirname 2e5c 2e basename 2e5c 2e @@ -47,6 +59,8 @@ extname 2e5c - isAbsolute 2e5c 66616c7365 toNamespacedPath 2e5c 2e5c resolve1 2e5c 5c +parse 2e5c 01012e01012e +format - - 2e 2e - 2e normalize 2e2e5c 2e2e5c dirname 2e2e5c 2e basename 2e2e5c 2e2e @@ -54,6 +68,8 @@ extname 2e2e5c - isAbsolute 2e2e5c 66616c7365 toNamespacedPath 2e2e5c 2e2e5c resolve1 2e2e5c 5c +parse 2e2e5c 01012e2e01012e2e +format - - 2e2e 2e2e - 2e2e normalize 2f 5c dirname 2f 2f basename 2f - @@ -61,6 +77,8 @@ extname 2f - isAbsolute 2f 74727565 toNamespacedPath 2f 2f resolve1 2f 5c +parse 2f 2f012f010101 +format 2f 2f - - - 2f normalize 5c 5c dirname 5c 5c basename 5c - @@ -68,6 +86,8 @@ extname 5c - isAbsolute 5c 74727565 toNamespacedPath 5c 5c resolve1 5c 5c +parse 5c 5c015c010101 +format 5c 5c - - - 5c normalize 2f2f 5c dirname 2f2f 2f basename 2f2f - @@ -75,6 +95,8 @@ extname 2f2f - isAbsolute 2f2f 74727565 toNamespacedPath 2f2f 2f2f resolve1 2f2f 5c +parse 2f2f 2f012f010101 +format 2f 2f - - - 2f normalize 5c5c 5c dirname 5c5c 5c basename 5c5c - @@ -82,6 +104,8 @@ extname 5c5c - isAbsolute 5c5c 74727565 toNamespacedPath 5c5c 5c5c resolve1 5c5c 5c +parse 5c5c 5c015c010101 +format 5c 5c - - - 5c normalize 2f2f2f 5c dirname 2f2f2f 2f basename 2f2f2f - @@ -89,6 +113,8 @@ extname 2f2f2f - isAbsolute 2f2f2f 74727565 toNamespacedPath 2f2f2f 2f2f2f resolve1 2f2f2f 5c +parse 2f2f2f 2f012f010101 +format 2f 2f - - - 2f normalize 5c5c5c 5c dirname 5c5c5c 5c basename 5c5c5c - @@ -96,6 +122,8 @@ extname 5c5c5c - isAbsolute 5c5c5c 74727565 toNamespacedPath 5c5c5c 5c5c5c resolve1 5c5c5c 5c +parse 5c5c5c 5c015c010101 +format 5c 5c - - - 5c normalize 2f61 5c61 dirname 2f61 2f basename 2f61 61 @@ -103,6 +131,8 @@ extname 2f61 - isAbsolute 2f61 74727565 toNamespacedPath 2f61 2f61 resolve1 2f61 5c61 +parse 2f61 2f012f0161010161 +format 2f 2f 61 61 - 2f61 normalize 5c61 5c61 dirname 5c61 5c basename 5c61 61 @@ -110,6 +140,8 @@ extname 5c61 - isAbsolute 5c61 74727565 toNamespacedPath 5c61 5c61 resolve1 5c61 5c61 +parse 5c61 5c015c0161010161 +format 5c 5c 61 61 - 5c61 normalize 61 61 dirname 61 2e basename 61 61 @@ -117,6 +149,8 @@ extname 61 - isAbsolute 61 66616c7365 toNamespacedPath 61 61 resolve1 61 5c61 +parse 61 010161010161 +format - - 61 61 - 61 normalize 612f 615c dirname 612f 2e basename 612f 61 @@ -124,6 +158,8 @@ extname 612f - isAbsolute 612f 66616c7365 toNamespacedPath 612f 612f resolve1 612f 5c61 +parse 612f 010161010161 +format - - 61 61 - 61 normalize 615c 615c dirname 615c 2e basename 615c 61 @@ -131,6 +167,8 @@ extname 615c - isAbsolute 615c 66616c7365 toNamespacedPath 615c 615c resolve1 615c 5c61 +parse 615c 010161010161 +format - - 61 61 - 61 normalize 612f62 615c62 dirname 612f62 61 basename 612f62 62 @@ -138,6 +176,8 @@ extname 612f62 - isAbsolute 612f62 66616c7365 toNamespacedPath 612f62 5c615c62 resolve1 612f62 5c615c62 +parse 612f62 01610162010162 +format - 61 62 62 - 615c62 normalize 615c62 615c62 dirname 615c62 61 basename 615c62 62 @@ -145,6 +185,8 @@ extname 615c62 - isAbsolute 615c62 66616c7365 toNamespacedPath 615c62 5c615c62 resolve1 615c62 5c615c62 +parse 615c62 01610162010162 +format - 61 62 62 - 615c62 normalize 612f622f63 615c625c63 dirname 612f622f63 612f62 basename 612f622f63 63 @@ -152,6 +194,8 @@ extname 612f622f63 - isAbsolute 612f622f63 66616c7365 toNamespacedPath 612f622f63 5c615c625c63 resolve1 612f622f63 5c615c625c63 +parse 612f622f63 01612f620163010163 +format - 612f62 63 63 - 612f625c63 normalize 615c625c63 615c625c63 dirname 615c625c63 615c62 basename 615c625c63 63 @@ -159,6 +203,8 @@ extname 615c625c63 - isAbsolute 615c625c63 66616c7365 toNamespacedPath 615c625c63 5c615c625c63 resolve1 615c625c63 5c615c625c63 +parse 615c625c63 01615c620163010163 +format - 615c62 63 63 - 615c625c63 normalize 612f622f632f 615c625c635c dirname 612f622f632f 612f62 basename 612f622f632f 63 @@ -166,6 +212,8 @@ extname 612f622f632f - isAbsolute 612f622f632f 66616c7365 toNamespacedPath 612f622f632f 5c615c625c63 resolve1 612f622f632f 5c615c625c63 +parse 612f622f632f 01612f620163010163 +format - 612f62 63 63 - 612f625c63 normalize 615c625c635c 615c625c635c dirname 615c625c635c 615c62 basename 615c625c635c 63 @@ -173,6 +221,8 @@ extname 615c625c635c - isAbsolute 615c625c635c 66616c7365 toNamespacedPath 615c625c635c 5c615c625c63 resolve1 615c625c635c 5c615c625c63 +parse 615c625c635c 01615c620163010163 +format - 615c62 63 63 - 615c625c63 normalize 612f2f62 615c62 dirname 612f2f62 612f basename 612f2f62 62 @@ -180,6 +230,8 @@ extname 612f2f62 - isAbsolute 612f2f62 66616c7365 toNamespacedPath 612f2f62 5c615c62 resolve1 612f2f62 5c615c62 +parse 612f2f62 01612f0162010162 +format - 612f 62 62 - 612f5c62 normalize 615c5c62 615c62 dirname 615c5c62 615c basename 615c5c62 62 @@ -187,6 +239,8 @@ extname 615c5c62 - isAbsolute 615c5c62 66616c7365 toNamespacedPath 615c5c62 5c615c62 resolve1 615c5c62 5c615c62 +parse 615c5c62 01615c0162010162 +format - 615c 62 62 - 615c5c62 normalize 612f2e2f62 615c62 dirname 612f2e2f62 612f2e basename 612f2e2f62 62 @@ -194,6 +248,8 @@ extname 612f2e2f62 - isAbsolute 612f2e2f62 66616c7365 toNamespacedPath 612f2e2f62 5c615c62 resolve1 612f2e2f62 5c615c62 +parse 612f2e2f62 01612f2e0162010162 +format - 612f2e 62 62 - 612f2e5c62 normalize 615c2e5c62 615c62 dirname 615c2e5c62 615c2e basename 615c2e5c62 62 @@ -201,6 +257,8 @@ extname 615c2e5c62 - isAbsolute 615c2e5c62 66616c7365 toNamespacedPath 615c2e5c62 5c615c62 resolve1 615c2e5c62 5c615c62 +parse 615c2e5c62 01615c2e0162010162 +format - 615c2e 62 62 - 615c2e5c62 normalize 612f2e2e2f62 62 dirname 612f2e2e2f62 612f2e2e basename 612f2e2e2f62 62 @@ -208,6 +266,8 @@ extname 612f2e2e2f62 - isAbsolute 612f2e2e2f62 66616c7365 toNamespacedPath 612f2e2e2f62 612f2e2e2f62 resolve1 612f2e2e2f62 5c62 +parse 612f2e2e2f62 01612f2e2e0162010162 +format - 612f2e2e 62 62 - 612f2e2e5c62 normalize 615c2e2e5c62 62 dirname 615c2e2e5c62 615c2e2e basename 615c2e2e5c62 62 @@ -215,6 +275,8 @@ extname 615c2e2e5c62 - isAbsolute 615c2e2e5c62 66616c7365 toNamespacedPath 615c2e2e5c62 615c2e2e5c62 resolve1 615c2e2e5c62 5c62 +parse 615c2e2e5c62 01615c2e2e0162010162 +format - 615c2e2e 62 62 - 615c2e2e5c62 normalize 612f622f2e2e 61 dirname 612f622f2e2e 612f62 basename 612f622f2e2e 2e2e @@ -222,6 +284,8 @@ extname 612f622f2e2e - isAbsolute 612f622f2e2e 66616c7365 toNamespacedPath 612f622f2e2e 612f622f2e2e resolve1 612f622f2e2e 5c61 +parse 612f622f2e2e 01612f62012e2e01012e2e +format - 612f62 2e2e 2e2e - 612f625c2e2e normalize 615c625c2e2e 61 dirname 615c625c2e2e 615c62 basename 615c625c2e2e 2e2e @@ -229,6 +293,8 @@ extname 615c625c2e2e - isAbsolute 615c625c2e2e 66616c7365 toNamespacedPath 615c625c2e2e 615c625c2e2e resolve1 615c625c2e2e 5c61 +parse 615c625c2e2e 01615c62012e2e01012e2e +format - 615c62 2e2e 2e2e - 615c625c2e2e normalize 2e2e2f612f62 2e2e5c615c62 dirname 2e2e2f612f62 2e2e2f61 basename 2e2e2f612f62 62 @@ -236,6 +302,8 @@ extname 2e2e2f612f62 - isAbsolute 2e2e2f612f62 66616c7365 toNamespacedPath 2e2e2f612f62 5c615c62 resolve1 2e2e2f612f62 5c615c62 +parse 2e2e2f612f62 012e2e2f610162010162 +format - 2e2e2f61 62 62 - 2e2e2f615c62 normalize 2e2e5c615c62 2e2e5c615c62 dirname 2e2e5c615c62 2e2e5c61 basename 2e2e5c615c62 62 @@ -243,6 +311,8 @@ extname 2e2e5c615c62 - isAbsolute 2e2e5c615c62 66616c7365 toNamespacedPath 2e2e5c615c62 5c615c62 resolve1 2e2e5c615c62 5c615c62 +parse 2e2e5c615c62 012e2e5c610162010162 +format - 2e2e5c61 62 62 - 2e2e5c615c62 normalize 612f622f2e2e2f2e2e2f2e2e 2e2e dirname 612f622f2e2e2f2e2e2f2e2e 612f622f2e2e2f2e2e basename 612f622f2e2e2f2e2e2f2e2e 2e2e @@ -250,6 +320,8 @@ extname 612f622f2e2e2f2e2e2f2e2e - isAbsolute 612f622f2e2e2f2e2e2f2e2e 66616c7365 toNamespacedPath 612f622f2e2e2f2e2e2f2e2e 612f622f2e2e2f2e2e2f2e2e resolve1 612f622f2e2e2f2e2e2f2e2e 5c +parse 612f622f2e2e2f2e2e2f2e2e 01612f622f2e2e2f2e2e012e2e01012e2e +format - 612f622f2e2e2f2e2e 2e2e 2e2e - 612f622f2e2e2f2e2e5c2e2e normalize 615c625c2e2e5c2e2e5c2e2e 2e2e dirname 615c625c2e2e5c2e2e5c2e2e 615c625c2e2e5c2e2e basename 615c625c2e2e5c2e2e5c2e2e 2e2e @@ -257,6 +329,8 @@ extname 615c625c2e2e5c2e2e5c2e2e - isAbsolute 615c625c2e2e5c2e2e5c2e2e 66616c7365 toNamespacedPath 615c625c2e2e5c2e2e5c2e2e 615c625c2e2e5c2e2e5c2e2e resolve1 615c625c2e2e5c2e2e5c2e2e 5c +parse 615c625c2e2e5c2e2e5c2e2e 01615c625c2e2e5c2e2e012e2e01012e2e +format - 615c625c2e2e5c2e2e 2e2e 2e2e - 615c625c2e2e5c2e2e5c2e2e normalize 2f2e2e2f2e2e2f61 5c61 dirname 2f2e2e2f2e2e2f61 2f2e2e2f2e2e basename 2f2e2e2f2e2e2f61 61 @@ -264,6 +338,8 @@ extname 2f2e2e2f2e2e2f61 - isAbsolute 2f2e2e2f2e2e2f61 74727565 toNamespacedPath 2f2e2e2f2e2e2f61 2f2e2e2f2e2e2f61 resolve1 2f2e2e2f2e2e2f61 5c61 +parse 2f2e2e2f2e2e2f61 2f012f2e2e2f2e2e0161010161 +format 2f 2f2e2e2f2e2e 61 61 - 2f2e2e2f2e2e5c61 normalize 5c2e2e5c2e2e5c61 5c61 dirname 5c2e2e5c2e2e5c61 5c2e2e5c2e2e basename 5c2e2e5c2e2e5c61 61 @@ -271,6 +347,8 @@ extname 5c2e2e5c2e2e5c61 - isAbsolute 5c2e2e5c2e2e5c61 74727565 toNamespacedPath 5c2e2e5c2e2e5c61 5c2e2e5c2e2e5c61 resolve1 5c2e2e5c2e2e5c61 5c61 +parse 5c2e2e5c2e2e5c61 5c015c2e2e5c2e2e0161010161 +format 5c 5c2e2e5c2e2e 61 61 - 5c2e2e5c2e2e5c61 normalize 2f612f622f63 5c615c625c63 dirname 2f612f622f63 2f612f62 basename 2f612f622f63 63 @@ -278,6 +356,8 @@ extname 2f612f622f63 - isAbsolute 2f612f622f63 74727565 toNamespacedPath 2f612f622f63 5c615c625c63 resolve1 2f612f622f63 5c615c625c63 +parse 2f612f622f63 2f012f612f620163010163 +format 2f 2f612f62 63 63 - 2f612f625c63 normalize 5c615c625c63 5c615c625c63 dirname 5c615c625c63 5c615c62 basename 5c615c625c63 63 @@ -285,6 +365,8 @@ extname 5c615c625c63 - isAbsolute 5c615c625c63 74727565 toNamespacedPath 5c615c625c63 5c615c625c63 resolve1 5c615c625c63 5c615c625c63 +parse 5c615c625c63 5c015c615c620163010163 +format 5c 5c615c62 63 63 - 5c615c625c63 normalize 2f612f622f632f 5c615c625c635c dirname 2f612f622f632f 2f612f62 basename 2f612f622f632f 63 @@ -292,6 +374,8 @@ extname 2f612f622f632f - isAbsolute 2f612f622f632f 74727565 toNamespacedPath 2f612f622f632f 5c615c625c63 resolve1 2f612f622f632f 5c615c625c63 +parse 2f612f622f632f 2f012f612f620163010163 +format 2f 2f612f62 63 63 - 2f612f625c63 normalize 5c615c625c635c 5c615c625c635c dirname 5c615c625c635c 5c615c62 basename 5c615c625c635c 63 @@ -299,6 +383,8 @@ extname 5c615c625c635c - isAbsolute 5c615c625c635c 74727565 toNamespacedPath 5c615c625c635c 5c615c625c63 resolve1 5c615c625c635c 5c615c625c63 +parse 5c615c625c635c 5c015c615c620163010163 +format 5c 5c615c62 63 63 - 5c615c625c63 normalize 2f2f612f622f63 5c5c615c625c63 dirname 2f2f612f622f63 2f2f612f622f basename 2f2f612f622f63 63 @@ -306,6 +392,8 @@ extname 2f2f612f622f63 - isAbsolute 2f2f612f622f63 74727565 toNamespacedPath 2f2f612f622f63 5c5c3f5c554e435c615c625c63 resolve1 2f2f612f622f63 5c5c615c625c63 +parse 2f2f612f622f63 2f2f612f622f012f2f612f622f0163010163 +format 2f2f612f622f 2f2f612f622f 63 63 - 2f2f612f622f63 normalize 5c5c615c625c63 5c5c615c625c63 dirname 5c5c615c625c63 5c5c615c625c basename 5c5c615c625c63 63 @@ -313,6 +401,8 @@ extname 5c5c615c625c63 - isAbsolute 5c5c615c625c63 74727565 toNamespacedPath 5c5c615c625c63 5c5c3f5c554e435c615c625c63 resolve1 5c5c615c625c63 5c5c615c625c63 +parse 5c5c615c625c63 5c5c615c625c015c5c615c625c0163010163 +format 5c5c615c625c 5c5c615c625c 63 63 - 5c5c615c625c63 normalize 66697874757265732f2f2f622f2e2e2f622f632e6a73 66697874757265735c625c632e6a73 dirname 66697874757265732f2f2f622f2e2e2f622f632e6a73 66697874757265732f2f2f622f2e2e2f62 basename 66697874757265732f2f2f622f2e2e2f622f632e6a73 632e6a73 @@ -320,6 +410,8 @@ extname 66697874757265732f2f2f622f2e2e2f622f632e6a73 2e6a73 isAbsolute 66697874757265732f2f2f622f2e2e2f622f632e6a73 66616c7365 toNamespacedPath 66697874757265732f2f2f622f2e2e2f622f632e6a73 5c66697874757265735c625c632e6a73 resolve1 66697874757265732f2f2f622f2e2e2f622f632e6a73 5c66697874757265735c625c632e6a73 +parse 66697874757265732f2f2f622f2e2e2f622f632e6a73 0166697874757265732f2f2f622f2e2e2f6201632e6a73012e6a730163 +format - 66697874757265732f2f2f622f2e2e2f62 632e6a73 63 2e6a73 66697874757265732f2f2f622f2e2e2f625c632e6a73 normalize 66697874757265735c5c5c625c2e2e5c625c632e6a73 66697874757265735c625c632e6a73 dirname 66697874757265735c5c5c625c2e2e5c625c632e6a73 66697874757265735c5c5c625c2e2e5c62 basename 66697874757265735c5c5c625c2e2e5c625c632e6a73 632e6a73 @@ -327,6 +419,8 @@ extname 66697874757265735c5c5c625c2e2e5c625c632e6a73 2e6a73 isAbsolute 66697874757265735c5c5c625c2e2e5c625c632e6a73 66616c7365 toNamespacedPath 66697874757265735c5c5c625c2e2e5c625c632e6a73 5c66697874757265735c625c632e6a73 resolve1 66697874757265735c5c5c625c2e2e5c625c632e6a73 5c66697874757265735c625c632e6a73 +parse 66697874757265735c5c5c625c2e2e5c625c632e6a73 0166697874757265735c5c5c625c2e2e5c6201632e6a73012e6a730163 +format - 66697874757265735c5c5c625c2e2e5c62 632e6a73 63 2e6a73 66697874757265735c5c5c625c2e2e5c625c632e6a73 normalize 2f666f6f2f2e2e2f2e2e2f2e2e2f626172 5c626172 dirname 2f666f6f2f2e2e2f2e2e2f2e2e2f626172 2f666f6f2f2e2e2f2e2e2f2e2e basename 2f666f6f2f2e2e2f2e2e2f2e2e2f626172 626172 @@ -334,6 +428,8 @@ extname 2f666f6f2f2e2e2f2e2e2f2e2e2f626172 - isAbsolute 2f666f6f2f2e2e2f2e2e2f2e2e2f626172 74727565 toNamespacedPath 2f666f6f2f2e2e2f2e2e2f2e2e2f626172 5c626172 resolve1 2f666f6f2f2e2e2f2e2e2f2e2e2f626172 5c626172 +parse 2f666f6f2f2e2e2f2e2e2f2e2e2f626172 2f012f666f6f2f2e2e2f2e2e2f2e2e016261720101626172 +format 2f 2f666f6f2f2e2e2f2e2e2f2e2e 626172 626172 - 2f666f6f2f2e2e2f2e2e2f2e2e5c626172 normalize 5c666f6f5c2e2e5c2e2e5c2e2e5c626172 5c626172 dirname 5c666f6f5c2e2e5c2e2e5c2e2e5c626172 5c666f6f5c2e2e5c2e2e5c2e2e basename 5c666f6f5c2e2e5c2e2e5c2e2e5c626172 626172 @@ -341,6 +437,8 @@ extname 5c666f6f5c2e2e5c2e2e5c2e2e5c626172 - isAbsolute 5c666f6f5c2e2e5c2e2e5c2e2e5c626172 74727565 toNamespacedPath 5c666f6f5c2e2e5c2e2e5c2e2e5c626172 5c626172 resolve1 5c666f6f5c2e2e5c2e2e5c2e2e5c626172 5c626172 +parse 5c666f6f5c2e2e5c2e2e5c2e2e5c626172 5c015c666f6f5c2e2e5c2e2e5c2e2e016261720101626172 +format 5c 5c666f6f5c2e2e5c2e2e5c2e2e 626172 626172 - 5c666f6f5c2e2e5c2e2e5c2e2e5c626172 normalize 666f6f2f6261725c62617a 666f6f5c6261725c62617a dirname 666f6f2f6261725c62617a 666f6f2f626172 basename 666f6f2f6261725c62617a 62617a @@ -348,6 +446,8 @@ extname 666f6f2f6261725c62617a - isAbsolute 666f6f2f6261725c62617a 66616c7365 toNamespacedPath 666f6f2f6261725c62617a 5c666f6f5c6261725c62617a resolve1 666f6f2f6261725c62617a 5c666f6f5c6261725c62617a +parse 666f6f2f6261725c62617a 01666f6f2f6261720162617a010162617a +format - 666f6f2f626172 62617a 62617a - 666f6f2f6261725c62617a normalize 433a 433a2e dirname 433a 433a basename 433a - @@ -355,6 +455,8 @@ extname 433a - isAbsolute 433a 66616c7365 toNamespacedPath 433a 5c5c3f5c433a5c resolve1 433a 433a5c +parse 433a 433a01433a010101 +format 433a 433a - - - 433a normalize 633a 633a2e dirname 633a 633a basename 633a - @@ -362,6 +464,8 @@ extname 633a - isAbsolute 633a 66616c7365 toNamespacedPath 633a 5c5c3f5c633a5c resolve1 633a 633a5c +parse 633a 633a01633a010101 +format 633a 633a - - - 633a normalize 433a2f 433a5c dirname 433a2f 433a2f basename 433a2f - @@ -369,6 +473,8 @@ extname 433a2f - isAbsolute 433a2f 74727565 toNamespacedPath 433a2f 5c5c3f5c433a5c resolve1 433a2f 433a5c +parse 433a2f 433a2f01433a2f010101 +format 433a2f 433a2f - - - 433a2f normalize 433a5c 433a5c dirname 433a5c 433a5c basename 433a5c - @@ -376,6 +482,8 @@ extname 433a5c - isAbsolute 433a5c 74727565 toNamespacedPath 433a5c 5c5c3f5c433a5c resolve1 433a5c 433a5c +parse 433a5c 433a5c01433a5c010101 +format 433a5c 433a5c - - - 433a5c normalize 433a61 433a61 dirname 433a61 433a basename 433a61 61 @@ -383,6 +491,8 @@ extname 433a61 - isAbsolute 433a61 66616c7365 toNamespacedPath 433a61 5c5c3f5c433a5c61 resolve1 433a61 433a5c61 +parse 433a61 433a01433a0161010161 +format 433a 433a 61 61 - 433a61 normalize 433a612f62 433a615c62 dirname 433a612f62 433a61 basename 433a612f62 62 @@ -390,6 +500,8 @@ extname 433a612f62 - isAbsolute 433a612f62 66616c7365 toNamespacedPath 433a612f62 5c5c3f5c433a5c615c62 resolve1 433a612f62 433a5c615c62 +parse 433a612f62 433a01433a610162010162 +format 433a 433a61 62 62 - 433a615c62 normalize 433a2e2f61 433a61 dirname 433a2e2f61 433a2e basename 433a2e2f61 61 @@ -397,6 +509,8 @@ extname 433a2e2f61 - isAbsolute 433a2e2f61 66616c7365 toNamespacedPath 433a2e2f61 5c5c3f5c433a5c61 resolve1 433a2e2f61 433a5c61 +parse 433a2e2f61 433a01433a2e0161010161 +format 433a 433a2e 61 61 - 433a2e5c61 normalize 433a2e2e2f61 433a2e2e5c61 dirname 433a2e2e2f61 433a2e2e basename 433a2e2e2f61 61 @@ -404,6 +518,8 @@ extname 433a2e2e2f61 - isAbsolute 433a2e2e2f61 66616c7365 toNamespacedPath 433a2e2e2f61 5c5c3f5c433a5c61 resolve1 433a2e2e2f61 433a5c61 +parse 433a2e2e2f61 433a01433a2e2e0161010161 +format 433a 433a2e2e 61 61 - 433a2e2e5c61 normalize 433a2f61 433a5c61 dirname 433a2f61 433a2f basename 433a2f61 61 @@ -411,6 +527,8 @@ extname 433a2f61 - isAbsolute 433a2f61 74727565 toNamespacedPath 433a2f61 5c5c3f5c433a5c61 resolve1 433a2f61 433a5c61 +parse 433a2f61 433a2f01433a2f0161010161 +format 433a2f 433a2f 61 61 - 433a2f61 normalize 433a5c61 433a5c61 dirname 433a5c61 433a5c basename 433a5c61 61 @@ -418,6 +536,8 @@ extname 433a5c61 - isAbsolute 433a5c61 74727565 toNamespacedPath 433a5c61 5c5c3f5c433a5c61 resolve1 433a5c61 433a5c61 +parse 433a5c61 433a5c01433a5c0161010161 +format 433a5c 433a5c 61 61 - 433a5c61 normalize 433a2f612f62 433a5c615c62 dirname 433a2f612f62 433a2f61 basename 433a2f612f62 62 @@ -425,6 +545,8 @@ extname 433a2f612f62 - isAbsolute 433a2f612f62 74727565 toNamespacedPath 433a2f612f62 5c5c3f5c433a5c615c62 resolve1 433a2f612f62 433a5c615c62 +parse 433a2f612f62 433a2f01433a2f610162010162 +format 433a2f 433a2f61 62 62 - 433a2f615c62 normalize 433a5c615c62 433a5c615c62 dirname 433a5c615c62 433a5c61 basename 433a5c615c62 62 @@ -432,6 +554,8 @@ extname 433a5c615c62 - isAbsolute 433a5c615c62 74727565 toNamespacedPath 433a5c615c62 5c5c3f5c433a5c615c62 resolve1 433a5c615c62 433a5c615c62 +parse 433a5c615c62 433a5c01433a5c610162010162 +format 433a5c 433a5c61 62 62 - 433a5c615c62 normalize 433a2f612f2e2e2f62 433a5c62 dirname 433a2f612f2e2e2f62 433a2f612f2e2e basename 433a2f612f2e2e2f62 62 @@ -439,6 +563,8 @@ extname 433a2f612f2e2e2f62 - isAbsolute 433a2f612f2e2e2f62 74727565 toNamespacedPath 433a2f612f2e2e2f62 5c5c3f5c433a5c62 resolve1 433a2f612f2e2e2f62 433a5c62 +parse 433a2f612f2e2e2f62 433a2f01433a2f612f2e2e0162010162 +format 433a2f 433a2f612f2e2e 62 62 - 433a2f612f2e2e5c62 normalize 433a5c615c2e2e5c62 433a5c62 dirname 433a5c615c2e2e5c62 433a5c615c2e2e basename 433a5c615c2e2e5c62 62 @@ -446,6 +572,8 @@ extname 433a5c615c2e2e5c62 - isAbsolute 433a5c615c2e2e5c62 74727565 toNamespacedPath 433a5c615c2e2e5c62 5c5c3f5c433a5c62 resolve1 433a5c615c2e2e5c62 433a5c62 +parse 433a5c615c2e2e5c62 433a5c01433a5c615c2e2e0162010162 +format 433a5c 433a5c615c2e2e 62 62 - 433a5c615c2e2e5c62 normalize 433a2f612f622f 433a5c615c625c dirname 433a2f612f622f 433a2f61 basename 433a2f612f622f 62 @@ -453,6 +581,8 @@ extname 433a2f612f622f - isAbsolute 433a2f612f622f 74727565 toNamespacedPath 433a2f612f622f 5c5c3f5c433a5c615c62 resolve1 433a2f612f622f 433a5c615c62 +parse 433a2f612f622f 433a2f01433a2f610162010162 +format 433a2f 433a2f61 62 62 - 433a2f615c62 normalize 433a5c615c625c 433a5c615c625c dirname 433a5c615c625c 433a5c61 basename 433a5c615c625c 62 @@ -460,6 +590,8 @@ extname 433a5c615c625c - isAbsolute 433a5c615c625c 74727565 toNamespacedPath 433a5c615c625c 5c5c3f5c433a5c615c62 resolve1 433a5c615c625c 433a5c615c62 +parse 433a5c615c625c 433a5c01433a5c610162010162 +format 433a5c 433a5c61 62 62 - 433a5c615c62 normalize 433a2e2e5c61 433a2e2e5c61 dirname 433a2e2e5c61 433a2e2e basename 433a2e2e5c61 61 @@ -467,6 +599,8 @@ extname 433a2e2e5c61 - isAbsolute 433a2e2e5c61 66616c7365 toNamespacedPath 433a2e2e5c61 5c5c3f5c433a5c61 resolve1 433a2e2e5c61 433a5c61 +parse 433a2e2e5c61 433a01433a2e2e0161010161 +format 433a 433a2e2e 61 61 - 433a2e2e5c61 normalize 433a5c2e 433a5c dirname 433a5c2e 433a5c basename 433a5c2e 2e @@ -474,6 +608,8 @@ extname 433a5c2e - isAbsolute 433a5c2e 74727565 toNamespacedPath 433a5c2e 5c5c3f5c433a5c resolve1 433a5c2e 433a5c +parse 433a5c2e 433a5c01433a5c012e01012e +format 433a5c 433a5c 2e 2e - 433a5c2e normalize 433a5c2e2e 433a5c dirname 433a5c2e2e 433a5c basename 433a5c2e2e 2e2e @@ -481,6 +617,8 @@ extname 433a5c2e2e - isAbsolute 433a5c2e2e 74727565 toNamespacedPath 433a5c2e2e 5c5c3f5c433a5c resolve1 433a5c2e2e 433a5c +parse 433a5c2e2e 433a5c01433a5c012e2e01012e2e +format 433a5c 433a5c 2e2e 2e2e - 433a5c2e2e normalize 633a2f626c61685c626c6168 633a5c626c61685c626c6168 dirname 633a2f626c61685c626c6168 633a2f626c6168 basename 633a2f626c61685c626c6168 626c6168 @@ -488,6 +626,8 @@ extname 633a2f626c61685c626c6168 - isAbsolute 633a2f626c61685c626c6168 74727565 toNamespacedPath 633a2f626c61685c626c6168 5c5c3f5c633a5c626c61685c626c6168 resolve1 633a2f626c61685c626c6168 633a5c626c61685c626c6168 +parse 633a2f626c61685c626c6168 633a2f01633a2f626c616801626c61680101626c6168 +format 633a2f 633a2f626c6168 626c6168 626c6168 - 633a2f626c61685c626c6168 normalize 643a2f67616d6573 643a5c67616d6573 dirname 643a2f67616d6573 643a2f basename 643a2f67616d6573 67616d6573 @@ -495,6 +635,8 @@ extname 643a2f67616d6573 - isAbsolute 643a2f67616d6573 74727565 toNamespacedPath 643a2f67616d6573 5c5c3f5c643a5c67616d6573 resolve1 643a2f67616d6573 643a5c67616d6573 +parse 643a2f67616d6573 643a2f01643a2f0167616d6573010167616d6573 +format 643a2f 643a2f 67616d6573 67616d6573 - 643a2f67616d6573 normalize 643a2e2e2f612f62 643a2e2e5c615c62 dirname 643a2e2e2f612f62 643a2e2e2f61 basename 643a2e2e2f612f62 62 @@ -502,6 +644,8 @@ extname 643a2e2e2f612f62 - isAbsolute 643a2e2e2f612f62 66616c7365 toNamespacedPath 643a2e2e2f612f62 5c5c3f5c643a5c615c62 resolve1 643a2e2e2f612f62 643a5c615c62 +parse 643a2e2e2f612f62 643a01643a2e2e2f610162010162 +format 643a 643a2e2e2f61 62 62 - 643a2e2e2f615c62 normalize 443a5c2e2e5c2e2e5c78 443a5c78 dirname 443a5c2e2e5c2e2e5c78 443a5c2e2e5c2e2e basename 443a5c2e2e5c2e2e5c78 78 @@ -509,6 +653,8 @@ extname 443a5c2e2e5c2e2e5c78 - isAbsolute 443a5c2e2e5c2e2e5c78 74727565 toNamespacedPath 443a5c2e2e5c2e2e5c78 5c5c3f5c443a5c78 resolve1 443a5c2e2e5c2e2e5c78 443a5c78 +parse 443a5c2e2e5c2e2e5c78 443a5c01443a5c2e2e5c2e2e0178010178 +format 443a5c 443a5c2e2e5c2e2e 78 78 - 443a5c2e2e5c2e2e5c78 normalize 5a3a7768617465766572 5a3a7768617465766572 dirname 5a3a7768617465766572 5a3a basename 5a3a7768617465766572 7768617465766572 @@ -516,6 +662,8 @@ extname 5a3a7768617465766572 - isAbsolute 5a3a7768617465766572 66616c7365 toNamespacedPath 5a3a7768617465766572 5c5c3f5c5a3a5c7768617465766572 resolve1 5a3a7768617465766572 5a3a5c7768617465766572 +parse 5a3a7768617465766572 5a3a015a3a01776861746576657201017768617465766572 +format 5a3a 5a3a 7768617465766572 7768617465766572 - 5a3a7768617465766572 normalize 313a2f61 2e5c313a5c61 dirname 313a2f61 313a basename 313a2f61 61 @@ -523,6 +671,8 @@ extname 313a2f61 - isAbsolute 313a2f61 66616c7365 toNamespacedPath 313a2f61 5c313a5c61 resolve1 313a2f61 5c313a5c61 +parse 313a2f61 01313a0161010161 +format - 313a 61 61 - 313a5c61 normalize 61623a2f63 2e5c61623a5c63 dirname 61623a2f63 61623a basename 61623a2f63 63 @@ -530,6 +680,8 @@ extname 61623a2f63 - isAbsolute 61623a2f63 66616c7365 toNamespacedPath 61623a2f63 5c61623a5c63 resolve1 61623a2f63 5c61623a5c63 +parse 61623a2f63 0161623a0163010163 +format - 61623a 63 63 - 61623a5c63 normalize 3a5c61 2e5c3a5c61 dirname 3a5c61 3a basename 3a5c61 61 @@ -537,6 +689,8 @@ extname 3a5c61 - isAbsolute 3a5c61 66616c7365 toNamespacedPath 3a5c61 5c3a5c61 resolve1 3a5c61 5c3a5c61 +parse 3a5c61 013a0161010161 +format - 3a 61 61 - 3a5c61 normalize 2f2f736572766572 5c736572766572 dirname 2f2f736572766572 2f basename 2f2f736572766572 736572766572 @@ -544,6 +698,8 @@ extname 2f2f736572766572 - isAbsolute 2f2f736572766572 74727565 toNamespacedPath 2f2f736572766572 5c736572766572 resolve1 2f2f736572766572 5c736572766572 +parse 2f2f736572766572 2f012f017365727665720101736572766572 +format 2f 2f 736572766572 736572766572 - 2f736572766572 normalize 5c5c736572766572 5c736572766572 dirname 5c5c736572766572 5c basename 5c5c736572766572 736572766572 @@ -551,6 +707,8 @@ extname 5c5c736572766572 - isAbsolute 5c5c736572766572 74727565 toNamespacedPath 5c5c736572766572 5c736572766572 resolve1 5c5c736572766572 5c736572766572 +parse 5c5c736572766572 5c015c017365727665720101736572766572 +format 5c 5c 736572766572 736572766572 - 5c736572766572 normalize 2f2f7365727665722f7368617265 5c5c7365727665725c73686172655c dirname 2f2f7365727665722f7368617265 2f2f7365727665722f7368617265 basename 2f2f7365727665722f7368617265 7368617265 @@ -558,6 +716,8 @@ extname 2f2f7365727665722f7368617265 - isAbsolute 2f2f7365727665722f7368617265 74727565 toNamespacedPath 2f2f7365727665722f7368617265 5c5c3f5c554e435c7365727665725c73686172655c resolve1 2f2f7365727665722f7368617265 5c5c7365727665725c73686172655c +parse 2f2f7365727665722f7368617265 2f2f7365727665722f7368617265012f2f7365727665722f7368617265010101 +format 2f2f7365727665722f7368617265 2f2f7365727665722f7368617265 - - - 2f2f7365727665722f7368617265 normalize 5c5c7365727665725c7368617265 5c5c7365727665725c73686172655c dirname 5c5c7365727665725c7368617265 5c5c7365727665725c7368617265 basename 5c5c7365727665725c7368617265 7368617265 @@ -565,6 +725,8 @@ extname 5c5c7365727665725c7368617265 - isAbsolute 5c5c7365727665725c7368617265 74727565 toNamespacedPath 5c5c7365727665725c7368617265 5c5c3f5c554e435c7365727665725c73686172655c resolve1 5c5c7365727665725c7368617265 5c5c7365727665725c73686172655c +parse 5c5c7365727665725c7368617265 5c5c7365727665725c7368617265015c5c7365727665725c7368617265010101 +format 5c5c7365727665725c7368617265 5c5c7365727665725c7368617265 - - - 5c5c7365727665725c7368617265 normalize 2f2f7365727665722f73686172652f 5c5c7365727665725c73686172655c dirname 2f2f7365727665722f73686172652f 2f2f7365727665722f73686172652f basename 2f2f7365727665722f73686172652f 7368617265 @@ -572,6 +734,8 @@ extname 2f2f7365727665722f73686172652f - isAbsolute 2f2f7365727665722f73686172652f 74727565 toNamespacedPath 2f2f7365727665722f73686172652f 5c5c3f5c554e435c7365727665725c73686172655c resolve1 2f2f7365727665722f73686172652f 5c5c7365727665725c73686172655c +parse 2f2f7365727665722f73686172652f 2f2f7365727665722f73686172652f012f2f7365727665722f73686172652f010101 +format 2f2f7365727665722f73686172652f 2f2f7365727665722f73686172652f - - - 2f2f7365727665722f73686172652f normalize 5c5c7365727665725c73686172655c 5c5c7365727665725c73686172655c dirname 5c5c7365727665725c73686172655c 5c5c7365727665725c73686172655c basename 5c5c7365727665725c73686172655c 7368617265 @@ -579,6 +743,8 @@ extname 5c5c7365727665725c73686172655c - isAbsolute 5c5c7365727665725c73686172655c 74727565 toNamespacedPath 5c5c7365727665725c73686172655c 5c5c3f5c554e435c7365727665725c73686172655c resolve1 5c5c7365727665725c73686172655c 5c5c7365727665725c73686172655c +parse 5c5c7365727665725c73686172655c 5c5c7365727665725c73686172655c015c5c7365727665725c73686172655c010101 +format 5c5c7365727665725c73686172655c 5c5c7365727665725c73686172655c - - - 5c5c7365727665725c73686172655c normalize 2f2f7365727665722f73686172652f6469722f66696c652e747874 5c5c7365727665725c73686172655c6469725c66696c652e747874 dirname 2f2f7365727665722f73686172652f6469722f66696c652e747874 2f2f7365727665722f73686172652f646972 basename 2f2f7365727665722f73686172652f6469722f66696c652e747874 66696c652e747874 @@ -586,6 +752,8 @@ extname 2f2f7365727665722f73686172652f6469722f66696c652e747874 2e747874 isAbsolute 2f2f7365727665722f73686172652f6469722f66696c652e747874 74727565 toNamespacedPath 2f2f7365727665722f73686172652f6469722f66696c652e747874 5c5c3f5c554e435c7365727665725c73686172655c6469725c66696c652e747874 resolve1 2f2f7365727665722f73686172652f6469722f66696c652e747874 5c5c7365727665725c73686172655c6469725c66696c652e747874 +parse 2f2f7365727665722f73686172652f6469722f66696c652e747874 2f2f7365727665722f73686172652f012f2f7365727665722f73686172652f6469720166696c652e747874012e7478740166696c65 +format 2f2f7365727665722f73686172652f 2f2f7365727665722f73686172652f646972 66696c652e747874 66696c65 2e747874 2f2f7365727665722f73686172652f6469725c66696c652e747874 normalize 5c5c7365727665725c73686172655c6469725c66696c652e747874 5c5c7365727665725c73686172655c6469725c66696c652e747874 dirname 5c5c7365727665725c73686172655c6469725c66696c652e747874 5c5c7365727665725c73686172655c646972 basename 5c5c7365727665725c73686172655c6469725c66696c652e747874 66696c652e747874 @@ -593,6 +761,8 @@ extname 5c5c7365727665725c73686172655c6469725c66696c652e747874 2e747874 isAbsolute 5c5c7365727665725c73686172655c6469725c66696c652e747874 74727565 toNamespacedPath 5c5c7365727665725c73686172655c6469725c66696c652e747874 5c5c3f5c554e435c7365727665725c73686172655c6469725c66696c652e747874 resolve1 5c5c7365727665725c73686172655c6469725c66696c652e747874 5c5c7365727665725c73686172655c6469725c66696c652e747874 +parse 5c5c7365727665725c73686172655c6469725c66696c652e747874 5c5c7365727665725c73686172655c015c5c7365727665725c73686172655c6469720166696c652e747874012e7478740166696c65 +format 5c5c7365727665725c73686172655c 5c5c7365727665725c73686172655c646972 66696c652e747874 66696c65 2e747874 5c5c7365727665725c73686172655c6469725c66696c652e747874 normalize 5c5c7365727665725c73686172655c2e2e5c78 5c5c7365727665725c73686172655c78 dirname 5c5c7365727665725c73686172655c2e2e5c78 5c5c7365727665725c73686172655c2e2e basename 5c5c7365727665725c73686172655c2e2e5c78 78 @@ -600,6 +770,8 @@ extname 5c5c7365727665725c73686172655c2e2e5c78 - isAbsolute 5c5c7365727665725c73686172655c2e2e5c78 74727565 toNamespacedPath 5c5c7365727665725c73686172655c2e2e5c78 5c5c3f5c554e435c7365727665725c73686172655c78 resolve1 5c5c7365727665725c73686172655c2e2e5c78 5c5c7365727665725c73686172655c78 +parse 5c5c7365727665725c73686172655c2e2e5c78 5c5c7365727665725c73686172655c015c5c7365727665725c73686172655c2e2e0178010178 +format 5c5c7365727665725c73686172655c 5c5c7365727665725c73686172655c2e2e 78 78 - 5c5c7365727665725c73686172655c2e2e5c78 normalize 2f2f7365727665722f2f7368617265 5c5c7365727665725c73686172655c dirname 2f2f7365727665722f2f7368617265 2f2f7365727665722f2f7368617265 basename 2f2f7365727665722f2f7368617265 7368617265 @@ -607,6 +779,8 @@ extname 2f2f7365727665722f2f7368617265 - isAbsolute 2f2f7365727665722f2f7368617265 74727565 toNamespacedPath 2f2f7365727665722f2f7368617265 5c5c3f5c554e435c7365727665725c73686172655c resolve1 2f2f7365727665722f2f7368617265 5c5c7365727665725c73686172655c +parse 2f2f7365727665722f2f7368617265 2f2f7365727665722f2f7368617265012f2f7365727665722f2f7368617265010101 +format 2f2f7365727665722f2f7368617265 2f2f7365727665722f2f7368617265 - - - 2f2f7365727665722f2f7368617265 normalize 5c5c7365727665725c5c7368617265 5c5c7365727665725c73686172655c dirname 5c5c7365727665725c5c7368617265 5c5c7365727665725c5c7368617265 basename 5c5c7365727665725c5c7368617265 7368617265 @@ -614,6 +788,8 @@ extname 5c5c7365727665725c5c7368617265 - isAbsolute 5c5c7365727665725c5c7368617265 74727565 toNamespacedPath 5c5c7365727665725c5c7368617265 5c5c3f5c554e435c7365727665725c73686172655c resolve1 5c5c7365727665725c5c7368617265 5c5c7365727665725c73686172655c +parse 5c5c7365727665725c5c7368617265 5c5c7365727665725c5c7368617265015c5c7365727665725c5c7368617265010101 +format 5c5c7365727665725c5c7368617265 5c5c7365727665725c5c7368617265 - - - 5c5c7365727665725c5c7368617265 normalize 2f2f2f7365727665722f73686172652f78 5c7365727665725c73686172655c78 dirname 2f2f2f7365727665722f73686172652f78 2f2f2f7365727665722f7368617265 basename 2f2f2f7365727665722f73686172652f78 78 @@ -621,6 +797,8 @@ extname 2f2f2f7365727665722f73686172652f78 - isAbsolute 2f2f2f7365727665722f73686172652f78 74727565 toNamespacedPath 2f2f2f7365727665722f73686172652f78 5c7365727665725c73686172655c78 resolve1 2f2f2f7365727665722f73686172652f78 5c7365727665725c73686172655c78 +parse 2f2f2f7365727665722f73686172652f78 2f012f2f2f7365727665722f73686172650178010178 +format 2f 2f2f2f7365727665722f7368617265 78 78 - 2f2f2f7365727665722f73686172655c78 normalize 5c5c5c7365727665725c73686172655c78 5c7365727665725c73686172655c78 dirname 5c5c5c7365727665725c73686172655c78 5c5c5c7365727665725c7368617265 basename 5c5c5c7365727665725c73686172655c78 78 @@ -628,6 +806,8 @@ extname 5c5c5c7365727665725c73686172655c78 - isAbsolute 5c5c5c7365727665725c73686172655c78 74727565 toNamespacedPath 5c5c5c7365727665725c73686172655c78 5c7365727665725c73686172655c78 resolve1 5c5c5c7365727665725c73686172655c78 5c7365727665725c73686172655c78 +parse 5c5c5c7365727665725c73686172655c78 5c015c5c5c7365727665725c73686172650178010178 +format 5c 5c5c5c7365727665725c7368617265 78 78 - 5c5c5c7365727665725c73686172655c78 normalize 2f2f7365727665722f73686172652f2e2e2f2e2e 5c5c7365727665725c73686172655c dirname 2f2f7365727665722f73686172652f2e2e2f2e2e 2f2f7365727665722f73686172652f2e2e basename 2f2f7365727665722f73686172652f2e2e2f2e2e 2e2e @@ -635,6 +815,8 @@ extname 2f2f7365727665722f73686172652f2e2e2f2e2e - isAbsolute 2f2f7365727665722f73686172652f2e2e2f2e2e 74727565 toNamespacedPath 2f2f7365727665722f73686172652f2e2e2f2e2e 5c5c3f5c554e435c7365727665725c73686172655c resolve1 2f2f7365727665722f73686172652f2e2e2f2e2e 5c5c7365727665725c73686172655c +parse 2f2f7365727665722f73686172652f2e2e2f2e2e 2f2f7365727665722f73686172652f012f2f7365727665722f73686172652f2e2e012e2e01012e2e +format 2f2f7365727665722f73686172652f 2f2f7365727665722f73686172652f2e2e 2e2e 2e2e - 2f2f7365727665722f73686172652f2e2e5c2e2e normalize 5c5c2e5c504859534943414c445249564530 5c5c2e5c504859534943414c445249564530 dirname 5c5c2e5c504859534943414c445249564530 5c5c2e5c504859534943414c445249564530 basename 5c5c2e5c504859534943414c445249564530 504859534943414c445249564530 @@ -642,6 +824,8 @@ extname 5c5c2e5c504859534943414c445249564530 - isAbsolute 5c5c2e5c504859534943414c445249564530 74727565 toNamespacedPath 5c5c2e5c504859534943414c445249564530 5c5c2e5c504859534943414c445249564530 resolve1 5c5c2e5c504859534943414c445249564530 5c5c2e5c504859534943414c445249564530 +parse 5c5c2e5c504859534943414c445249564530 5c5c2e5c504859534943414c445249564530015c5c2e5c504859534943414c445249564530010101 +format 5c5c2e5c504859534943414c445249564530 5c5c2e5c504859534943414c445249564530 - - - 5c5c2e5c504859534943414c445249564530 normalize 5c5c2e5c633a5c78 5c5c2e5c633a5c78 dirname 5c5c2e5c633a5c78 5c5c2e5c633a5c basename 5c5c2e5c633a5c78 78 @@ -649,6 +833,8 @@ extname 5c5c2e5c633a5c78 - isAbsolute 5c5c2e5c633a5c78 74727565 toNamespacedPath 5c5c2e5c633a5c78 5c5c2e5c633a5c78 resolve1 5c5c2e5c633a5c78 5c5c2e5c633a5c78 +parse 5c5c2e5c633a5c78 5c5c2e5c633a5c015c5c2e5c633a5c0178010178 +format 5c5c2e5c633a5c 5c5c2e5c633a5c 78 78 - 5c5c2e5c633a5c78 normalize 2f2f2e2f633a2f782f2e2e2f79 5c5c2e5c633a5c79 dirname 2f2f2e2f633a2f782f2e2e2f79 2f2f2e2f633a2f782f2e2e basename 2f2f2e2f633a2f782f2e2e2f79 79 @@ -656,6 +842,8 @@ extname 2f2f2e2f633a2f782f2e2e2f79 - isAbsolute 2f2f2e2f633a2f782f2e2e2f79 74727565 toNamespacedPath 2f2f2e2f633a2f782f2e2e2f79 5c5c2e5c633a5c79 resolve1 2f2f2e2f633a2f782f2e2e2f79 5c5c2e5c633a5c79 +parse 2f2f2e2f633a2f782f2e2e2f79 2f2f2e2f633a2f012f2f2e2f633a2f782f2e2e0179010179 +format 2f2f2e2f633a2f 2f2f2e2f633a2f782f2e2e 79 79 - 2f2f2e2f633a2f782f2e2e5c79 normalize 5c5c3f5c433a5c785c2e2e5c79 5c5c3f5c433a5c79 dirname 5c5c3f5c433a5c785c2e2e5c79 5c5c3f5c433a5c785c2e2e basename 5c5c3f5c433a5c785c2e2e5c79 79 @@ -663,6 +851,8 @@ extname 5c5c3f5c433a5c785c2e2e5c79 - isAbsolute 5c5c3f5c433a5c785c2e2e5c79 74727565 toNamespacedPath 5c5c3f5c433a5c785c2e2e5c79 5c5c3f5c433a5c79 resolve1 5c5c3f5c433a5c785c2e2e5c79 5c5c3f5c433a5c79 +parse 5c5c3f5c433a5c785c2e2e5c79 5c5c3f5c433a5c015c5c3f5c433a5c785c2e2e0179010179 +format 5c5c3f5c433a5c 5c5c3f5c433a5c785c2e2e 79 79 - 5c5c3f5c433a5c785c2e2e5c79 normalize 2f2f3f2f554e432f7365727665722f73686172652f78 5c5c3f5c554e435c7365727665725c73686172655c78 dirname 2f2f3f2f554e432f7365727665722f73686172652f78 2f2f3f2f554e432f7365727665722f7368617265 basename 2f2f3f2f554e432f7365727665722f73686172652f78 78 @@ -670,6 +860,8 @@ extname 2f2f3f2f554e432f7365727665722f73686172652f78 - isAbsolute 2f2f3f2f554e432f7365727665722f73686172652f78 74727565 toNamespacedPath 2f2f3f2f554e432f7365727665722f73686172652f78 5c5c3f5c554e435c7365727665725c73686172655c78 resolve1 2f2f3f2f554e432f7365727665722f73686172652f78 5c5c3f5c554e435c7365727665725c73686172655c78 +parse 2f2f3f2f554e432f7365727665722f73686172652f78 2f2f3f2f554e432f012f2f3f2f554e432f7365727665722f73686172650178010178 +format 2f2f3f2f554e432f 2f2f3f2f554e432f7365727665722f7368617265 78 78 - 2f2f3f2f554e432f7365727665722f73686172655c78 normalize 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e5c62 5c5c3f5c554e435c7365727665725c73686172655c62 dirname 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e5c62 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e basename 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e5c62 62 @@ -677,6 +869,8 @@ extname 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e5c62 - isAbsolute 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e5c62 74727565 toNamespacedPath 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e5c62 5c5c3f5c554e435c7365727665725c73686172655c62 resolve1 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e5c62 5c5c3f5c554e435c7365727665725c73686172655c62 +parse 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e5c62 5c5c3f5c554e435c015c5c3f5c554e435c7365727665725c73686172655c615c2e2e0162010162 +format 5c5c3f5c554e435c 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e 62 62 - 5c5c3f5c554e435c7365727665725c73686172655c615c2e2e5c62 normalize 5c5c2e5c 5c dirname 5c5c2e5c 5c basename 5c5c2e5c 2e @@ -684,6 +878,8 @@ extname 5c5c2e5c - isAbsolute 5c5c2e5c 74727565 toNamespacedPath 5c5c2e5c 5c5c2e5c resolve1 5c5c2e5c 5c +parse 5c5c2e5c 5c015c012e01012e +format 5c 5c 2e 2e - 5c2e normalize 5c5c3f5c 5c3f5c dirname 5c5c3f5c 5c basename 5c5c3f5c 3f @@ -691,6 +887,8 @@ extname 5c5c3f5c - isAbsolute 5c5c3f5c 74727565 toNamespacedPath 5c5c3f5c 5c5c3f5c resolve1 5c5c3f5c 5c3f +parse 5c5c3f5c 5c015c013f01013f +format 5c 5c 3f 3f - 5c3f normalize 5c5c2e 5c dirname 5c5c2e 5c basename 5c5c2e 2e @@ -698,6 +896,8 @@ extname 5c5c2e - isAbsolute 5c5c2e 74727565 toNamespacedPath 5c5c2e 5c5c2e resolve1 5c5c2e 5c +parse 5c5c2e 5c015c012e01012e +format 5c 5c 2e 2e - 5c2e normalize 5c5c3f 5c3f dirname 5c5c3f 5c basename 5c5c3f 3f @@ -705,6 +905,8 @@ extname 5c5c3f - isAbsolute 5c5c3f 74727565 toNamespacedPath 5c5c3f 5c5c3f resolve1 5c5c3f 5c3f +parse 5c5c3f 5c015c013f01013f +format 5c 5c 3f 3f - 5c3f normalize 434f4e 434f4e dirname 434f4e 2e basename 434f4e 434f4e @@ -712,6 +914,8 @@ extname 434f4e - isAbsolute 434f4e 66616c7365 toNamespacedPath 434f4e 5c434f4e resolve1 434f4e 5c434f4e +parse 434f4e 0101434f4e0101434f4e +format - - 434f4e 434f4e - 434f4e normalize 636f6e 636f6e dirname 636f6e 2e basename 636f6e 636f6e @@ -719,6 +923,8 @@ extname 636f6e - isAbsolute 636f6e 66616c7365 toNamespacedPath 636f6e 5c636f6e resolve1 636f6e 5c636f6e +parse 636f6e 0101636f6e0101636f6e +format - - 636f6e 636f6e - 636f6e normalize 434f4e3a 2e5c434f4e3a2e dirname 434f4e3a 2e basename 434f4e3a 434f4e3a @@ -726,6 +932,8 @@ extname 434f4e3a - isAbsolute 434f4e3a 66616c7365 toNamespacedPath 434f4e3a 5c434f4e3a resolve1 434f4e3a 5c434f4e3a +parse 434f4e3a 0101434f4e3a0101434f4e3a +format - - 434f4e3a 434f4e3a - 434f4e3a normalize 636f6e3a78 2e5c636f6e3a78 dirname 636f6e3a78 2e basename 636f6e3a78 636f6e3a78 @@ -733,6 +941,8 @@ extname 636f6e3a78 - isAbsolute 636f6e3a78 66616c7365 toNamespacedPath 636f6e3a78 5c636f6e3a78 resolve1 636f6e3a78 5c636f6e3a78 +parse 636f6e3a78 0101636f6e3a780101636f6e3a78 +format - - 636f6e3a78 636f6e3a78 - 636f6e3a78 normalize 4e554c 4e554c dirname 4e554c 2e basename 4e554c 4e554c @@ -740,6 +950,8 @@ extname 4e554c - isAbsolute 4e554c 66616c7365 toNamespacedPath 4e554c 5c4e554c resolve1 4e554c 5c4e554c +parse 4e554c 01014e554c01014e554c +format - - 4e554c 4e554c - 4e554c normalize 4e554c3a 2e5c4e554c3a2e dirname 4e554c3a 2e basename 4e554c3a 4e554c3a @@ -747,6 +959,8 @@ extname 4e554c3a - isAbsolute 4e554c3a 66616c7365 toNamespacedPath 4e554c3a 5c4e554c3a resolve1 4e554c3a 5c4e554c3a +parse 4e554c3a 01014e554c3a01014e554c3a +format - - 4e554c3a 4e554c3a - 4e554c3a normalize 6e756c2e747874 6e756c2e747874 dirname 6e756c2e747874 2e basename 6e756c2e747874 6e756c2e747874 @@ -754,6 +968,8 @@ extname 6e756c2e747874 2e747874 isAbsolute 6e756c2e747874 66616c7365 toNamespacedPath 6e756c2e747874 5c6e756c2e747874 resolve1 6e756c2e747874 5c6e756c2e747874 +parse 6e756c2e747874 01016e756c2e747874012e747874016e756c +format - - 6e756c2e747874 6e756c 2e747874 6e756c2e747874 normalize 434f4d31 434f4d31 dirname 434f4d31 2e basename 434f4d31 434f4d31 @@ -761,6 +977,8 @@ extname 434f4d31 - isAbsolute 434f4d31 66616c7365 toNamespacedPath 434f4d31 5c434f4d31 resolve1 434f4d31 5c434f4d31 +parse 434f4d31 0101434f4d310101434f4d31 +format - - 434f4d31 434f4d31 - 434f4d31 normalize 434f4d313a 2e5c434f4d313a2e dirname 434f4d313a 2e basename 434f4d313a 434f4d313a @@ -768,6 +986,8 @@ extname 434f4d313a - isAbsolute 434f4d313a 66616c7365 toNamespacedPath 434f4d313a 5c434f4d313a resolve1 434f4d313a 5c434f4d313a +parse 434f4d313a 0101434f4d313a0101434f4d313a +format - - 434f4d313a 434f4d313a - 434f4d313a normalize 636f6d393a7461696c 2e5c636f6d393a7461696c dirname 636f6d393a7461696c 2e basename 636f6d393a7461696c 636f6d393a7461696c @@ -775,6 +995,8 @@ extname 636f6d393a7461696c - isAbsolute 636f6d393a7461696c 66616c7365 toNamespacedPath 636f6d393a7461696c 5c636f6d393a7461696c resolve1 636f6d393a7461696c 5c636f6d393a7461696c +parse 636f6d393a7461696c 0101636f6d393a7461696c0101636f6d393a7461696c +format - - 636f6d393a7461696c 636f6d393a7461696c - 636f6d393a7461696c normalize 4c5054313a 2e5c4c5054313a2e dirname 4c5054313a 2e basename 4c5054313a 4c5054313a @@ -782,6 +1004,8 @@ extname 4c5054313a - isAbsolute 4c5054313a 66616c7365 toNamespacedPath 4c5054313a 5c4c5054313a resolve1 4c5054313a 5c4c5054313a +parse 4c5054313a 01014c5054313a01014c5054313a +format - - 4c5054313a 4c5054313a - 4c5054313a normalize 6c7074313a2f78 2e5c6c7074313a78 dirname 6c7074313a2f78 6c7074313a basename 6c7074313a2f78 78 @@ -789,6 +1013,8 @@ extname 6c7074313a2f78 - isAbsolute 6c7074313a2f78 66616c7365 toNamespacedPath 6c7074313a2f78 5c6c7074313a5c78 resolve1 6c7074313a2f78 5c6c7074313a5c78 +parse 6c7074313a2f78 016c7074313a0178010178 +format - 6c7074313a 78 78 - 6c7074313a5c78 normalize 4155583a 2e5c4155583a2e dirname 4155583a 2e basename 4155583a 4155583a @@ -796,6 +1022,8 @@ extname 4155583a - isAbsolute 4155583a 66616c7365 toNamespacedPath 4155583a 5c4155583a resolve1 4155583a 5c4155583a +parse 4155583a 01014155583a01014155583a +format - - 4155583a 4155583a - 4155583a normalize 50524e3a 2e5c50524e3a2e dirname 50524e3a 2e basename 50524e3a 50524e3a @@ -803,6 +1031,8 @@ extname 50524e3a - isAbsolute 50524e3a 66616c7365 toNamespacedPath 50524e3a 5c50524e3a resolve1 50524e3a 5c50524e3a +parse 50524e3a 010150524e3a010150524e3a +format - - 50524e3a 50524e3a - 50524e3a normalize 434f4dc2b93a 2e5c434f4dc2b93a2e dirname 434f4dc2b93a 2e basename 434f4dc2b93a 434f4dc2b93a @@ -810,6 +1040,8 @@ extname 434f4dc2b93a - isAbsolute 434f4dc2b93a 66616c7365 toNamespacedPath 434f4dc2b93a 5c434f4dc2b93a resolve1 434f4dc2b93a 5c434f4dc2b93a +parse 434f4dc2b93a 0101434f4dc2b93a0101434f4dc2b93a +format - - 434f4dc2b93a 434f4dc2b93a - 434f4dc2b93a normalize 6c7074c2b33a 2e5c6c7074c2b33a2e dirname 6c7074c2b33a 2e basename 6c7074c2b33a 6c7074c2b33a @@ -817,6 +1049,8 @@ extname 6c7074c2b33a - isAbsolute 6c7074c2b33a 66616c7365 toNamespacedPath 6c7074c2b33a 5c6c7074c2b33a resolve1 6c7074c2b33a 5c6c7074c2b33a +parse 6c7074c2b33a 01016c7074c2b33a01016c7074c2b33a +format - - 6c7074c2b33a 6c7074c2b33a - 6c7074c2b33a normalize 434f4e58 2e5c434f4e58 dirname 434f4e58 2e basename 434f4e58 434f4e58 @@ -824,6 +1058,8 @@ extname 434f4e58 - isAbsolute 434f4e58 66616c7365 toNamespacedPath 434f4e58 5c434f4e58 resolve1 434f4e58 5c434f4e58 +parse 434f4e58 0101434f4e580101434f4e58 +format - - 434f4e58 434f4e58 - 434f4e58 normalize 58434f4e 58434f4e dirname 58434f4e 2e basename 58434f4e 58434f4e @@ -831,6 +1067,8 @@ extname 58434f4e - isAbsolute 58434f4e 66616c7365 toNamespacedPath 58434f4e 5c58434f4e resolve1 58434f4e 5c58434f4e +parse 58434f4e 010158434f4e010158434f4e +format - - 58434f4e 58434f4e - 58434f4e normalize 612f434f4e 615c434f4e dirname 612f434f4e 61 basename 612f434f4e 434f4e @@ -838,6 +1076,8 @@ extname 612f434f4e - isAbsolute 612f434f4e 66616c7365 toNamespacedPath 612f434f4e 5c615c434f4e resolve1 612f434f4e 5c615c434f4e +parse 612f434f4e 016101434f4e0101434f4e +format - 61 434f4e 434f4e - 615c434f4e normalize 615c4e554c3a 2e5c615c4e554c3a dirname 615c4e554c3a 61 basename 615c4e554c3a 4e554c3a @@ -845,6 +1085,8 @@ extname 615c4e554c3a - isAbsolute 615c4e554c3a 66616c7365 toNamespacedPath 615c4e554c3a 5c615c4e554c3a resolve1 615c4e554c3a 5c615c4e554c3a +parse 615c4e554c3a 0161014e554c3a01014e554c3a +format - 61 4e554c3a 4e554c3a - 615c4e554c3a normalize 433a5c434f4e 433a5c434f4e dirname 433a5c434f4e 433a5c basename 433a5c434f4e 434f4e @@ -852,6 +1094,8 @@ extname 433a5c434f4e - isAbsolute 433a5c434f4e 74727565 toNamespacedPath 433a5c434f4e 5c5c3f5c433a5c434f4e resolve1 433a5c434f4e 433a5c434f4e +parse 433a5c434f4e 433a5c01433a5c01434f4e0101434f4e +format 433a5c 433a5c 434f4e 434f4e - 433a5c434f4e normalize 434f4e3a65787472613a636f6c6f6e73 2e5c434f4e3a65787472613a636f6c6f6e73 dirname 434f4e3a65787472613a636f6c6f6e73 2e basename 434f4e3a65787472613a636f6c6f6e73 434f4e3a65787472613a636f6c6f6e73 @@ -859,6 +1103,8 @@ extname 434f4e3a65787472613a636f6c6f6e73 - isAbsolute 434f4e3a65787472613a636f6c6f6e73 66616c7365 toNamespacedPath 434f4e3a65787472613a636f6c6f6e73 5c434f4e3a65787472613a636f6c6f6e73 resolve1 434f4e3a65787472613a636f6c6f6e73 5c434f4e3a65787472613a636f6c6f6e73 +parse 434f4e3a65787472613a636f6c6f6e73 0101434f4e3a65787472613a636f6c6f6e730101434f4e3a65787472613a636f6c6f6e73 +format - - 434f4e3a65787472613a636f6c6f6e73 434f4e3a65787472613a636f6c6f6e73 - 434f4e3a65787472613a636f6c6f6e73 normalize 613a623a63 613a623a63 dirname 613a623a63 613a basename 613a623a63 623a63 @@ -866,6 +1112,8 @@ extname 613a623a63 - isAbsolute 613a623a63 66616c7365 toNamespacedPath 613a623a63 5c5c3f5c613a5c623a63 resolve1 613a623a63 613a5c623a63 +parse 613a623a63 613a01613a01623a630101623a63 +format 613a 613a 623a63 623a63 - 613a623a63 normalize 783a 783a2e dirname 783a 783a basename 783a - @@ -873,6 +1121,8 @@ extname 783a - isAbsolute 783a 66616c7365 toNamespacedPath 783a 5c5c3f5c783a5c resolve1 783a 783a5c +parse 783a 783a01783a010101 +format 783a 783a - - - 783a normalize 783a793a 783a793a dirname 783a793a 783a basename 783a793a 793a @@ -880,6 +1130,8 @@ extname 783a793a - isAbsolute 783a793a 66616c7365 toNamespacedPath 783a793a 5c5c3f5c783a5c793a resolve1 783a793a 783a5c793a +parse 783a793a 783a01783a01793a0101793a +format 783a 783a 793a 793a - 783a793a normalize 613a2e2f62 613a62 dirname 613a2e2f62 613a2e basename 613a2e2f62 62 @@ -887,6 +1139,8 @@ extname 613a2e2f62 - isAbsolute 613a2e2f62 66616c7365 toNamespacedPath 613a2e2f62 5c5c3f5c613a5c62 resolve1 613a2e2f62 613a5c62 +parse 613a2e2f62 613a01613a2e0162010162 +format 613a 613a2e 62 62 - 613a2e5c62 normalize 613a2e5c62 613a62 dirname 613a2e5c62 613a2e basename 613a2e5c62 62 @@ -894,6 +1148,8 @@ extname 613a2e5c62 - isAbsolute 613a2e5c62 66616c7365 toNamespacedPath 613a2e5c62 5c5c3f5c613a5c62 resolve1 613a2e5c62 613a5c62 +parse 613a2e5c62 613a01613a2e0162010162 +format 613a 613a2e 62 62 - 613a2e5c62 normalize 6162633a 2e5c6162633a dirname 6162633a 2e basename 6162633a 6162633a @@ -901,6 +1157,8 @@ extname 6162633a - isAbsolute 6162633a 66616c7365 toNamespacedPath 6162633a 5c6162633a resolve1 6162633a 5c6162633a +parse 6162633a 01016162633a01016162633a +format - - 6162633a 6162633a - 6162633a normalize 6162633a2f78 2e5c6162633a5c78 dirname 6162633a2f78 6162633a basename 6162633a2f78 78 @@ -908,6 +1166,8 @@ extname 6162633a2f78 - isAbsolute 6162633a2f78 66616c7365 toNamespacedPath 6162633a2f78 5c6162633a5c78 resolve1 6162633a2f78 5c6162633a5c78 +parse 6162633a2f78 016162633a0178010178 +format - 6162633a 78 78 - 6162633a5c78 normalize 612f623a 2e5c615c623a dirname 612f623a 61 basename 612f623a 623a @@ -915,6 +1175,8 @@ extname 612f623a - isAbsolute 612f623a 66616c7365 toNamespacedPath 612f623a 5c615c623a resolve1 612f623a 5c615c623a +parse 612f623a 016101623a0101623a +format - 61 623a 623a - 615c623a normalize 615c623a63 615c623a63 dirname 615c623a63 61 basename 615c623a63 623a63 @@ -922,6 +1184,8 @@ extname 615c623a63 - isAbsolute 615c623a63 66616c7365 toNamespacedPath 615c623a63 5c615c623a63 resolve1 615c623a63 5c615c623a63 +parse 615c623a63 016101623a630101623a63 +format - 61 623a63 623a63 - 615c623a63 normalize 613a5c62 613a5c62 dirname 613a5c62 613a5c basename 613a5c62 62 @@ -929,6 +1193,8 @@ extname 613a5c62 - isAbsolute 613a5c62 74727565 toNamespacedPath 613a5c62 5c5c3f5c613a5c62 resolve1 613a5c62 613a5c62 +parse 613a5c62 613a5c01613a5c0162010162 +format 613a5c 613a5c 62 62 - 613a5c62 normalize 636f6ec2b9 2e5c636f6ec2b9 dirname 636f6ec2b9 2e basename 636f6ec2b9 636f6ec2b9 @@ -936,6 +1202,8 @@ extname 636f6ec2b9 - isAbsolute 636f6ec2b9 66616c7365 toNamespacedPath 636f6ec2b9 5c636f6ec2b9 resolve1 636f6ec2b9 5c636f6ec2b9 +parse 636f6ec2b9 0101636f6ec2b90101636f6ec2b9 +format - - 636f6ec2b9 636f6ec2b9 - 636f6ec2b9 normalize 2e2e3a 2e5c2e2e3a dirname 2e2e3a 2e basename 2e2e3a 2e2e3a @@ -943,6 +1211,8 @@ extname 2e2e3a 2e3a isAbsolute 2e2e3a 66616c7365 toNamespacedPath 2e2e3a 5c2e2e3a resolve1 2e2e3a 5c2e2e3a +parse 2e2e3a 01012e2e3a012e3a012e +format - - 2e2e3a 2e 2e3a 2e2e3a normalize 66696c652e747874 66696c652e747874 dirname 66696c652e747874 2e basename 66696c652e747874 66696c652e747874 @@ -950,6 +1220,8 @@ extname 66696c652e747874 2e747874 isAbsolute 66696c652e747874 66616c7365 toNamespacedPath 66696c652e747874 5c66696c652e747874 resolve1 66696c652e747874 5c66696c652e747874 +parse 66696c652e747874 010166696c652e747874012e7478740166696c65 +format - - 66696c652e747874 66696c65 2e747874 66696c652e747874 normalize 66696c652e 66696c652e dirname 66696c652e 2e basename 66696c652e 66696c652e @@ -957,6 +1229,8 @@ extname 66696c652e 2e isAbsolute 66696c652e 66616c7365 toNamespacedPath 66696c652e 5c66696c652e resolve1 66696c652e 5c66696c652e +parse 66696c652e 010166696c652e012e0166696c65 +format - - 66696c652e 66696c65 2e 66696c652e normalize 2e66696c65 2e66696c65 dirname 2e66696c65 2e basename 2e66696c65 2e66696c65 @@ -964,6 +1238,8 @@ extname 2e66696c65 - isAbsolute 2e66696c65 66616c7365 toNamespacedPath 2e66696c65 5c2e66696c65 resolve1 2e66696c65 5c2e66696c65 +parse 2e66696c65 01012e66696c6501012e66696c65 +format - - 2e66696c65 2e66696c65 - 2e66696c65 normalize 2e66696c652e747874 2e66696c652e747874 dirname 2e66696c652e747874 2e basename 2e66696c652e747874 2e66696c652e747874 @@ -971,6 +1247,8 @@ extname 2e66696c652e747874 2e747874 isAbsolute 2e66696c652e747874 66616c7365 toNamespacedPath 2e66696c652e747874 5c2e66696c652e747874 resolve1 2e66696c652e747874 5c2e66696c652e747874 +parse 2e66696c652e747874 01012e66696c652e747874012e747874012e66696c65 +format - - 2e66696c652e747874 2e66696c65 2e747874 2e66696c652e747874 normalize 66696c652e2e 66696c652e2e dirname 66696c652e2e 2e basename 66696c652e2e 66696c652e2e @@ -978,6 +1256,8 @@ extname 66696c652e2e 2e isAbsolute 66696c652e2e 66616c7365 toNamespacedPath 66696c652e2e 5c66696c652e2e resolve1 66696c652e2e 5c66696c652e2e +parse 66696c652e2e 010166696c652e2e012e0166696c652e +format - - 66696c652e2e 66696c652e 2e 66696c652e2e normalize 612e622f63 612e625c63 dirname 612e622f63 612e62 basename 612e622f63 63 @@ -985,6 +1265,8 @@ extname 612e622f63 - isAbsolute 612e622f63 66616c7365 toNamespacedPath 612e622f63 5c612e625c63 resolve1 612e622f63 5c612e625c63 +parse 612e622f63 01612e620163010163 +format - 612e62 63 63 - 612e625c63 normalize 433a5c615c622e747874 433a5c615c622e747874 dirname 433a5c615c622e747874 433a5c61 basename 433a5c615c622e747874 622e747874 @@ -992,6 +1274,8 @@ extname 433a5c615c622e747874 2e747874 isAbsolute 433a5c615c622e747874 74727565 toNamespacedPath 433a5c615c622e747874 5c5c3f5c433a5c615c622e747874 resolve1 433a5c615c622e747874 433a5c615c622e747874 +parse 433a5c615c622e747874 433a5c01433a5c6101622e747874012e7478740162 +format 433a5c 433a5c61 622e747874 62 2e747874 433a5c615c622e747874 normalize 433a5c612e625c63 433a5c612e625c63 dirname 433a5c612e625c63 433a5c612e62 basename 433a5c612e625c63 63 @@ -999,6 +1283,8 @@ extname 433a5c612e625c63 - isAbsolute 433a5c612e625c63 74727565 toNamespacedPath 433a5c612e625c63 5c5c3f5c433a5c612e625c63 resolve1 433a5c612e625c63 433a5c612e625c63 +parse 433a5c612e625c63 433a5c01433a5c612e620163010163 +format 433a5c 433a5c612e62 63 63 - 433a5c612e625c63 normalize 5c5c7365727665725c73686172655c662e657874 5c5c7365727665725c73686172655c662e657874 dirname 5c5c7365727665725c73686172655c662e657874 5c5c7365727665725c73686172655c basename 5c5c7365727665725c73686172655c662e657874 662e657874 @@ -1006,6 +1292,8 @@ extname 5c5c7365727665725c73686172655c662e657874 2e657874 isAbsolute 5c5c7365727665725c73686172655c662e657874 74727565 toNamespacedPath 5c5c7365727665725c73686172655c662e657874 5c5c3f5c554e435c7365727665725c73686172655c662e657874 resolve1 5c5c7365727665725c73686172655c662e657874 5c5c7365727665725c73686172655c662e657874 +parse 5c5c7365727665725c73686172655c662e657874 5c5c7365727665725c73686172655c015c5c7365727665725c73686172655c01662e657874012e6578740166 +format 5c5c7365727665725c73686172655c 5c5c7365727665725c73686172655c 662e657874 66 2e657874 5c5c7365727665725c73686172655c662e657874 normalize 615c622e635c64 615c622e635c64 dirname 615c622e635c64 615c622e63 basename 615c622e635c64 64 @@ -1013,6 +1301,8 @@ extname 615c622e635c64 - isAbsolute 615c622e635c64 66616c7365 toNamespacedPath 615c622e635c64 5c615c622e635c64 resolve1 615c622e635c64 5c615c622e635c64 +parse 615c622e635c64 01615c622e630164010164 +format - 615c622e63 64 64 - 615c622e635c64 normalize 433a2e747874 433a2e747874 dirname 433a2e747874 433a basename 433a2e747874 2e747874 @@ -1020,6 +1310,8 @@ extname 433a2e747874 - isAbsolute 433a2e747874 66616c7365 toNamespacedPath 433a2e747874 5c5c3f5c433a5c2e747874 resolve1 433a2e747874 433a5c2e747874 +parse 433a2e747874 433a01433a012e74787401012e747874 +format 433a 433a 2e747874 2e747874 - 433a2e747874 normalize 433a5c2e2e747874 433a5c2e2e747874 dirname 433a5c2e2e747874 433a5c basename 433a5c2e2e747874 2e2e747874 @@ -1027,6 +1319,8 @@ extname 433a5c2e2e747874 2e747874 isAbsolute 433a5c2e2e747874 74727565 toNamespacedPath 433a5c2e2e747874 5c5c3f5c433a5c2e2e747874 resolve1 433a5c2e2e747874 433a5c2e2e747874 +parse 433a5c2e2e747874 433a5c01433a5c012e2e747874012e747874012e +format 433a5c 433a5c 2e2e747874 2e 2e747874 433a5c2e2e747874 normalize 785c2e2e 2e dirname 785c2e2e 78 basename 785c2e2e 2e2e @@ -1034,6 +1328,8 @@ extname 785c2e2e - isAbsolute 785c2e2e 66616c7365 toNamespacedPath 785c2e2e 785c2e2e resolve1 785c2e2e 5c +parse 785c2e2e 0178012e2e01012e2e +format - 78 2e2e 2e2e - 785c2e2e normalize 2e2e5c2e 2e2e dirname 2e2e5c2e 2e2e basename 2e2e5c2e 2e @@ -1041,6 +1337,8 @@ extname 2e2e5c2e - isAbsolute 2e2e5c2e 66616c7365 toNamespacedPath 2e2e5c2e 2e2e5c2e resolve1 2e2e5c2e 5c +parse 2e2e5c2e 012e2e012e01012e +format - 2e2e 2e 2e - 2e2e5c2e normalize 20 20 dirname 20 2e basename 20 20 @@ -1048,6 +1346,8 @@ extname 20 - isAbsolute 20 66616c7365 toNamespacedPath 20 20 resolve1 20 5c20 +parse 20 010120010120 +format - - 20 20 - 20 normalize 202f61 205c61 dirname 202f61 20 basename 202f61 61 @@ -1055,6 +1355,8 @@ extname 202f61 - isAbsolute 202f61 66616c7365 toNamespacedPath 202f61 5c205c61 resolve1 202f61 5c205c61 +parse 202f61 01200161010161 +format - 20 61 61 - 205c61 normalize 205c61 205c61 dirname 205c61 20 basename 205c61 61 @@ -1062,6 +1364,8 @@ extname 205c61 - isAbsolute 205c61 66616c7365 toNamespacedPath 205c61 5c205c61 resolve1 205c61 5c205c61 +parse 205c61 01200161010161 +format - 20 61 61 - 205c61 normalize 6120625c632064 6120625c632064 dirname 6120625c632064 612062 basename 6120625c632064 632064 @@ -1069,6 +1373,8 @@ extname 6120625c632064 - isAbsolute 6120625c632064 66616c7365 toNamespacedPath 6120625c632064 5c6120625c632064 resolve1 6120625c632064 5c6120625c632064 +parse 6120625c632064 01612062016320640101632064 +format - 612062 632064 632064 - 6120625c632064 normalize 09610a 09610a dirname 09610a 2e basename 09610a 09610a @@ -1076,6 +1382,8 @@ extname 09610a - isAbsolute 09610a 66616c7365 toNamespacedPath 09610a 5c09610a resolve1 09610a 5c09610a +parse 09610a 010109610a010109610a +format - - 09610a 09610a - 09610a normalize c3a9 c3a9 dirname c3a9 2e basename c3a9 c3a9 @@ -1083,6 +1391,8 @@ extname c3a9 - isAbsolute c3a9 66616c7365 toNamespacedPath c3a9 c3a9 resolve1 c3a9 5cc3a9 +parse c3a9 0101c3a90101c3a9 +format - - c3a9 c3a9 - c3a9 normalize 433a5c636166c3a95c6e61c3af7665 433a5c636166c3a95c6e61c3af7665 dirname 433a5c636166c3a95c6e61c3af7665 433a5c636166c3a9 basename 433a5c636166c3a95c6e61c3af7665 6e61c3af7665 @@ -1090,6 +1400,8 @@ extname 433a5c636166c3a95c6e61c3af7665 - isAbsolute 433a5c636166c3a95c6e61c3af7665 74727565 toNamespacedPath 433a5c636166c3a95c6e61c3af7665 5c5c3f5c433a5c636166c3a95c6e61c3af7665 resolve1 433a5c636166c3a95c6e61c3af7665 433a5c636166c3a95c6e61c3af7665 +parse 433a5c636166c3a95c6e61c3af7665 433a5c01433a5c636166c3a9016e61c3af766501016e61c3af7665 +format 433a5c 433a5c636166c3a9 6e61c3af7665 6e61c3af7665 - 433a5c636166c3a95c6e61c3af7665 normalize e4bda0e5a5bd2fe4b896e7958c e4bda0e5a5bd5ce4b896e7958c dirname e4bda0e5a5bd2fe4b896e7958c e4bda0e5a5bd basename e4bda0e5a5bd2fe4b896e7958c e4b896e7958c @@ -1097,6 +1409,8 @@ extname e4bda0e5a5bd2fe4b896e7958c - isAbsolute e4bda0e5a5bd2fe4b896e7958c 66616c7365 toNamespacedPath e4bda0e5a5bd2fe4b896e7958c 5ce4bda0e5a5bd5ce4b896e7958c resolve1 e4bda0e5a5bd2fe4b896e7958c 5ce4bda0e5a5bd5ce4b896e7958c +parse e4bda0e5a5bd2fe4b896e7958c 01e4bda0e5a5bd01e4b896e7958c0101e4b896e7958c +format - e4bda0e5a5bd e4b896e7958c e4b896e7958c - e4bda0e5a5bd5ce4b896e7958c normalize 5c5c73c3a9727665725c7368617265 5c5c73c3a9727665725c73686172655c dirname 5c5c73c3a9727665725c7368617265 5c5c73c3a9727665725c7368617265 basename 5c5c73c3a9727665725c7368617265 7368617265 @@ -1104,6 +1418,8 @@ extname 5c5c73c3a9727665725c7368617265 - isAbsolute 5c5c73c3a9727665725c7368617265 74727565 toNamespacedPath 5c5c73c3a9727665725c7368617265 5c5c3f5c554e435c73c3a9727665725c73686172655c resolve1 5c5c73c3a9727665725c7368617265 5c5c73c3a9727665725c73686172655c +parse 5c5c73c3a9727665725c7368617265 5c5c73c3a9727665725c7368617265015c5c73c3a9727665725c7368617265010101 +format 5c5c73c3a9727665725c7368617265 5c5c73c3a9727665725c7368617265 - - - 5c5c73c3a9727665725c7368617265 normalize 433a5cf09f98805c78 433a5cf09f98805c78 dirname 433a5cf09f98805c78 433a5cf09f9880 basename 433a5cf09f98805c78 78 @@ -1111,6 +1427,8 @@ extname 433a5cf09f98805c78 - isAbsolute 433a5cf09f98805c78 74727565 toNamespacedPath 433a5cf09f98805c78 5c5c3f5c433a5cf09f98805c78 resolve1 433a5cf09f98805c78 433a5cf09f98805c78 +parse 433a5cf09f98805c78 433a5c01433a5cf09f98800178010178 +format 433a5c 433a5cf09f9880 78 78 - 433a5cf09f98805c78 normalize 4e554cc2b9 2e5c4e554cc2b9 dirname 4e554cc2b9 2e basename 4e554cc2b9 4e554cc2b9 @@ -1118,6 +1436,8 @@ extname 4e554cc2b9 - isAbsolute 4e554cc2b9 66616c7365 toNamespacedPath 4e554cc2b9 5c4e554cc2b9 resolve1 4e554cc2b9 5c4e554cc2b9 +parse 4e554cc2b9 01014e554cc2b901014e554cc2b9 +format - - 4e554cc2b9 4e554cc2b9 - 4e554cc2b9 normalize 4e554cf09f9880 4e554cf09f9880 dirname 4e554cf09f9880 2e basename 4e554cf09f9880 4e554cf09f9880 @@ -1125,6 +1445,152 @@ extname 4e554cf09f9880 - isAbsolute 4e554cf09f9880 66616c7365 toNamespacedPath 4e554cf09f9880 5c4e554cf09f9880 resolve1 4e554cf09f9880 5c4e554cf09f9880 +parse 4e554cf09f9880 01014e554cf09f988001014e554cf09f9880 +format - - 4e554cf09f9880 4e554cf09f9880 - 4e554cf09f9880 +format - - - - - - +format - - - - 65 2e65 +format - - - - 2e65 2e65 +format - - - 6e - 6e +format - - - 6e 65 6e2e65 +format - - - 6e 2e65 6e2e65 +format - - 622e78 - - 622e78 +format - - 622e78 - 65 622e78 +format - - 622e78 - 2e65 622e78 +format - - 622e78 6e - 622e78 +format - - 622e78 6e 65 622e78 +format - - 622e78 6e 2e65 622e78 +format - 433a5c - - - 433a5c5c +format - 433a5c - - 65 433a5c5c2e65 +format - 433a5c - - 2e65 433a5c5c2e65 +format - 433a5c - 6e - 433a5c5c6e +format - 433a5c - 6e 65 433a5c5c6e2e65 +format - 433a5c - 6e 2e65 433a5c5c6e2e65 +format - 433a5c 622e78 - - 433a5c5c622e78 +format - 433a5c 622e78 - 65 433a5c5c622e78 +format - 433a5c 622e78 - 2e65 433a5c5c622e78 +format - 433a5c 622e78 6e - 433a5c5c622e78 +format - 433a5c 622e78 6e 65 433a5c5c622e78 +format - 433a5c 622e78 6e 2e65 433a5c5c622e78 +format - 64 - - - 645c +format - 64 - - 65 645c2e65 +format - 64 - - 2e65 645c2e65 +format - 64 - 6e - 645c6e +format - 64 - 6e 65 645c6e2e65 +format - 64 - 6e 2e65 645c6e2e65 +format - 64 622e78 - - 645c622e78 +format - 64 622e78 - 65 645c622e78 +format - 64 622e78 - 2e65 645c622e78 +format - 64 622e78 6e - 645c622e78 +format - 64 622e78 6e 65 645c622e78 +format - 64 622e78 6e 2e65 645c622e78 +format - 433a5c64 - - - 433a5c645c +format - 433a5c64 - - 65 433a5c645c2e65 +format - 433a5c64 - - 2e65 433a5c645c2e65 +format - 433a5c64 - 6e - 433a5c645c6e +format - 433a5c64 - 6e 65 433a5c645c6e2e65 +format - 433a5c64 - 6e 2e65 433a5c645c6e2e65 +format - 433a5c64 622e78 - - 433a5c645c622e78 +format - 433a5c64 622e78 - 65 433a5c645c622e78 +format - 433a5c64 622e78 - 2e65 433a5c645c622e78 +format - 433a5c64 622e78 6e - 433a5c645c622e78 +format - 433a5c64 622e78 6e 65 433a5c645c622e78 +format - 433a5c64 622e78 6e 2e65 433a5c645c622e78 +format 433a5c - - - - 433a5c +format 433a5c - - - 65 433a5c2e65 +format 433a5c - - - 2e65 433a5c2e65 +format 433a5c - - 6e - 433a5c6e +format 433a5c - - 6e 65 433a5c6e2e65 +format 433a5c - - 6e 2e65 433a5c6e2e65 +format 433a5c - 622e78 - - 433a5c622e78 +format 433a5c - 622e78 - 65 433a5c622e78 +format 433a5c - 622e78 - 2e65 433a5c622e78 +format 433a5c - 622e78 6e - 433a5c622e78 +format 433a5c - 622e78 6e 65 433a5c622e78 +format 433a5c - 622e78 6e 2e65 433a5c622e78 +format 433a5c 433a5c - - - 433a5c +format 433a5c 433a5c - - 65 433a5c2e65 +format 433a5c 433a5c - - 2e65 433a5c2e65 +format 433a5c 433a5c - 6e - 433a5c6e +format 433a5c 433a5c - 6e 65 433a5c6e2e65 +format 433a5c 433a5c - 6e 2e65 433a5c6e2e65 +format 433a5c 433a5c 622e78 - - 433a5c622e78 +format 433a5c 433a5c 622e78 - 65 433a5c622e78 +format 433a5c 433a5c 622e78 - 2e65 433a5c622e78 +format 433a5c 433a5c 622e78 6e - 433a5c622e78 +format 433a5c 433a5c 622e78 6e 65 433a5c622e78 +format 433a5c 433a5c 622e78 6e 2e65 433a5c622e78 +format 433a5c 64 - - - 645c +format 433a5c 64 - - 65 645c2e65 +format 433a5c 64 - - 2e65 645c2e65 +format 433a5c 64 - 6e - 645c6e +format 433a5c 64 - 6e 65 645c6e2e65 +format 433a5c 64 - 6e 2e65 645c6e2e65 +format 433a5c 64 622e78 - - 645c622e78 +format 433a5c 64 622e78 - 65 645c622e78 +format 433a5c 64 622e78 - 2e65 645c622e78 +format 433a5c 64 622e78 6e - 645c622e78 +format 433a5c 64 622e78 6e 65 645c622e78 +format 433a5c 64 622e78 6e 2e65 645c622e78 +format 433a5c 433a5c64 - - - 433a5c645c +format 433a5c 433a5c64 - - 65 433a5c645c2e65 +format 433a5c 433a5c64 - - 2e65 433a5c645c2e65 +format 433a5c 433a5c64 - 6e - 433a5c645c6e +format 433a5c 433a5c64 - 6e 65 433a5c645c6e2e65 +format 433a5c 433a5c64 - 6e 2e65 433a5c645c6e2e65 +format 433a5c 433a5c64 622e78 - - 433a5c645c622e78 +format 433a5c 433a5c64 622e78 - 65 433a5c645c622e78 +format 433a5c 433a5c64 622e78 - 2e65 433a5c645c622e78 +format 433a5c 433a5c64 622e78 6e - 433a5c645c622e78 +format 433a5c 433a5c64 622e78 6e 65 433a5c645c622e78 +format 433a5c 433a5c64 622e78 6e 2e65 433a5c645c622e78 +format 5c - - - - 5c +format 5c - - - 65 5c2e65 +format 5c - - - 2e65 5c2e65 +format 5c - - 6e - 5c6e +format 5c - - 6e 65 5c6e2e65 +format 5c - - 6e 2e65 5c6e2e65 +format 5c - 622e78 - - 5c622e78 +format 5c - 622e78 - 65 5c622e78 +format 5c - 622e78 - 2e65 5c622e78 +format 5c - 622e78 6e - 5c622e78 +format 5c - 622e78 6e 65 5c622e78 +format 5c - 622e78 6e 2e65 5c622e78 +format 5c 433a5c - - - 433a5c5c +format 5c 433a5c - - 65 433a5c5c2e65 +format 5c 433a5c - - 2e65 433a5c5c2e65 +format 5c 433a5c - 6e - 433a5c5c6e +format 5c 433a5c - 6e 65 433a5c5c6e2e65 +format 5c 433a5c - 6e 2e65 433a5c5c6e2e65 +format 5c 433a5c 622e78 - - 433a5c5c622e78 +format 5c 433a5c 622e78 - 65 433a5c5c622e78 +format 5c 433a5c 622e78 - 2e65 433a5c5c622e78 +format 5c 433a5c 622e78 6e - 433a5c5c622e78 +format 5c 433a5c 622e78 6e 65 433a5c5c622e78 +format 5c 433a5c 622e78 6e 2e65 433a5c5c622e78 +format 5c 64 - - - 645c +format 5c 64 - - 65 645c2e65 +format 5c 64 - - 2e65 645c2e65 +format 5c 64 - 6e - 645c6e +format 5c 64 - 6e 65 645c6e2e65 +format 5c 64 - 6e 2e65 645c6e2e65 +format 5c 64 622e78 - - 645c622e78 +format 5c 64 622e78 - 65 645c622e78 +format 5c 64 622e78 - 2e65 645c622e78 +format 5c 64 622e78 6e - 645c622e78 +format 5c 64 622e78 6e 65 645c622e78 +format 5c 64 622e78 6e 2e65 645c622e78 +format 5c 433a5c64 - - - 433a5c645c +format 5c 433a5c64 - - 65 433a5c645c2e65 +format 5c 433a5c64 - - 2e65 433a5c645c2e65 +format 5c 433a5c64 - 6e - 433a5c645c6e +format 5c 433a5c64 - 6e 65 433a5c645c6e2e65 +format 5c 433a5c64 - 6e 2e65 433a5c645c6e2e65 +format 5c 433a5c64 622e78 - - 433a5c645c622e78 +format 5c 433a5c64 622e78 - 65 433a5c645c622e78 +format 5c 433a5c64 622e78 - 2e65 433a5c645c622e78 +format 5c 433a5c64 622e78 6e - 433a5c645c622e78 +format 5c 433a5c64 622e78 6e 65 433a5c645c622e78 +format 5c 433a5c64 622e78 6e 2e65 433a5c645c622e78 basenameSuffix 6261722e747874 2e747874 626172 basenameSuffix 2e747874 2e747874 - basenameSuffix 666f6f2e545854 2e747874 666f6f2e545854 diff --git a/packages/runtime/test/test_path.c b/packages/runtime/test/test_path.c index 1bce4a89f..c55af2a02 100644 --- a/packages/runtime/test/test_path.c +++ b/packages/runtime/test/test_path.c @@ -157,6 +157,22 @@ int main(int argc, char **argv) { scr_arr_release(pack); } else if (strcmp(op, "relative") == 0) { result = scr_path_win32_relative(args[0], args[1]); + } else if (strcmp(op, "parse") == 0) { + /* The five fields joined by U+0001, like the generator. */ + ScrArr *parts = scr_path_win32_parse(args[0]); + char joined[MAX_FIELD]; + size_t used = 0; + for (size_t k = 0; k < parts->len; k++) { + ScrStr *part = scr_arr_get_ref(parts, (double)k); + if (k > 0) joined[used++] = '\x01'; + memcpy(joined + used, part->data, part->len); + used += part->len; + scr_str_release(part); + } + scr_arr_release(parts); + check(op, args, nargs, joined, used, expbuf, explen); + } else if (strcmp(op, "format") == 0) { + result = scr_path_win32_format(args[0], args[1], args[2], args[3], args[4]); } else { fprintf(stderr, "unknown op: %s\n", op); return 2; diff --git a/tests/corpus/5140-os-host-facts.ts b/tests/corpus/5140-os-host-facts.ts new file mode 100644 index 000000000..2ae469ce1 --- /dev/null +++ b/tests/corpus/5140-os-host-facts.ts @@ -0,0 +1,57 @@ +// node:os host facts: cpus, hostname, arch, machine, version, endianness, +// freemem, loadavg, uptime, devNull and getPriority. Host values differ +// between machines, so this prints their shapes, types and invariants. +import * as os from "node:os"; +import { cpus, devNull, getPriority, hostname } from "node:os"; + +const list = os.cpus(); +const first = list[0]!; +console.log("cpus", list.length > 0, list.length === cpus().length); +console.log(Object.keys(first), Object.keys(first.times), typeof first.model, typeof first.speed); +console.log( + list.every( + (cpu) => + cpu.model.length >= 0 && + Number.isInteger(cpu.speed) && + cpu.speed >= 0 && + [cpu.times.user, cpu.times.nice, cpu.times.sys, cpu.times.idle, cpu.times.irq].every( + (t) => Number.isInteger(t) && t >= 0, + ), + ), +); +console.log(JSON.stringify(Object.keys(JSON.parse(JSON.stringify(first))))); + +console.log("hostname", typeof os.hostname(), os.hostname().length > 0, hostname() === os.hostname()); +console.log("arch", os.arch() === process.arch, typeof os.machine(), os.machine().length > 0); +console.log("version", typeof os.version(), os.version() === os.version()); +console.log("endianness", os.endianness()); + +const free = os.freemem(); +console.log("freemem", typeof free, free > 0, free <= os.totalmem(), Number.isInteger(free)); +const load = os.loadavg(); +console.log("loadavg", Array.isArray(load), load.length, load.every((v) => typeof v === "number" && v >= 0)); +const up = os.uptime(); +console.log("uptime", typeof up, up > 0, os.uptime() >= up); + +console.log("devNull", JSON.stringify(devNull), os.devNull === devNull); + +const priority = os.getPriority(); +console.log("priority", typeof priority, priority === getPriority(0), priority === os.getPriority(process.pid)); +console.log(priority >= os.constants.priority.PRIORITY_HIGHEST && priority <= os.constants.priority.PRIORITY_LOW); +const maybe: number | undefined = undefined; +console.log(os.getPriority(maybe) === priority); +for (const pid of [1.5, -0.5, Number.NaN, 2 ** 31, -(2 ** 31) - 1, 2 ** 40]) { + try { + os.getPriority(pid); + console.log("no throw", pid); + } catch (e) { + const err = e as Error & { code?: string }; + console.log(err.name, err.code, err.message); + } +} +try { + os.getPriority(2147483646); +} catch (e) { + const err = e as Error & { code?: string }; + console.log(err instanceof Error, err.name, err.code, err.message); +} diff --git a/tests/corpus/5141-os-constants.ts b/tests/corpus/5141-os-constants.ts new file mode 100644 index 000000000..6b2540b3e --- /dev/null +++ b/tests/corpus/5141-os-constants.ts @@ -0,0 +1,36 @@ +// os.constants: the null-prototype groups, read-only numeric members, +// the frozen signals group, one object per program, and member reads +// that are missing on some platforms. Only values every platform shares +// are printed. +import * as os from "node:os"; +import { constants } from "node:os"; + +console.log(Object.keys(os.constants)); +console.log(os.constants === constants, os.constants.signals === constants.signals); +console.log(Object.getPrototypeOf(os.constants) === null, Object.getPrototypeOf(os.constants.errno) === null); +console.log(Object.isFrozen(os.constants.signals), Object.isFrozen(os.constants.errno)); +console.log(os.constants.UV_UDP_REUSEADDR); +console.log(JSON.stringify(os.constants.priority)); +console.log(os.constants.priority); +console.log(os.constants.signals.SIGINT, os.constants.signals.SIGTERM, os.constants.signals.SIGKILL); +console.log(os.constants.errno.ENOENT, os.constants.errno.EACCES, os.constants.errno.EEXIST); + +// Dynamic names, entries and destructuring. +for (const name of ["SIGINT", "SIGTERM"] as const) console.log(name, os.constants.signals[name]); +const entries = Object.entries(os.constants.signals); +console.log(entries.length > 5, entries.some(([name, value]) => name === "SIGINT" && value === 2)); +const { signals, errno, priority } = constants; +console.log(signals.SIGKILL, errno.ENOENT, priority.PRIORITY_NORMAL); +function lookup(name: string): number | undefined { + return (os.constants.signals as Record)[name]; +} +console.log(lookup("SIGTERM"), lookup("SIGNOPE")); + +// A member some platforms lack reads as undefined until converted. +const breakSignal = os.constants.signals.SIGBREAK; +console.log(breakSignal === undefined || typeof breakSignal === "number"); + +// Numeric uses. +const term: number = os.constants.signals.SIGTERM; +console.log(term + 1, os.constants.signals.SIGINT * 2, Math.max(os.constants.priority.PRIORITY_LOW, 0)); +console.log(`${os.constants.errno.ENOENT}`, String(os.constants.priority.PRIORITY_HIGH), os.constants.priority.PRIORITY_HIGHEST < 0); diff --git a/tests/corpus/5142-path-parse-format.ts b/tests/corpus/5142-path-parse-format.ts new file mode 100644 index 000000000..4458d7d95 --- /dev/null +++ b/tests/corpus/5142-path-parse-format.ts @@ -0,0 +1,56 @@ +// path.parse and path.format for the posix and win32 families: roots, +// trailing separators, dot files, extensions, UNC and drive roots, and +// format's `||` defaults, round-tripped through each other. +import * as path from "node:path"; +import { format, parse } from "node:path/posix"; + +const posixCases = [ + "", "/", "//", "///a//", ".", "..", "a/..", ".hidden", "/.hidden", "file.", "a.b.c", + "/a/b/c/", "./", "../x.y", "/home/user/dir/file.txt", "dir/sub/", "a//b", "/a/.b.c.", + "..ext", "/foo/bar.baz/", "x/y.z/..", "unicodé/fïle.tşt", "emoji/😀.png", +]; +for (const p of posixCases) { + const parsed = path.posix.parse(p); + console.log(JSON.stringify(p), JSON.stringify(parsed), JSON.stringify(path.posix.format(parsed))); +} + +const winCases = [ + "", "C:", "C:\\", "C:\\a", "c:foo.txt", "\\", "/", "\\\\server\\share", "\\\\server\\share\\", + "\\\\server\\share\\a\\b.c", "\\\\server", "\\\\server\\", "a/b\\c.d", "\\\\?\\C:\\x.y", + "C:\\..\\x", "C:\\path\\dir\\file.txt", "C:/mixed/sep/f.e", "\\\\.\\COM1", "dir\\", ".\\.git", + "C:\\.hidden", "d:\\a\\..", +]; +for (const p of winCases) { + const parsed = path.win32.parse(p); + console.log(JSON.stringify(p), JSON.stringify(parsed), JSON.stringify(path.win32.format(parsed))); +} + +// format's defaults: dir wins over root, base over name + ext, and the +// separator is skipped when dir is the root. +const objects: path.FormatInputPathObject[] = [ + {}, + { root: "/" }, + { dir: "/a" }, + { root: "/", dir: "/" , base: "x" }, + { root: "/", base: "x" }, + { dir: "a", base: "b" }, + { dir: "a", name: "n", ext: "e" }, + { dir: "a", name: "n", ext: ".e" }, + { name: "n" }, + { ext: "e" }, + { base: "", name: "n", ext: "" }, + { root: "/r/", dir: "/r/", name: "x", ext: ".y" }, + { root: "/x", dir: "", base: "b" }, + { dir: undefined, root: undefined, name: "only" }, +]; +objects.forEach((o, i) => { + console.log(i, JSON.stringify(path.posix.format(o)), JSON.stringify(path.win32.format(o))); +}); + +// Named imports, the bare module and typed bindings. +const parsed: path.ParsedPath = parse("/srv/app/index.js"); +console.log(parsed.root, parsed.dir, parsed.base, parsed.ext, parsed.name, format(parsed)); +const keys = Object.keys(path.parse("x/y.z")); +console.log(keys.join(","), path.format({ dir: "x", base: "y.z" }) === path.join("x", "y.z")); +const back = path.win32.format(path.win32.parse("C:\\Users\\me\\notes.md")); +console.log(back, path.win32.parse(back).name); diff --git a/tests/fixtures/node-types/fenced.ts b/tests/fixtures/node-types/fenced.ts index d327b6b70..5d5311c7f 100644 --- a/tests/fixtures/node-types/fenced.ts +++ b/tests/fixtures/node-types/fenced.ts @@ -34,10 +34,10 @@ ReadableStream.from(new Set([1, 2])); * typecheck under @types/node and fence with the module-qualified name — * calls and value reads alike. */ import { watchFile } from "fs"; -import { cpus } from "node:os"; +import { setPriority } from "node:os"; import { win32 } from "path"; watchFile("x", () => {}); -console.log(cpus().length); +setPriority(0); console.log(win32.sep); /* URL getters and serialization lower under @types/node, but object-URL * registry operations still fence by member name with the supported diff --git a/tests/harness/__snapshots__/node-types-fenced.txt b/tests/harness/__snapshots__/node-types-fenced.txt index 1725513d3..6ffee77e9 100644 --- a/tests/harness/__snapshots__/node-types-fenced.txt +++ b/tests/harness/__snapshots__/node-types-fenced.txt @@ -57,22 +57,22 @@ fenced.ts:39:1 - error SC2020: 'fs.watchFile' is typed by @types/node but has no 38 | import { win32 } from "path"; 39 | watchFile("x", () => {}); | ^~~~~~~~~~~~~~~~~~~~~~~~ - 40 | console.log(cpus().length); + 40 | setPriority(0); hint: the type checker sees everything @types/node declares, but only the supported surface compiles (https://scriptc.dev/limitations) -fenced.ts:40:13 - error SC2020: 'CpuInfo[].length' is part of the standard library types but has no scriptc lowering yet +fenced.ts:40:1 - error SC2020: 'os.setPriority' is typed by @types/node but has no scriptc lowering yet 39 | watchFile("x", () => {}); - 40 | console.log(cpus().length); - | ^~~~~~~~~~~~~ + 40 | setPriority(0); + | ^~~~~~~~~~~~~~ 41 | console.log(win32.sep); - hint: the type checker sees the full standard library, but only the supported surface compiles (https://scriptc.dev/limitations) + hint: the type checker sees everything @types/node declares, but only the supported surface compiles (https://scriptc.dev/limitations) fenced.ts:41:13 - error SC2020: 'PlatformPath.sep' is typed by @types/node but has no scriptc lowering yet - 40 | console.log(cpus().length); + 40 | setPriority(0); 41 | console.log(win32.sep); | ^~~~~~~~~ 42 | /* URL getters and serialization lower under @types/node, but object-URL