{ "stdlib_version": "v0.5.0", "modules": { "STDARGS": { "synopsis": "m-stdlib — argparse (v0.0.7).", "description": "Public API. The parser handle is a positive integer keyed under\n^STDLIB($job,\"stdargs\",p,...); state is per-process and per-handle.\n\n $$new^STDARGS(prog,desc) — alloc parser, return p\n addflag^STDARGS(p,long,short,action,dest) — register a flag\n addpos^STDARGS(p,name,dest) — register a positional\n addsub^STDARGS(p,name,subParserHandle) — register a sub-command\n parse^STDARGS(p,argline,.ns) — parse argline into ns\n $$help^STDARGS(p) — formatted help text\n free^STDARGS(p) — drop parser state\n\nActions:\n store_true ns(dest)=1 if flag seen; default 0\n store ns(dest)=\n count ns(dest)+=1 per occurrence; default 0; \"-vvv\" expands\n append $increment(k); ns(dest,k)=\n\n\"--\" terminates flag parsing — subsequent tokens are positional even\nwhen they start with \"-\".\n\nSub-commands: when any sub is registered, the first non-flag token\nmust match a sub name; the remainder is re-parsed by the sub-parser\nagainst the same ns. The chosen sub name is recorded as ns(\"__sub__\").\n\nArgs source: $ZCMDLINE on YDB; an explicit string elsewhere.\nTokenisation is whitespace-only — quoting is the shell's job.\n\nErrors set $ECODE to one of:\n ,U-STDARGS-UNKNOWN-ACTION,\n ,U-STDARGS-UNKNOWN-FLAG,\n ,U-STDARGS-UNKNOWN-SUBCOMMAND,\n ,U-STDARGS-MISSING-VALUE,\n ,U-STDARGS-MISSING-POSITIONAL,", "errors": [ "U-STDARGS-UNKNOWN-ACTION", "U-STDARGS-UNKNOWN-FLAG", "U-STDARGS-UNKNOWN-SUBCOMMAND", "U-STDARGS-MISSING-VALUE", "U-STDARGS-MISSING-POSITIONAL" ], "labels": { "new": { "form": "extrinsic", "signature": "$$new^STDARGS(prog, desc)", "synopsis": "Allocate a fresh parser handle.", "params": [ { "name": "prog", "type": "string", "doc": "program name (rendered into the help banner)" }, { "name": "desc", "type": "string", "doc": "one-line description (rendered into the help banner)" } ], "returns": { "type": "int", "doc": "positive parser handle; pass to addflag / addpos / addsub / parse / help / free" }, "raises": [], "raised_in_body": [], "examples": [ "set p=$$new^STDARGS(\"widget\",\"frob the widget\")" ], "since": "v0.0.7", "stable": "stable", "see_also": [ "do free^STDARGS", "do addflag^STDARGS", "do addpos^STDARGS", "do parse^STDARGS" ], "deprecated": "", "description": "", "source": { "file": "src/STDARGS.m", "line": 41 } }, "free": { "form": "procedure", "signature": "do free^STDARGS(p)", "synopsis": "Release a parser's state.", "params": [ { "name": "p", "type": "int", "doc": "parser handle from new()" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do free^STDARGS(p)" ], "since": "v0.0.7", "stable": "stable", "see_also": [ "$$new^STDARGS" ], "deprecated": "", "description": "Idempotent. The handle must not be reused after free().", "source": { "file": "src/STDARGS.m", "line": 55 } }, "addflag": { "form": "procedure", "signature": "do addflag^STDARGS(p, long, short, action, dest)", "synopsis": "Register a flag.", "params": [ { "name": "p", "type": "int", "doc": "parser handle from new()" }, { "name": "long", "type": "string", "doc": "long form including \"--\" prefix (e.g. \"--verbose\")" }, { "name": "short", "type": "string", "doc": "short form including \"-\" prefix; \"\" if no short" }, { "name": "action", "type": "string", "doc": "one of: store_true, store, count, append" }, { "name": "dest", "type": "string", "doc": "ns(dest) subscript that the parsed value lands in" } ], "returns": null, "raises": [ { "code": "U-STDARGS-UNKNOWN-ACTION", "doc": "`action` is not one of the four documented values" } ], "raised_in_body": [], "examples": [ "do addflag^STDARGS(p,\"--verbose\",\"-v\",\"store_true\",\"verbose\")" ], "since": "v0.0.7", "stable": "stable", "see_also": [ "do addpos^STDARGS", "do addsub^STDARGS" ], "deprecated": "", "description": "", "source": { "file": "src/STDARGS.m", "line": 65 } }, "addpos": { "form": "procedure", "signature": "do addpos^STDARGS(p, name, dest)", "synopsis": "Register a positional argument.", "params": [ { "name": "p", "type": "int", "doc": "parser handle from new()" }, { "name": "name", "type": "string", "doc": "positional's display name (rendered into help)" }, { "name": "dest", "type": "string", "doc": "ns(dest) subscript that the value lands in" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do addpos^STDARGS(p,\"path\",\"path\")" ], "since": "v0.0.7", "stable": "stable", "see_also": [ "do addflag^STDARGS", "do parse^STDARGS" ], "deprecated": "", "description": "Positionals are filled in addpos() declaration order.", "source": { "file": "src/STDARGS.m", "line": 86 } }, "addsub": { "form": "procedure", "signature": "do addsub^STDARGS(p, name, sub)", "synopsis": "Register a sub-command -> sub-parser handle.", "params": [ { "name": "p", "type": "int", "doc": "parser handle from new()" }, { "name": "name", "type": "string", "doc": "sub-command name (matched against the first non-flag token)" }, { "name": "sub", "type": "int", "doc": "parser handle from a separate new() call — the sub-parser" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do addsub^STDARGS(p,\"add\",subHandle)" ], "since": "v0.0.7", "stable": "stable", "see_also": [ "do parse^STDARGS" ], "deprecated": "", "description": "When a parser has any sub-commands, the first non-flag token\nmust name one — `parse` raises U-STDARGS-UNKNOWN-SUBCOMMAND otherwise.", "source": { "file": "src/STDARGS.m", "line": 101 } }, "parse": { "form": "procedure", "signature": "do parse^STDARGS(p, argline, ns)", "synopsis": "Parse argline; populate ns(dest)=value.", "params": [ { "name": "p", "type": "int", "doc": "parser handle from new()" }, { "name": "argline", "type": "string", "doc": "the raw command line (e.g. $ZCMDLINE on YDB)" }, { "name": "ns", "type": "array", "doc": "by-ref local; populated as ns(dest)=value" } ], "returns": null, "raises": [ { "code": "U-STDARGS-UNKNOWN-FLAG", "doc": "token starts with \"-\" but isn't a registered flag" }, { "code": "U-STDARGS-UNKNOWN-SUBCOMMAND", "doc": "first non-flag token doesn't match any addsub() name" }, { "code": "U-STDARGS-MISSING-VALUE", "doc": "a `store` / `append` flag has no value token after it" }, { "code": "U-STDARGS-MISSING-POSITIONAL", "doc": "a registered positional was not supplied" } ], "raised_in_body": [], "examples": [ "do parse^STDARGS(p,$zcmdline,.ns)" ], "since": "v0.0.7", "stable": "stable", "see_also": [ "$$help^STDARGS" ], "deprecated": "", "description": "ns is by-reference. On parse error sets $ECODE to one of the\ndocumented codes; otherwise returns silently.", "source": { "file": "src/STDARGS.m", "line": 114 } }, "help": { "form": "extrinsic", "signature": "$$help^STDARGS(p)", "synopsis": "Return formatted help text.", "params": [ { "name": "p", "type": "int", "doc": "parser handle from new()" } ], "returns": { "type": "string", "doc": "multi-line help banner — usage line, description, flags, positionals, commands" }, "raises": [], "raised_in_body": [], "examples": [ "write $$help^STDARGS(p)" ], "since": "v0.0.7", "stable": "stable", "see_also": [ "$$new^STDARGS", "do parse^STDARGS" ], "deprecated": "", "description": "Lists usage line, description, then flags, positionals, commands.", "source": { "file": "src/STDARGS.m", "line": 133 } } }, "source": { "file": "src/STDARGS.m", "line": 1 } }, "STDASSERT": { "synopsis": "m-stdlib — assertion library (v0.0.1).", "description": "Output protocol mirrors m-tools/^TESTRUN exactly so m-cli's\n`m test` runner accepts STDASSERT-driven suites unchanged:\n \" PASS \" (two leading spaces)\n \" FAIL \"\n \" expected: \" (nine leading spaces)\n \" actual: \"\n \"Results: tests

passed failed\"\n \"All tests passed.\" -or- \" test(s) FAILED.\"\n\nSuite shape:\n STDASSERTTST ;\n new pass,fail\n do start^STDASSERT(.pass,.fail)\n do tMyCase(.pass,.fail)\n do report^STDASSERT(pass,fail)\n quit", "errors": [], "labels": { "start": { "form": "procedure", "signature": "do start^STDASSERT(p, f)", "synopsis": "Initialise pass/fail counters (call by-reference).", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref; set to 0)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref; set to 0)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do start^STDASSERT(.pass,.fail)" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do report^STDASSERT", "do eq^STDASSERT" ], "deprecated": "", "description": "Call once at the top of every suite entry.", "source": { "file": "src/STDASSERT.m", "line": 22 } }, "report": { "form": "procedure", "signature": "do report^STDASSERT(p, f)", "synopsis": "Print summary; halt with error if any failures.", "params": [ { "name": "p", "type": "int", "doc": "pass count" }, { "name": "f", "type": "int", "doc": "fail count" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do report^STDASSERT(pass,fail)" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do start^STDASSERT" ], "deprecated": "", "description": "Emits the \"Results:\" line m-cli's runner parses.\nHalts with non-zero status if f>0 — drives CI exit code.", "source": { "file": "src/STDASSERT.m", "line": 42 } }, "eq": { "form": "procedure", "signature": "do eq^STDASSERT(p, f, actual, expected, desc)", "synopsis": "Assert actual=expected (string equality).", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref)" }, { "name": "actual", "type": "string", "doc": "observed value" }, { "name": "expected", "type": "string", "doc": "expected value" }, { "name": "desc", "type": "string", "doc": "human-readable assertion description" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do eq^STDASSERT(.pass,.fail,result,\"hello\",\"greet test\")" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do ne^STDASSERT", "do near^STDASSERT" ], "deprecated": "", "description": "", "source": { "file": "src/STDASSERT.m", "line": 60 } }, "ne": { "form": "procedure", "signature": "do ne^STDASSERT(p, f, actual, expected, desc)", "synopsis": "Assert actual'=expected (string inequality).", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref)" }, { "name": "actual", "type": "string", "doc": "observed value" }, { "name": "expected", "type": "string", "doc": "value `actual` must NOT equal" }, { "name": "desc", "type": "string", "doc": "human-readable description" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do ne^STDASSERT(.pass,.fail,oldId,newId,\"id rotated\")" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do eq^STDASSERT" ], "deprecated": "", "description": "", "source": { "file": "src/STDASSERT.m", "line": 74 } }, "true": { "form": "procedure", "signature": "do true^STDASSERT(p, f, cond, desc)", "synopsis": "Assert cond is truthy (non-zero numeric prefix).", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref)" }, { "name": "cond", "type": "string", "doc": "condition (M truthiness)" }, { "name": "desc", "type": "string", "doc": "description" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do true^STDASSERT(.pass,.fail,$data(arr),\"arr defined\")" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do false^STDASSERT" ], "deprecated": "", "description": "", "source": { "file": "src/STDASSERT.m", "line": 88 } }, "false": { "form": "procedure", "signature": "do false^STDASSERT(p, f, cond, desc)", "synopsis": "Assert cond is falsy (zero numeric prefix or empty).", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref)" }, { "name": "cond", "type": "string", "doc": "condition (M falsiness)" }, { "name": "desc", "type": "string", "doc": "description" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do false^STDASSERT(.pass,.fail,$data(missing),\"missing undef\")" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do true^STDASSERT" ], "deprecated": "", "description": "Empty string and \"abc\" are both falsy.", "source": { "file": "src/STDASSERT.m", "line": 101 } }, "near": { "form": "procedure", "signature": "do near^STDASSERT(p, f, a, b, eps, desc)", "synopsis": "Assert |a-b|<=eps (float comparison).", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref)" }, { "name": "a", "type": "num", "doc": "first value" }, { "name": "b", "type": "num", "doc": "second value" }, { "name": "eps", "type": "num", "doc": "tolerance (max allowed |a-b|)" }, { "name": "desc", "type": "string", "doc": "description" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do near^STDASSERT(.pass,.fail,sum,3.14,0.01,\"approx pi\")" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do eq^STDASSERT" ], "deprecated": "", "description": "Use for fractional comparisons where exact equality is fragile.", "source": { "file": "src/STDASSERT.m", "line": 115 } }, "raises": { "form": "procedure", "signature": "do raises^STDASSERT(p, f, code, errno, desc)", "synopsis": "Assert XECUTEing 'code' sets $ECODE containing 'errno'.", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref)" }, { "name": "code", "type": "string", "doc": "M code XECUTEd inside the assertion frame" }, { "name": "errno", "type": "string", "doc": "substring expected to appear in $ECODE" }, { "name": "desc", "type": "string", "doc": "description" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do raises^STDASSERT(.pass,.fail,\"set x=1/0\",\"Z150373058\",\"divzero\")" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do contains^STDASSERT" ], "deprecated": "", "description": "errno is matched as a substring (M's \"[\" operator). For YDB\nDIVZERO use \"Z150373058\"; for general \"M9\" use \",M9,\".", "source": { "file": "src/STDASSERT.m", "line": 133 } }, "contains": { "form": "procedure", "signature": "do contains^STDASSERT(p, f, haystack, needle, desc)", "synopsis": "Assert haystack contains needle (M's \"[\" operator).", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref)" }, { "name": "haystack", "type": "string", "doc": "string to search" }, { "name": "needle", "type": "string", "doc": "substring to find (empty always matches)" }, { "name": "desc", "type": "string", "doc": "description" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do contains^STDASSERT(.pass,.fail,output,\"OK\",\"status line\")" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do raises^STDASSERT" ], "deprecated": "", "description": "", "source": { "file": "src/STDASSERT.m", "line": 176 } }, "len": { "form": "procedure", "signature": "do len^STDASSERT(p, f, actual, n, desc)", "synopsis": "Assert actual=n (length comparison helper).", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref)" }, { "name": "actual", "type": "int", "doc": "observed length" }, { "name": "n", "type": "int", "doc": "expected length" }, { "name": "desc", "type": "string", "doc": "description" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do len^STDASSERT(.pass,.fail,$length(s),5,\"5-char string\")" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "do eq^STDASSERT" ], "deprecated": "", "description": "", "source": { "file": "src/STDASSERT.m", "line": 190 } } }, "source": { "file": "src/STDASSERT.m", "line": 1 } }, "STDB64": { "synopsis": "m-stdlib — RFC-4648 Base64 (standard + URL-safe).", "description": "Five public extrinsics:\n $$encode^STDB64(data) — standard alphabet (+ /), with padding\n $$decode^STDB64(text) — decode standard alphabet\n $$urlencode^STDB64(data) — URL-safe alphabet (- _), no padding\n $$urldecode^STDB64(text) — decode URL-safe; padding optional\n $$valid^STDB64(text) — well-formed standard base64 (with padding)\n\nAlgorithm: take 3 bytes (24 bits) at a time, split into four 6-bit\ngroups, map each via the 64-char alphabet. Pad with '=' when the\ninput length is not a multiple of 3.\n\nInput is treated as a string of bytes (one M character per byte —\nvalues 0..255 via $ASCII / $CHAR). On YDB UTF-8 mode, multi-byte\nUTF-8 characters round-trip correctly when the producer and consumer\nboth treat the string as M-characters. Arbitrary-binary support\n(always-byte semantics regardless of $ZCHSET) lands with STDCRYPTO\nin Phase 3 via $ZCHAR / $ZASCII helpers.", "errors": [], "labels": { "encode": { "form": "extrinsic", "signature": "$$encode^STDB64(data)", "synopsis": "Standard base64 (RFC-4648 §4) with padding.", "params": [ { "name": "data", "type": "string", "doc": "byte string to encode (one M char per byte)" } ], "returns": { "type": "string", "doc": "base64 with '=' padding; \"\" for empty input" }, "raises": [], "raised_in_body": [], "examples": [ "write $$encode^STDB64(\"foobar\") ; \"Zm9vYmFy\"" ], "since": "v0.0.2", "stable": "stable", "see_also": [ "$$decode^STDB64", "$$urlencode^STDB64", "$$valid^STDB64" ], "deprecated": "", "description": "Returns the empty string for empty input.", "source": { "file": "src/STDB64.m", "line": 25 } }, "decode": { "form": "extrinsic", "signature": "$$decode^STDB64(text)", "synopsis": "Inverse of encode(); accepts standard alphabet + '=' padding.", "params": [ { "name": "text", "type": "string", "doc": "base64-encoded text (standard alphabet, with padding)" } ], "returns": { "type": "string", "doc": "decoded byte string; \"\" for empty input" }, "raises": [], "raised_in_body": [], "examples": [ "write $$decode^STDB64(\"Zm9vYmFy\") ; \"foobar\"" ], "since": "v0.0.2", "stable": "stable", "see_also": [ "$$encode^STDB64", "$$valid^STDB64" ], "deprecated": "", "description": "Returns the empty string for empty input.", "source": { "file": "src/STDB64.m", "line": 35 } }, "urlencode": { "form": "extrinsic", "signature": "$$urlencode^STDB64(data)", "synopsis": "URL-safe base64 (RFC-4648 §5) without padding.", "params": [ { "name": "data", "type": "string", "doc": "byte string to encode" } ], "returns": { "type": "string", "doc": "URL-safe base64 ('-' / '_' alphabet, no padding)" }, "raises": [], "raised_in_body": [], "examples": [ "write $$urlencode^STDB64(\"f\") ; \"Zg\" (no padding)" ], "since": "v0.0.2", "stable": "stable", "see_also": [ "$$urldecode^STDB64", "$$encode^STDB64" ], "deprecated": "", "description": "Uses '-' / '_' instead of '+' / '/'; drops trailing '=' (JWT\nconvention). Use urldecode() to invert.", "source": { "file": "src/STDB64.m", "line": 45 } }, "urldecode": { "form": "extrinsic", "signature": "$$urldecode^STDB64(text)", "synopsis": "Decode URL-safe base64; padding may be present or omitted.", "params": [ { "name": "text", "type": "string", "doc": "URL-safe base64 (padding optional)" } ], "returns": { "type": "string", "doc": "decoded byte string; \"\" for empty input" }, "raises": [], "raised_in_body": [], "examples": [ "write $$urldecode^STDB64(\"Zg\") ; \"f\"" ], "since": "v0.0.2", "stable": "stable", "see_also": [ "$$urlencode^STDB64", "$$decode^STDB64" ], "deprecated": "", "description": "Trailing '=' is stripped before decoding so input from JWT\nproducers (no padding) and Python's urlsafe_b64encode (padded)\nboth work.", "source": { "file": "src/STDB64.m", "line": 56 } }, "valid": { "form": "extrinsic", "signature": "$$valid^STDB64(text)", "synopsis": "True iff text is well-formed standard base64 with padding.", "params": [ { "name": "text", "type": "string", "doc": "candidate base64 text" } ], "returns": { "type": "bool", "doc": "1 iff well-formed; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDB64(\"Zg==\") ; 1" ], "since": "v0.0.2", "stable": "stable", "see_also": [ "$$decode^STDB64", "$$urldecode^STDB64" ], "deprecated": "", "description": "Length must be a multiple of 4. Padding ('=') only at the end,\nat most two characters. Body characters must all be in the\nstandard alphabet. Empty string is valid.", "source": { "file": "src/STDB64.m", "line": 68 } } }, "source": { "file": "src/STDB64.m", "line": 1 } }, "STDCACHE": { "synopsis": "m-stdlib — LRU + TTL cache over a caller-owned local array.", "description": "Public extrinsics:\n new^STDCACHE(.cache, capacity?, ttl?) — initialise; cap=0 unlimited, ttl=0 no expiry\n put^STDCACHE(.cache, key, value) — insert/update; touches recency\n $$get^STDCACHE(.cache, key) — fetch; \"\" if absent or expired; touches recency\n $$has^STDCACHE(.cache, key) — predicate; expired keys are lazily reaped\n remove^STDCACHE(.cache, key) — delete one entry; idempotent\n clear^STDCACHE(.cache) — drop all entries; capacity/ttl preserved\n $$size^STDCACHE(.cache) — current entry count\n $$capacity^STDCACHE(.cache) — declared capacity (0 = unlimited)\n\nTree shape (caller-owned; pass by reference):\n cache(\"cap\") — capacity (0 = unlimited)\n cache(\"ttl\") — TTL seconds (0 = no expiry)\n cache(\"size\") — current entry count\n cache(\"seq\") — monotonic counter for recency tracking\n cache(\"v\",key) — stored value\n cache(\"ts\",key) — recency: this key's seq number\n cache(\"o\",seq) — reverse map: seq → key (for LRU eviction lookup)\n cache(\"ex\",key) — expiry seconds-since-1840-epoch (only when ttl>0)\n\nLRU eviction: the smallest seq in cache(\"o\",...) is the least-recently-\ntouched key. On capacity overflow, $ORDER picks it off in O(1) per evict.\nRecency touch: on get/put, kill the old (seq → key) entry, bump seq, write\nthe new (seq → key) entry, update cache(\"ts\",key).\n\nTTL eviction: lazy. has() and get() check cache(\"ex\",key) before returning;\nif expired, remove() is invoked inline. size() is decremented at that point.\nA get() of an expired key returns \"\" exactly like an absent key.\n\nTime source: M's $H = \"DDDDD,SSSSS\" (ANSI standard). nowSec() collapses\nthis to seconds since 1840-12-31. No `$Z*` extensions; runs unchanged on\nYDB and IRIS.", "errors": [], "labels": { "new": { "form": "procedure", "signature": "do new^STDCACHE(cache, capacity, ttl)", "synopsis": "Initialise cache with optional capacity / TTL.", "params": [ { "name": "cache", "type": "array", "doc": "by-ref local; killed then populated" }, { "name": "capacity", "type": "int", "doc": "max entries; 0 = unlimited (default 0)" }, { "name": "ttl", "type": "int", "doc": "TTL in seconds; 0 = no expiry (default 0)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do new^STDCACHE(.cfg,128,300) ; 128 entries, 5-minute TTL" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do put^STDCACHE", "do clear^STDCACHE" ], "deprecated": "", "description": "Idempotent — calling new() on an existing cache wipes it.", "source": { "file": "src/STDCACHE.m", "line": 40 } }, "put": { "form": "procedure", "signature": "do put^STDCACHE(cache, key, value)", "synopsis": "Insert / update. Promotes the key to most-recent. May evict.", "params": [ { "name": "cache", "type": "array", "doc": "by-ref local from new^STDCACHE" }, { "name": "key", "type": "string", "doc": "cache key" }, { "name": "value", "type": "string", "doc": "value to store" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do put^STDCACHE(.cfg,\"hostname\",\"example.org\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$get^STDCACHE", "do remove^STDCACHE" ], "deprecated": "", "description": "", "source": { "file": "src/STDCACHE.m", "line": 56 } }, "get": { "form": "extrinsic", "signature": "$$get^STDCACHE(cache, key)", "synopsis": "Return the cached value, or \"\" if absent / expired. Touches recency.", "params": [ { "name": "cache", "type": "array", "doc": "by-ref local from new^STDCACHE" }, { "name": "key", "type": "string", "doc": "cache key" } ], "returns": { "type": "string", "doc": "the stored value; \"\" if absent or expired" }, "raises": [], "raised_in_body": [], "examples": [ "write $$get^STDCACHE(.cfg,\"hostname\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$has^STDCACHE", "do put^STDCACHE" ], "deprecated": "", "description": "Expired entries are reaped inline before the lookup returns.", "source": { "file": "src/STDCACHE.m", "line": 84 } }, "has": { "form": "extrinsic", "signature": "$$has^STDCACHE(cache, key)", "synopsis": "Return 1 iff key is present and not expired; reap if expired.", "params": [ { "name": "cache", "type": "array", "doc": "by-ref local from new^STDCACHE" }, { "name": "key", "type": "string", "doc": "cache key" } ], "returns": { "type": "bool", "doc": "1 iff present and not expired; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "if $$has^STDCACHE(.cfg,\"hostname\") ..." ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$get^STDCACHE" ], "deprecated": "", "description": "", "source": { "file": "src/STDCACHE.m", "line": 104 } }, "remove": { "form": "procedure", "signature": "do remove^STDCACHE(cache, key)", "synopsis": "Delete one entry. Idempotent — no-op if key is absent.", "params": [ { "name": "cache", "type": "array", "doc": "by-ref local from new^STDCACHE" }, { "name": "key", "type": "string", "doc": "cache key" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do remove^STDCACHE(.cfg,\"stale-token\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do clear^STDCACHE" ], "deprecated": "", "description": "", "source": { "file": "src/STDCACHE.m", "line": 116 } }, "clear": { "form": "procedure", "signature": "do clear^STDCACHE(cache)", "synopsis": "Drop every entry; preserve capacity / TTL settings.", "params": [ { "name": "cache", "type": "array", "doc": "by-ref local from new^STDCACHE" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do clear^STDCACHE(.cfg)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do new^STDCACHE", "do remove^STDCACHE" ], "deprecated": "", "description": "", "source": { "file": "src/STDCACHE.m", "line": 133 } }, "size": { "form": "extrinsic", "signature": "$$size^STDCACHE(cache)", "synopsis": "Return the current entry count.", "params": [ { "name": "cache", "type": "array", "doc": "by-ref local from new^STDCACHE" } ], "returns": { "type": "int", "doc": "current entry count" }, "raises": [], "raised_in_body": [], "examples": [ "write $$size^STDCACHE(.cfg)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$capacity^STDCACHE" ], "deprecated": "", "description": "Reflects entries actually in the cache; expired entries that have\nnot yet been touched are still counted until lazily reaped.", "source": { "file": "src/STDCACHE.m", "line": 144 } }, "capacity": { "form": "extrinsic", "signature": "$$capacity^STDCACHE(cache)", "synopsis": "Return the declared capacity (0 = unlimited).", "params": [ { "name": "cache", "type": "array", "doc": "by-ref local from new^STDCACHE" } ], "returns": { "type": "int", "doc": "declared capacity (0 = unlimited)" }, "raises": [], "raised_in_body": [], "examples": [ "write $$capacity^STDCACHE(.cfg)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$size^STDCACHE" ], "deprecated": "", "description": "", "source": { "file": "src/STDCACHE.m", "line": 155 } } }, "source": { "file": "src/STDCACHE.m", "line": 1 } }, "STDCOLL": { "synopsis": "m-stdlib — collections (Set, Map, Stack, Queue, Deque, Heap, OrderedDict).", "description": "All collections are by-reference local arrays owned by the caller.\nThe caller's variable is the collection; killing it disposes of\neverything. No process-globals are touched.\n\nReserved subscripts inside each collection:\n (\"v\",...) values / members / payload\n (\"n\") cardinality counter\n (\"h\") head index (queue, deque)\n (\"t\") tail index (queue, deque)\n (\"k\",i) heap-array of keys (heap)\n (\"seq\",key) insertion sequence number (odict)\n (\"ord\",seq) reverse map sequence -> key (odict)\n (\"nseq\") monotonic sequence allocator (odict)\n\nPublic API — each entry point is a procedure call (`do …`) or an\nextrinsic ($$ …) per the prefix below.\n\nSet (unordered, no duplicates; subscript-as-value)\n do setAdd^STDCOLL(.s,value)\n $$setHas^STDCOLL(.s,value) -> 0|1\n do setRemove^STDCOLL(.s,value)\n $$setSize^STDCOLL(.s) -> count\n do setClear^STDCOLL(.s)\n $$setNext^STDCOLL(.s,prev) -> next member, \"\" at end\n\nMap (string-keyed dictionary)\n do mapPut^STDCOLL(.m,key,value)\n $$mapGet^STDCOLL(.m,key,default) -> value or default\n $$mapHas^STDCOLL(.m,key) -> 0|1\n do mapRemove^STDCOLL(.m,key)\n $$mapSize^STDCOLL(.m)\n do mapClear^STDCOLL(.m)\n $$mapNext^STDCOLL(.m,prev) -> next key in $order\n\nStack (LIFO)\n do stackPush^STDCOLL(.s,value)\n $$stackPop^STDCOLL(.s) -> top; \"\" if empty\n $$stackPeek^STDCOLL(.s) -> top without removal\n $$stackSize^STDCOLL(.s)\n do stackClear^STDCOLL(.s)\n\nQueue (FIFO; head/tail indices)\n do queuePush^STDCOLL(.q,value) enqueue at back\n $$queuePop^STDCOLL(.q) dequeue front; \"\" if empty\n $$queuePeek^STDCOLL(.q) front without removal\n $$queueSize^STDCOLL(.q)\n do queueClear^STDCOLL(.q)\n\nDeque (double-ended)\n do dequePushFront^STDCOLL(.d,value)\n do dequePushBack^STDCOLL(.d,value)\n $$dequePopFront^STDCOLL(.d)\n $$dequePopBack^STDCOLL(.d)\n $$dequePeekFront^STDCOLL(.d)\n $$dequePeekBack^STDCOLL(.d)\n $$dequeSize^STDCOLL(.d)\n do dequeClear^STDCOLL(.d)\n\nHeap (min-heap; numeric key, optional payload)\n do heapPush^STDCOLL(.h,key[,value]) value defaults to key\n $$heapPop^STDCOLL(.h) value at min key; \"\"\n $$heapPopKey^STDCOLL(.h) min key; \"\"\n $$heapPeek^STDCOLL(.h) value at min key\n $$heapPeekKey^STDCOLL(.h) min key\n $$heapSize^STDCOLL(.h)\n do heapClear^STDCOLL(.h)\n\nOrderedDict (insertion-ordered map; update keeps original position)\n do odictPut^STDCOLL(.o,key,value)\n $$odictGet^STDCOLL(.o,key,default)\n $$odictHas^STDCOLL(.o,key)\n do odictRemove^STDCOLL(.o,key)\n $$odictSize^STDCOLL(.o)\n do odictClear^STDCOLL(.o)\n $$odictFirst^STDCOLL(.o) first key in insertion order\n $$odictLast^STDCOLL(.o) last key in insertion order\n $$odictNext^STDCOLL(.o,prev) forward step\n $$odictPrev^STDCOLL(.o,next) reverse step\n\nEdge cases:\n - Empty-string set members and map / odict keys are silently\n ignored on add / put: M's $order cannot enumerate the empty\n subscript, and the API would not be able to round-trip them.\n - Pop / peek on empty silently returns \"\". Callers gate on\n `*Size` when they need to distinguish empty from a stored \"\".\n - Heap keys must be numeric (compared with M's `<`).\n - All collections may be reset by `kill `; every entry\n point reads counters via `$get(...,0)` so a fresh / killed\n variable is indistinguishable from an explicitly cleared one.", "errors": [], "labels": { "setAdd": { "form": "procedure", "signature": "do setAdd^STDCOLL(s, value)", "synopsis": "Add value to set s (idempotent).", "params": [ { "name": "s", "type": "array", "doc": "by-ref local; the set" }, { "name": "value", "type": "string", "doc": "member to add (empty string is silently ignored)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do setAdd^STDCOLL(.s,\"alpha\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$setHas^STDCOLL", "do setRemove^STDCOLL" ], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 97 } }, "setHas": { "form": "extrinsic", "signature": "$$setHas^STDCOLL(s, value)", "synopsis": "Return 1 iff value is a member of set s.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local; the set" }, { "name": "value", "type": "string", "doc": "candidate member" } ], "returns": { "type": "bool", "doc": "1 iff value is a member; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$setHas^STDCOLL(.s,\"alpha\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "do setAdd^STDCOLL" ], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 110 } }, "setRemove": { "form": "procedure", "signature": "do setRemove^STDCOLL(s, value)", "synopsis": "Remove value from set s; absent values are no-ops.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local; the set" }, { "name": "value", "type": "string", "doc": "member to remove" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do setRemove^STDCOLL(.s,\"alpha\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 121 } }, "setSize": { "form": "extrinsic", "signature": "$$setSize^STDCOLL(s)", "synopsis": "Return cardinality.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "int", "doc": "cardinality" }, "raises": [], "raised_in_body": [], "examples": [ "write $$setSize^STDCOLL(.s)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 132 } }, "setClear": { "form": "procedure", "signature": "do setClear^STDCOLL(s)", "synopsis": "Drop every member.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do setClear^STDCOLL(.s)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 140 } }, "setNext": { "form": "extrinsic", "signature": "$$setNext^STDCOLL(s, prev)", "synopsis": "Return the next member after prev in $order; \"\" at end.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local" }, { "name": "prev", "type": "string", "doc": "previous member (\"\" for first call)" } ], "returns": { "type": "string", "doc": "next member; \"\" at end" }, "raises": [], "raised_in_body": [], "examples": [ "set k=$$setNext^STDCOLL(.s,\"\") for quit:k=\"\" ..." ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 148 } }, "mapPut": { "form": "procedure", "signature": "do mapPut^STDCOLL(m, key, value)", "synopsis": "Store value at key (overwrites).", "params": [ { "name": "m", "type": "array", "doc": "by-ref local; the map" }, { "name": "key", "type": "string", "doc": "map key (empty silently ignored)" }, { "name": "value", "type": "string", "doc": "value to store" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do mapPut^STDCOLL(.m,\"name\",\"Alice\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 159 } }, "mapGet": { "form": "extrinsic", "signature": "$$mapGet^STDCOLL(m, key, default)", "synopsis": "Return value at key; default if absent.", "params": [ { "name": "m", "type": "array", "doc": "by-ref local" }, { "name": "key", "type": "string", "doc": "map key" }, { "name": "default", "type": "string", "doc": "fallback if key absent" } ], "returns": { "type": "string", "doc": "stored value or default" }, "raises": [], "raised_in_body": [], "examples": [ "set v=$$mapGet^STDCOLL(.m,\"name\",\"\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 171 } }, "mapHas": { "form": "extrinsic", "signature": "$$mapHas^STDCOLL(m, key)", "synopsis": "Return 1 iff key is set.", "params": [ { "name": "m", "type": "array", "doc": "by-ref local" }, { "name": "key", "type": "string", "doc": "candidate key" } ], "returns": { "type": "bool", "doc": "1 iff present; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$mapHas^STDCOLL(.m,\"name\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 181 } }, "mapRemove": { "form": "procedure", "signature": "do mapRemove^STDCOLL(m, key)", "synopsis": "Drop key (no-op when absent).", "params": [ { "name": "m", "type": "array", "doc": "by-ref local" }, { "name": "key", "type": "string", "doc": "key to remove" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do mapRemove^STDCOLL(.m,\"name\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 191 } }, "mapSize": { "form": "extrinsic", "signature": "$$mapSize^STDCOLL(m)", "synopsis": "Return number of keys.", "params": [ { "name": "m", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "int", "doc": "number of keys" }, "raises": [], "raised_in_body": [], "examples": [ "write $$mapSize^STDCOLL(.m)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 202 } }, "mapClear": { "form": "procedure", "signature": "do mapClear^STDCOLL(m)", "synopsis": "Drop every entry.", "params": [ { "name": "m", "type": "array", "doc": "by-ref local" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do mapClear^STDCOLL(.m)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 210 } }, "mapNext": { "form": "extrinsic", "signature": "$$mapNext^STDCOLL(m, prev)", "synopsis": "Return next key after prev in $order; \"\" at end.", "params": [ { "name": "m", "type": "array", "doc": "by-ref local" }, { "name": "prev", "type": "string", "doc": "previous key (\"\" for first call)" } ], "returns": { "type": "string", "doc": "next key; \"\" at end" }, "raises": [], "raised_in_body": [], "examples": [ "set k=$$mapNext^STDCOLL(.m,\"\") for quit:k=\"\" ..." ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 218 } }, "stackPush": { "form": "procedure", "signature": "do stackPush^STDCOLL(s, value)", "synopsis": "Push value on top of the stack.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local; the stack" }, { "name": "value", "type": "string", "doc": "value to push" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do stackPush^STDCOLL(.s,\"alpha\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 229 } }, "stackPop": { "form": "extrinsic", "signature": "$$stackPop^STDCOLL(s)", "synopsis": "Remove and return the top; \"\" when empty.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "top value; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set top=$$stackPop^STDCOLL(.s)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 241 } }, "stackPeek": { "form": "extrinsic", "signature": "$$stackPeek^STDCOLL(s)", "synopsis": "Return the top without removal; \"\" when empty.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "top value; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set top=$$stackPeek^STDCOLL(.s)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 256 } }, "stackSize": { "form": "extrinsic", "signature": "$$stackSize^STDCOLL(s)", "synopsis": "Return depth.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "int", "doc": "stack depth" }, "raises": [], "raised_in_body": [], "examples": [ "write $$stackSize^STDCOLL(.s)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 267 } }, "stackClear": { "form": "procedure", "signature": "do stackClear^STDCOLL(s)", "synopsis": "Drop every entry.", "params": [ { "name": "s", "type": "array", "doc": "by-ref local" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do stackClear^STDCOLL(.s)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 275 } }, "queuePush": { "form": "procedure", "signature": "do queuePush^STDCOLL(q, value)", "synopsis": "Enqueue at back.", "params": [ { "name": "q", "type": "array", "doc": "by-ref local; the queue" }, { "name": "value", "type": "string", "doc": "value to enqueue" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do queuePush^STDCOLL(.q,\"alpha\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 285 } }, "queuePop": { "form": "extrinsic", "signature": "$$queuePop^STDCOLL(q)", "synopsis": "Dequeue at front; \"\" when empty.", "params": [ { "name": "q", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "front value; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set front=$$queuePop^STDCOLL(.q)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 299 } }, "queuePeek": { "form": "extrinsic", "signature": "$$queuePeek^STDCOLL(q)", "synopsis": "Return front without removal; \"\" when empty.", "params": [ { "name": "q", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "front value; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set front=$$queuePeek^STDCOLL(.q)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 314 } }, "queueSize": { "form": "extrinsic", "signature": "$$queueSize^STDCOLL(q)", "synopsis": "Return queue length.", "params": [ { "name": "q", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "int", "doc": "queue length" }, "raises": [], "raised_in_body": [], "examples": [ "write $$queueSize^STDCOLL(.q)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 325 } }, "queueClear": { "form": "procedure", "signature": "do queueClear^STDCOLL(q)", "synopsis": "Drop every entry.", "params": [ { "name": "q", "type": "array", "doc": "by-ref local" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do queueClear^STDCOLL(.q)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 336 } }, "dequePushFront": { "form": "procedure", "signature": "do dequePushFront^STDCOLL(d, value)", "synopsis": "Push value at the front.", "params": [ { "name": "d", "type": "array", "doc": "by-ref local; the deque" }, { "name": "value", "type": "string", "doc": "value to push" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do dequePushFront^STDCOLL(.d,\"alpha\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 346 } }, "dequePushBack": { "form": "procedure", "signature": "do dequePushBack^STDCOLL(d, value)", "synopsis": "Push value at the back.", "params": [ { "name": "d", "type": "array", "doc": "by-ref local" }, { "name": "value", "type": "string", "doc": "value to push" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do dequePushBack^STDCOLL(.d,\"omega\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 359 } }, "dequePopFront": { "form": "extrinsic", "signature": "$$dequePopFront^STDCOLL(d)", "synopsis": "Pop and return the front; \"\" when empty.", "params": [ { "name": "d", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "front value; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set v=$$dequePopFront^STDCOLL(.d)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 372 } }, "dequePopBack": { "form": "extrinsic", "signature": "$$dequePopBack^STDCOLL(d)", "synopsis": "Pop and return the back; \"\" when empty.", "params": [ { "name": "d", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "back value; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set v=$$dequePopBack^STDCOLL(.d)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 387 } }, "dequePeekFront": { "form": "extrinsic", "signature": "$$dequePeekFront^STDCOLL(d)", "synopsis": "Return front without removal; \"\" when empty.", "params": [ { "name": "d", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "front value; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set v=$$dequePeekFront^STDCOLL(.d)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 402 } }, "dequePeekBack": { "form": "extrinsic", "signature": "$$dequePeekBack^STDCOLL(d)", "synopsis": "Return back without removal; \"\" when empty.", "params": [ { "name": "d", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "back value; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set v=$$dequePeekBack^STDCOLL(.d)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 413 } }, "dequeSize": { "form": "extrinsic", "signature": "$$dequeSize^STDCOLL(d)", "synopsis": "Return deque length.", "params": [ { "name": "d", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "int", "doc": "deque length" }, "raises": [], "raised_in_body": [], "examples": [ "write $$dequeSize^STDCOLL(.d)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 424 } }, "dequeClear": { "form": "procedure", "signature": "do dequeClear^STDCOLL(d)", "synopsis": "Drop every entry.", "params": [ { "name": "d", "type": "array", "doc": "by-ref local" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do dequeClear^STDCOLL(.d)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 435 } }, "heapPush": { "form": "procedure", "signature": "do heapPush^STDCOLL(h, key, value)", "synopsis": "Push (key, value) onto the heap.", "params": [ { "name": "h", "type": "array", "doc": "by-ref local; the heap" }, { "name": "key", "type": "num", "doc": "numeric priority (smaller = higher priority in min-heap)" }, { "name": "value", "type": "string", "doc": "payload; defaults to key if omitted" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do heapPush^STDCOLL(.h,3,\"task A\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 445 } }, "heapPop": { "form": "extrinsic", "signature": "$$heapPop^STDCOLL(h)", "synopsis": "Pop value at the min key; \"\" when empty.", "params": [ { "name": "h", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "payload at the min key; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set v=$$heapPop^STDCOLL(.h)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 461 } }, "heapPopKey": { "form": "extrinsic", "signature": "$$heapPopKey^STDCOLL(h)", "synopsis": "Pop and return the min key; \"\" when empty.", "params": [ { "name": "h", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "num", "doc": "min key; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set k=$$heapPopKey^STDCOLL(.h)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 474 } }, "heapPeek": { "form": "extrinsic", "signature": "$$heapPeek^STDCOLL(h)", "synopsis": "Return value at min key without removal; \"\" when empty.", "params": [ { "name": "h", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "payload at min key; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set v=$$heapPeek^STDCOLL(.h)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 487 } }, "heapPeekKey": { "form": "extrinsic", "signature": "$$heapPeekKey^STDCOLL(h)", "synopsis": "Return min key without removal; \"\" when empty.", "params": [ { "name": "h", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "num", "doc": "min key; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set k=$$heapPeekKey^STDCOLL(.h)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 496 } }, "heapSize": { "form": "extrinsic", "signature": "$$heapSize^STDCOLL(h)", "synopsis": "Return heap size.", "params": [ { "name": "h", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "int", "doc": "heap size" }, "raises": [], "raised_in_body": [], "examples": [ "write $$heapSize^STDCOLL(.h)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 505 } }, "heapClear": { "form": "procedure", "signature": "do heapClear^STDCOLL(h)", "synopsis": "Drop every entry.", "params": [ { "name": "h", "type": "array", "doc": "by-ref local" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do heapClear^STDCOLL(.h)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 513 } }, "odictPut": { "form": "procedure", "signature": "do odictPut^STDCOLL(o, key, value)", "synopsis": "Store value at key; create-or-update preserving position.", "params": [ { "name": "o", "type": "array", "doc": "by-ref local; the ordered dict" }, { "name": "key", "type": "string", "doc": "dict key (empty silently ignored)" }, { "name": "value", "type": "string", "doc": "value to store" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do odictPut^STDCOLL(.o,\"name\",\"Alice\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "Sequence numbers are monotonic — an update reuses the\nexisting position; a new key is appended to the back.", "source": { "file": "src/STDCOLL.m", "line": 570 } }, "odictGet": { "form": "extrinsic", "signature": "$$odictGet^STDCOLL(o, key, default)", "synopsis": "Return value at key; default if absent.", "params": [ { "name": "o", "type": "array", "doc": "by-ref local" }, { "name": "key", "type": "string", "doc": "dict key" }, { "name": "default", "type": "string", "doc": "fallback if key absent" } ], "returns": { "type": "string", "doc": "stored value or default" }, "raises": [], "raised_in_body": [], "examples": [ "set v=$$odictGet^STDCOLL(.o,\"name\",\"\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 590 } }, "odictHas": { "form": "extrinsic", "signature": "$$odictHas^STDCOLL(o, key)", "synopsis": "Return 1 iff key is set.", "params": [ { "name": "o", "type": "array", "doc": "by-ref local" }, { "name": "key", "type": "string", "doc": "candidate key" } ], "returns": { "type": "bool", "doc": "1 iff present" }, "raises": [], "raised_in_body": [], "examples": [ "write $$odictHas^STDCOLL(.o,\"name\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 600 } }, "odictRemove": { "form": "procedure", "signature": "do odictRemove^STDCOLL(o, key)", "synopsis": "Drop key (no-op when absent).", "params": [ { "name": "o", "type": "array", "doc": "by-ref local" }, { "name": "key", "type": "string", "doc": "key to remove" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do odictRemove^STDCOLL(.o,\"name\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 610 } }, "odictSize": { "form": "extrinsic", "signature": "$$odictSize^STDCOLL(o)", "synopsis": "Return number of keys.", "params": [ { "name": "o", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "int", "doc": "number of keys" }, "raises": [], "raised_in_body": [], "examples": [ "write $$odictSize^STDCOLL(.o)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 623 } }, "odictClear": { "form": "procedure", "signature": "do odictClear^STDCOLL(o)", "synopsis": "Drop every entry.", "params": [ { "name": "o", "type": "array", "doc": "by-ref local" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do odictClear^STDCOLL(.o)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 631 } }, "odictFirst": { "form": "extrinsic", "signature": "$$odictFirst^STDCOLL(o)", "synopsis": "Return first key in insertion order; \"\" when empty.", "params": [ { "name": "o", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "first key; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set k=$$odictFirst^STDCOLL(.o)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 639 } }, "odictLast": { "form": "extrinsic", "signature": "$$odictLast^STDCOLL(o)", "synopsis": "Return last key in insertion order; \"\" when empty.", "params": [ { "name": "o", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "string", "doc": "last key; \"\" when empty" }, "raises": [], "raised_in_body": [], "examples": [ "set k=$$odictLast^STDCOLL(.o)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 650 } }, "odictNext": { "form": "extrinsic", "signature": "$$odictNext^STDCOLL(o, prev)", "synopsis": "Return next key (insertion order) after prev; \"\" at end.", "params": [ { "name": "o", "type": "array", "doc": "by-ref local" }, { "name": "prev", "type": "string", "doc": "previous key (\"\" for first call)" } ], "returns": { "type": "string", "doc": "next key; \"\" at end" }, "raises": [], "raised_in_body": [], "examples": [ "set k=$$odictNext^STDCOLL(.o,k)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 661 } }, "odictPrev": { "form": "extrinsic", "signature": "$$odictPrev^STDCOLL(o, next)", "synopsis": "Return previous key (insertion order) before next; \"\" at start.", "params": [ { "name": "o", "type": "array", "doc": "by-ref local" }, { "name": "next", "type": "string", "doc": "next key (\"\" for last call)" } ], "returns": { "type": "string", "doc": "previous key; \"\" at start" }, "raises": [], "raised_in_body": [], "examples": [ "set k=$$odictPrev^STDCOLL(.o,k)" ], "since": "v0.2.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "", "source": { "file": "src/STDCOLL.m", "line": 676 } } }, "source": { "file": "src/STDCOLL.m", "line": 1 } }, "STDCOMPRESS": { "synopsis": "m-stdlib — gzip / deflate / zstd via $&stdcompress callouts.", "description": "m-lint: disable-file=M-MOD-024\nm-lint: disable-file=M-MOD-036\nm-lint: disable-file=M-MOD-020\nM-MOD-024 false positives: rc / out are initialised before every\nXECUTE'd $& call but the analyser cannot follow flow through the\nXECUTE indirection.\nM-MOD-036 (XECUTE injection) is intentional: the XECUTE wrapper is\nthe only way to invoke $&pkg.fn from M code that tree-sitter-m can\nstill parse — same trick as STDCRYPTO. The XECUTE source is built\nfrom a literal template plus a `sym` symbol that the M-side public\nsurface controls; no user data flows into the XECUTE string.\nM-MOD-020 (by-ref formal not written) false positives: dispatch\nhelpers write to `out` via the XECUTE'd $& call.\n\nPublic extrinsics (output via .out byref; return 1=ok / 0=fail):\n $$gzip^STDCOMPRESS(data,.out[,level]) — RFC 1952 gzip\n $$gunzip^STDCOMPRESS(data,.out) — RFC 1952 gunzip\n $$deflate^STDCOMPRESS(data,.out[,level]) — RFC 1951 deflate\n $$inflate^STDCOMPRESS(data,.out) — RFC 1951 inflate\n $$zstdCompress^STDCOMPRESS(data,.out[,level]) — RFC 8478 zstd\n $$zstdDecompress^STDCOMPRESS(data,.out) — RFC 8478 zstd\n $$available^STDCOMPRESS() — \"\"=ok, else missing\n\nErrors set $ECODE: ,U-STDCOMPRESS-CALLOUT-MISSING, (.so unloaded);\n,U-STDCOMPRESS-BAD-LEVEL, (level out of range); ,U-STDCOMPRESS-LIBZ-FAIL,\n(libz returned non-Z_STREAM_END); ,U-STDCOMPRESS-LIBZSTD-FAIL, (zstd\nreturned an error frame).\n\nLevels: gzip / deflate accept 1..9 (default 6); zstd accepts 1..22\n(default 3). Level 0 (no compression) is rejected to avoid surprise\npass-through.\n\nOutput cap: 1 MiB per call (YDB's max M-string length on this\nbuild; declared in tools/std_compress.xc). Streaming for larger\npayloads is queued.\n\nBackend: $&stdcompress. → libz (gzip / deflate) + libzstd\n(zstd). Source at src/callouts/stdcompress.c; descriptor at\ntools/std_compress.xc.\n\nDeployment runbook (full detail in docs/modules/stdcompress.md):\n 1. tools/build-callouts.sh ; produce so//stdcompress.so\n 2. export STDLIB_LIB=\n 3. export ydb_xc_stdcompress=/tools/std_compress.xc\n 4. ensure libz.so.1 + libzstd.so.1 are on the loader path", "errors": [ "U-STDCOMPRESS-BAD-LEVEL", "U-STDCOMPRESS-CALLOUT-MISSING", "U-STDCOMPRESS-LIBZ-FAIL", "U-STDCOMPRESS-LIBZSTD-FAIL" ], "labels": { "gzip": { "form": "procedure", "signature": "do gzip^STDCOMPRESS(data, out, level)", "synopsis": "RFC 1952 gzip-format compress.", "params": [ { "name": "data", "type": "byte-string", "doc": "one M character per byte" }, { "name": "out", "type": "byte-string", "doc": "by-ref local; populated with compressed bytes" }, { "name": "level", "type": "int", "doc": "compression level 1..9 (default 6)" } ], "returns": { "type": "bool", "doc": "1 on success; 0 with $ECODE on failure" }, "raises": [ { "code": "U-STDCOMPRESS-BAD-LEVEL", "doc": "level outside 1..9" }, { "code": "U-STDCOMPRESS-CALLOUT-MISSING", "doc": ".so unloaded" }, { "code": "U-STDCOMPRESS-LIBZ-FAIL", "doc": "libz reported failure" } ], "raised_in_body": [ "U-STDCOMPRESS-BAD-LEVEL" ], "examples": [ "do gzip^STDCOMPRESS(\"hello\",.buf)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$gunzip^STDCOMPRESS", "$$deflate^STDCOMPRESS" ], "deprecated": "", "description": "", "source": { "file": "src/STDCOMPRESS.m", "line": 52 } }, "gunzip": { "form": "procedure", "signature": "do gunzip^STDCOMPRESS(data, out)", "synopsis": "RFC 1952 gunzip.", "params": [ { "name": "data", "type": "byte-string", "doc": "gzip-format compressed bytes" }, { "name": "out", "type": "byte-string", "doc": "by-ref local; populated with raw bytes" } ], "returns": { "type": "bool", "doc": "1 on success; 0 with $ECODE on failure" }, "raises": [ { "code": "U-STDCOMPRESS-CALLOUT-MISSING", "doc": ".so unloaded" }, { "code": "U-STDCOMPRESS-LIBZ-FAIL", "doc": "libz reported failure" } ], "raised_in_body": [], "examples": [ "do gunzip^STDCOMPRESS(buf,.raw)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$gzip^STDCOMPRESS" ], "deprecated": "", "description": "", "source": { "file": "src/STDCOMPRESS.m", "line": 71 } }, "deflate": { "form": "procedure", "signature": "do deflate^STDCOMPRESS(data, out, level)", "synopsis": "RFC 1951 raw deflate (no header / trailer).", "params": [ { "name": "data", "type": "", "doc": "byte-string" }, { "name": "out", "type": "byte-string", "doc": "by-ref local; populated with deflated bytes" }, { "name": "level", "type": "int", "doc": "compression level 1..9 (default 6)" } ], "returns": { "type": "bool", "doc": "1 on success; 0 with $ECODE on failure" }, "raises": [ { "code": "U-STDCOMPRESS-BAD-LEVEL", "doc": "level outside 1..9" }, { "code": "U-STDCOMPRESS-CALLOUT-MISSING", "doc": ".so unloaded" }, { "code": "U-STDCOMPRESS-LIBZ-FAIL", "doc": "libz reported failure" } ], "raised_in_body": [ "U-STDCOMPRESS-BAD-LEVEL" ], "examples": [ "do deflate^STDCOMPRESS(\"hello\",.buf)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$inflate^STDCOMPRESS", "$$gzip^STDCOMPRESS" ], "deprecated": "", "description": "", "source": { "file": "src/STDCOMPRESS.m", "line": 86 } }, "inflate": { "form": "procedure", "signature": "do inflate^STDCOMPRESS(data, out)", "synopsis": "RFC 1951 raw inflate.", "params": [ { "name": "data", "type": "byte-string", "doc": "raw deflated bytes" }, { "name": "out", "type": "byte-string", "doc": "by-ref local; populated with raw bytes" } ], "returns": { "type": "bool", "doc": "1 on success; 0 with $ECODE on failure" }, "raises": [ { "code": "U-STDCOMPRESS-CALLOUT-MISSING", "doc": ".so unloaded" }, { "code": "U-STDCOMPRESS-LIBZ-FAIL", "doc": "libz reported failure" } ], "raised_in_body": [], "examples": [ "do inflate^STDCOMPRESS(buf,.raw)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$deflate^STDCOMPRESS" ], "deprecated": "", "description": "", "source": { "file": "src/STDCOMPRESS.m", "line": 105 } }, "zstdCompress": { "form": "procedure", "signature": "do zstdCompress^STDCOMPRESS(data, out, level)", "synopsis": "Zstandard (RFC 8478) compress.", "params": [ { "name": "data", "type": "", "doc": "byte-string" }, { "name": "out", "type": "byte-string", "doc": "by-ref local; populated with compressed bytes" }, { "name": "level", "type": "int", "doc": "compression level 1..22 (default 3)" } ], "returns": { "type": "bool", "doc": "1 on success; 0 with $ECODE on failure" }, "raises": [ { "code": "U-STDCOMPRESS-BAD-LEVEL", "doc": "level outside 1..22" }, { "code": "U-STDCOMPRESS-CALLOUT-MISSING", "doc": ".so unloaded" }, { "code": "U-STDCOMPRESS-LIBZSTD-FAIL", "doc": "libzstd reported failure" } ], "raised_in_body": [ "U-STDCOMPRESS-BAD-LEVEL" ], "examples": [ "do zstdCompress^STDCOMPRESS(\"hello\",.buf)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$zstdDecompress^STDCOMPRESS" ], "deprecated": "", "description": "", "source": { "file": "src/STDCOMPRESS.m", "line": 120 } }, "zstdDecompress": { "form": "procedure", "signature": "do zstdDecompress^STDCOMPRESS(data, out)", "synopsis": "Zstandard decompress.", "params": [ { "name": "data", "type": "byte-string", "doc": "zstd-compressed bytes" }, { "name": "out", "type": "byte-string", "doc": "by-ref local; populated with raw bytes" } ], "returns": { "type": "bool", "doc": "1 on success; 0 with $ECODE on failure" }, "raises": [ { "code": "U-STDCOMPRESS-CALLOUT-MISSING", "doc": ".so unloaded" }, { "code": "U-STDCOMPRESS-LIBZSTD-FAIL", "doc": "libzstd reported failure" } ], "raised_in_body": [], "examples": [ "do zstdDecompress^STDCOMPRESS(buf,.raw)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$zstdCompress^STDCOMPRESS" ], "deprecated": "", "description": "", "source": { "file": "src/STDCOMPRESS.m", "line": 139 } }, "available": { "form": "extrinsic", "signature": "$$available^STDCOMPRESS()", "synopsis": "\"\" iff both libz and libzstd loaded; else missing list.", "params": [], "returns": { "type": "string", "doc": "\"\" if both backends OK; comma-separated names of missing libs otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "if $$available^STDCOMPRESS()'=\"\" w \"missing libs\",!" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$gzip^STDCOMPRESS", "$$zstdCompress^STDCOMPRESS" ], "deprecated": "", "description": "Probes by attempting an empty round-trip on each backend.\nNever raises — clears $ECODE on the way out.", "source": { "file": "src/STDCOMPRESS.m", "line": 154 } } }, "source": { "file": "src/STDCOMPRESS.m", "line": 1 } }, "STDCRYPTO": { "synopsis": "m-stdlib — Cryptographic digests via $&stdcrypto → libcrypto.", "description": "m-lint: disable-file=M-MOD-024\nm-lint: disable-file=M-MOD-036\nm-lint: disable-file=M-MOD-020\nM-MOD-024 false positives: rc is initialised by every entry to\ndispatch3 / dispatch4 before any read, but the analyser cannot\ntrack flow through the $ETRAP indirection used to recover from\nmissing-callout failures.\nM-MOD-036 (XECUTE injection) is intentional here: the XECUTE\nwrapper is the only way to embed $&stdcrypto.() without\nthe tree-sitter-m grammar tripping on the package-prefixed\nexternal-call syntax (open work in tree-sitter-m). The\nXECUTEd command string is built only from a literal template\nand a `sym` argument that the M-side public surface controls\n— no user data ever flows into the XECUTE source. Same\npattern as STDXFRM's @expr indirection.\nM-MOD-020 (by-ref formal not written) false positives: dispatch3\n/ dispatch4 write to `out` by reference, but the writes happen\nthrough the XECUTE'd command string, which the by-ref analyser\ncan't introspect.\n\nPublic extrinsics:\n $$sha256^STDCRYPTO(data) — 64-char lowercase hex\n $$sha384^STDCRYPTO(data) — 96-char lowercase hex\n $$sha512^STDCRYPTO(data) — 128-char lowercase hex\n $$sha256Bytes^STDCRYPTO(data) — 32 raw bytes\n $$sha384Bytes^STDCRYPTO(data) — 48 raw bytes\n $$sha512Bytes^STDCRYPTO(data) — 64 raw bytes\n $$hmacSha256^STDCRYPTO(key,msg) — 64-char lowercase hex\n $$hmacSha384^STDCRYPTO(key,msg) — 96-char lowercase hex\n $$hmacSha512^STDCRYPTO(key,msg) — 128-char lowercase hex\n $$hmacSha256Bytes^STDCRYPTO(key,msg) — 32 raw bytes\n $$hmacSha384Bytes^STDCRYPTO(key,msg) — 48 raw bytes\n $$hmacSha512Bytes^STDCRYPTO(key,msg) — 64 raw bytes\n $$available^STDCRYPTO() — 1 iff stdcrypto callout\n is loaded\n\nBackend: $&stdcrypto. → libcrypto (OpenSSL EVP_Digest + HMAC).\nThe C source is at src/callouts/std_crypto.c; the YDB call-out\ndescriptor is at tools/std_crypto.xc; the build harness is\ntools/build-callouts.sh.\n\nYottaDB ABI note — argc-prefixed C signatures: YDB's\n$&pkg.fn(args) external-call ABI prepends an `int argc` to\nevery C entry point. The .xc descriptor still describes the\nuser-visible signature (sha256(I:,O:) etc.), but the actual\nC function is `int crypto_sha256(int argc, ydb_string_t* in,\nydb_string_t* out)`. A wrong argc returns -5. The legacy\n$ZF + ydb_ci form was abandoned because YDB r2.02's parser\nrejects the `.var` byref-output syntax for $ZF.\n\nDeployment runbook (full detail in docs/modules/stdcrypto.md):\n 1. tools/build-callouts.sh ; so//std_crypto.so\n 2. export STDLIB_LIB= ; resolved by the .xc\n 3. export ydb_xc_stdcrypto=/tools/std_crypto.xc\n 4. ensure libcrypto.so.3 (or .so.1.1) is on the loader path\n\nImplementation note — XECUTE wrapper:\nM-side calls go through dispatch3 / dispatch4, which build the\n\"set rc=$&stdcrypto.(...)\" command as a STRING and XECUTE\nit. This serves two purposes:\n (a) sidesteps the tree-sitter-m grammar gap for the\n `$&pkg.fn` external-call syntax (literal strings are\n not introspected by the parser);\n (b) sidesteps a pre-existing m fmt longest-prefix bug\n where bare $ZF was rewritten to $zfind / $ZFIND.\nThe XECUTE template is closed over a `sym` argument that the\npublic extrinsics control directly — no caller-supplied data\never appears in the command source.\n\nAll error paths set $ECODE rather than raising directly so callers\ncan wrap with a single $ETRAP — matches STDCSPRNG / STDCSV style.\n\nOut of scope at v1 (queued under T-N follow-ups):\n - AES-128/256-GCM encrypt/decrypt\n - Ed25519 / Ed448 sign/verify\n - X25519 key agreement\n - Streaming digest API (init/update/final tied to a handle)\n - SHA-1, MD5 (deprecated; ship only if a real consumer asks)\n - SHA-3 / SHAKE", "errors": [ "U-STDCRYPTO-CALLOUT-MISSING", "U-STDCRYPTO-DIGEST-FAIL", "U-STDCRYPTO-HMAC-FAIL" ], "labels": { "sha256": { "form": "extrinsic", "signature": "$$sha256^STDCRYPTO(data)", "synopsis": "64-char lowercase hex SHA-256 digest of data.", "params": [ { "name": "data", "type": "byte-string", "doc": "one M character per byte" } ], "returns": { "type": "string", "doc": "64-char lowercase hex digest" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto package not loaded" }, { "code": "U-STDCRYPTO-DIGEST-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [ "write $$sha256^STDCRYPTO(\"abc\") ; \"ba7816bf...\"" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$sha384^STDCRYPTO", "$$sha512^STDCRYPTO", "$$sha256Bytes^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 86 } }, "sha384": { "form": "extrinsic", "signature": "$$sha384^STDCRYPTO(data)", "synopsis": "96-char lowercase hex SHA-384 digest of data.", "params": [ { "name": "data", "type": "byte-string", "doc": "one M character per byte" } ], "returns": { "type": "string", "doc": "96-char lowercase hex digest" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-DIGEST-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [ "write $$sha384^STDCRYPTO(\"abc\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$sha256^STDCRYPTO", "$$sha512^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 97 } }, "sha512": { "form": "extrinsic", "signature": "$$sha512^STDCRYPTO(data)", "synopsis": "128-char lowercase hex SHA-512 digest of data.", "params": [ { "name": "data", "type": "byte-string", "doc": "one M character per byte" } ], "returns": { "type": "string", "doc": "128-char lowercase hex digest" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-DIGEST-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [ "write $$sha512^STDCRYPTO(\"abc\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$sha256^STDCRYPTO", "$$sha384^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 108 } }, "sha256Bytes": { "form": "extrinsic", "signature": "$$sha256Bytes^STDCRYPTO(data)", "synopsis": "32 raw bytes — SHA-256 digest of data.", "params": [ { "name": "data", "type": "byte-string", "doc": "one M character per byte" } ], "returns": { "type": "byte-string", "doc": "32 raw bytes" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-DIGEST-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [ "set d=$$sha256Bytes^STDCRYPTO(\"abc\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$sha256^STDCRYPTO", "$$sha384Bytes^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 119 } }, "sha384Bytes": { "form": "extrinsic", "signature": "$$sha384Bytes^STDCRYPTO(data)", "synopsis": "48 raw bytes — SHA-384 digest of data.", "params": [ { "name": "data", "type": "byte-string", "doc": "one M character per byte" } ], "returns": { "type": "byte-string", "doc": "48 raw bytes" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-DIGEST-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [ "set d=$$sha384Bytes^STDCRYPTO(\"abc\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$sha384^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 133 } }, "sha512Bytes": { "form": "extrinsic", "signature": "$$sha512Bytes^STDCRYPTO(data)", "synopsis": "64 raw bytes — SHA-512 digest of data.", "params": [ { "name": "data", "type": "byte-string", "doc": "one M character per byte" } ], "returns": { "type": "byte-string", "doc": "64 raw bytes" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-DIGEST-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [ "set d=$$sha512Bytes^STDCRYPTO(\"abc\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$sha512^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 147 } }, "hmacSha256": { "form": "extrinsic", "signature": "$$hmacSha256^STDCRYPTO(key, msg)", "synopsis": "64-char lowercase hex HMAC-SHA-256 of msg under key.", "params": [ { "name": "key", "type": "byte-string", "doc": "HMAC key (any length per RFC 2104)" }, { "name": "msg", "type": "byte-string", "doc": "message to authenticate" } ], "returns": { "type": "string", "doc": "64-char lowercase hex MAC" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-HMAC-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [ "write $$hmacSha256^STDCRYPTO(\"Jefe\",\"what do ya want for nothing?\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$hmacSha384^STDCRYPTO", "$$hmacSha512^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 163 } }, "hmacSha384": { "form": "extrinsic", "signature": "$$hmacSha384^STDCRYPTO(key, msg)", "synopsis": "96-char lowercase hex HMAC-SHA-384.", "params": [ { "name": "key", "type": "byte-string", "doc": "HMAC key" }, { "name": "msg", "type": "byte-string", "doc": "message to authenticate" } ], "returns": { "type": "string", "doc": "96-char lowercase hex MAC" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-HMAC-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$hmacSha256^STDCRYPTO", "$$hmacSha512^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 175 } }, "hmacSha512": { "form": "extrinsic", "signature": "$$hmacSha512^STDCRYPTO(key, msg)", "synopsis": "128-char lowercase hex HMAC-SHA-512.", "params": [ { "name": "key", "type": "byte-string", "doc": "HMAC key" }, { "name": "msg", "type": "byte-string", "doc": "message to authenticate" } ], "returns": { "type": "string", "doc": "128-char lowercase hex MAC" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-HMAC-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$hmacSha256^STDCRYPTO", "$$hmacSha384^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 186 } }, "hmacSha256Bytes": { "form": "extrinsic", "signature": "$$hmacSha256Bytes^STDCRYPTO(key, msg)", "synopsis": "32 raw bytes — HMAC-SHA-256.", "params": [ { "name": "key", "type": "byte-string", "doc": "HMAC key" }, { "name": "msg", "type": "byte-string", "doc": "message to authenticate" } ], "returns": { "type": "byte-string", "doc": "32 raw bytes" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-HMAC-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$hmacSha256^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 197 } }, "hmacSha384Bytes": { "form": "extrinsic", "signature": "$$hmacSha384Bytes^STDCRYPTO(key, msg)", "synopsis": "48 raw bytes — HMAC-SHA-384.", "params": [ { "name": "key", "type": "byte-string", "doc": "HMAC key" }, { "name": "msg", "type": "byte-string", "doc": "message" } ], "returns": { "type": "byte-string", "doc": "48 raw bytes" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-HMAC-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$hmacSha384^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 211 } }, "hmacSha512Bytes": { "form": "extrinsic", "signature": "$$hmacSha512Bytes^STDCRYPTO(key, msg)", "synopsis": "64 raw bytes — HMAC-SHA-512.", "params": [ { "name": "key", "type": "byte-string", "doc": "HMAC key" }, { "name": "msg", "type": "byte-string", "doc": "message" } ], "returns": { "type": "byte-string", "doc": "64 raw bytes" }, "raises": [ { "code": "U-STDCRYPTO-CALLOUT-MISSING", "doc": "std_crypto not loaded" }, { "code": "U-STDCRYPTO-HMAC-FAIL", "doc": "libcrypto reported failure" } ], "raised_in_body": [], "examples": [], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$hmacSha512^STDCRYPTO" ], "deprecated": "", "description": "", "source": { "file": "src/STDCRYPTO.m", "line": 225 } }, "available": { "form": "extrinsic", "signature": "$$available^STDCRYPTO()", "synopsis": "1 iff std_crypto callout is loaded and resolves.", "params": [], "returns": { "type": "bool", "doc": "1 iff std_crypto callout is loaded and produces a digest" }, "raises": [], "raised_in_body": [], "examples": [ "if '$$available^STDCRYPTO() s $ec=\",U-MYAPP-NO-CRYPTO,\"" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$sha256^STDCRYPTO" ], "deprecated": "", "description": "Pre-flight probe — never raises.", "source": { "file": "src/STDCRYPTO.m", "line": 241 } } }, "source": { "file": "src/STDCRYPTO.m", "line": 1 } }, "STDCSPRNG": { "synopsis": "m-stdlib — Cryptographic random (kernel CSPRNG via getrandom(2) | /dev/urandom).", "description": "m-lint: disable-file=M-MOD-024\nm-lint: disable-file=M-MOD-036\nM-MOD-024 false positives: the linter parses YDB OPEN/USE\ndeviceparams (readonly, nowrap, noecho) as local-variable reads,\nthen cascades read-of-undefined complaints across bytes/available;\nrc / out are also initialised before the XECUTE'd $ZF dispatch\nbut the analyser cannot follow flow through XECUTE indirection.\nSame finding as STDCSV / STDCRYPTO — tracked as a P2 in\nTOOLCHAIN-FINDINGS.md.\nM-MOD-036 (XECUTE injection) is intentional: the XECUTE wrapper\nis the only way to invoke $ZF without m fmt's abbreviation\nexpander mangling the token (longest-prefix match against\n$ZFIND). Same trick as STDCRYPTO / STDHTTP / STDCOMPRESS;\nthe XECUTE source is built from a literal template only.\n\nPublic extrinsics:\n $$bytes^STDCSPRNG(n) — n random bytes\n $$hex^STDCSPRNG(n) — 2n lowercase hex chars (n bytes hex-encoded)\n $$base64^STDCSPRNG(n) — URL-safe base64 of n bytes (no padding)\n $$token^STDCSPRNG(n) — n-char URL-safe token from [A-Za-z0-9_-]\n $$int^STDCSPRNG(min,max) — uniform integer in [min,max] (inclusive)\n $$uuid4^STDCSPRNG() — crypto-strong RFC-4122 v4 UUID\n $$available^STDCSPRNG() — 1 iff /dev/urandom is readable\n $$useCallout^STDCSPRNG() — 1 iff cs_random callout is loaded\n\nEntropy: Linux kernel ChaCha20 CSPRNG. Two backends share the\nsame pool, so the choice is purely a perf concern:\n • cs_random — $ZF → getrandom(2). Batched single-call read;\n no fd churn, no record-terminator dance. Picked when\n $ZTRNLNM(\"ydb_xc_std_csprng\") is set (descriptor deployed)\n and the .so resolves on first probe.\n • /dev/urandom — pure-M READ *b loop; one device read per\n byte. Always available on Linux YDB; the soft-fall-back\n when the callout is absent.\nThe public API is identical across both — callers never need to\npick. Suitable for session tokens, password reset tokens, JWT\nsigning salts, nonces.\n\nDistinct from $RANDOM (Mersenne Twister): $RANDOM is fast and\nstatistically uniform but its output is predictable from a few\nsamples — never use it for security-sensitive identifiers. Use\nSTDCSPRNG instead.\n\nDeployment runbook (full detail in docs/modules/stdcsprng.md):\n 1. tools/build-callouts.sh ; produce so//cs_random.so\n 2. export STDLIB_LIB= ; substituted into std_csprng.xc\n 3. export ydb_xc_std_csprng=/tools/std_csprng.xc\nWith those unset, bytes() / hex() / base64() / token() / int() /\nuuid4() all keep working via /dev/urandom — the callout is a\nperf-only swap.", "errors": [ "U-STDCSPRNG-BAD-COUNT", "U-STDCSPRNG-OPEN-FAIL", "U-STDCSPRNG-BAD-RANGE" ], "labels": { "bytes": { "form": "extrinsic", "signature": "$$bytes^STDCSPRNG(n)", "synopsis": "Return n random bytes from the kernel CSPRNG.", "params": [ { "name": "n", "type": "int", "doc": "byte count (>= 0)" } ], "returns": { "type": "byte-string", "doc": "n random bytes; \"\" for n=0" }, "raises": [ { "code": "U-STDCSPRNG-BAD-COUNT", "doc": "n < 0" }, { "code": "U-STDCSPRNG-OPEN-FAIL", "doc": "neither backend can produce bytes" } ], "raised_in_body": [ "U-STDCSPRNG-BAD-COUNT" ], "examples": [ "set b=$$bytes^STDCSPRNG(16) ; 16 random bytes" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$hex^STDCSPRNG", "$$base64^STDCSPRNG", "$$token^STDCSPRNG", "$$uuid4^STDCSPRNG" ], "deprecated": "", "description": "Tries $ZF → cs_random (getrandom(2)) first; falls back to a\n/dev/urandom READ *b loop when the callout descriptor is unset\nor the .so does not resolve.", "source": { "file": "src/STDCSPRNG.m", "line": 57 } }, "hex": { "form": "extrinsic", "signature": "$$hex^STDCSPRNG(n)", "synopsis": "Return 2n lowercase hex chars representing n random bytes.", "params": [ { "name": "n", "type": "int", "doc": "byte count (>= 0)" } ], "returns": { "type": "string", "doc": "2n lowercase hex chars" }, "raises": [ { "code": "U-STDCSPRNG-BAD-COUNT", "doc": "n < 0" } ], "raised_in_body": [ "U-STDCSPRNG-BAD-COUNT" ], "examples": [ "set t=$$hex^STDCSPRNG(16) ; 32-char hex token" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$bytes^STDCSPRNG", "$$encode^STDHEX" ], "deprecated": "", "description": "", "source": { "file": "src/STDCSPRNG.m", "line": 89 } }, "base64": { "form": "extrinsic", "signature": "$$base64^STDCSPRNG(n)", "synopsis": "Return URL-safe base64 of n random bytes (no padding).", "params": [ { "name": "n", "type": "int", "doc": "byte count (>= 0)" } ], "returns": { "type": "string", "doc": "URL-safe base64 (no padding)" }, "raises": [ { "code": "U-STDCSPRNG-BAD-COUNT", "doc": "n < 0" } ], "raised_in_body": [ "U-STDCSPRNG-BAD-COUNT" ], "examples": [ "set t=$$base64^STDCSPRNG(32) ; ~43-char URL-safe token" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$bytes^STDCSPRNG", "$$urlencode^STDB64" ], "deprecated": "", "description": "", "source": { "file": "src/STDCSPRNG.m", "line": 101 } }, "token": { "form": "extrinsic", "signature": "$$token^STDCSPRNG(n)", "synopsis": "Return an n-char URL-safe token from alphabet [A-Za-z0-9_-].", "params": [ { "name": "n", "type": "int", "doc": "character count (>= 0)" } ], "returns": { "type": "string", "doc": "n-char token from [A-Za-z0-9_-]" }, "raises": [ { "code": "U-STDCSPRNG-BAD-COUNT", "doc": "n < 0" } ], "raised_in_body": [ "U-STDCSPRNG-BAD-COUNT" ], "examples": [ "set t=$$token^STDCSPRNG(22) ; 22-char URL-safe token" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$base64^STDCSPRNG", "$$bytes^STDCSPRNG" ], "deprecated": "", "description": "Each character is one uniform draw from a 64-char alphabet\n(6 bits of entropy per char), giving 6n bits of entropy total.", "source": { "file": "src/STDCSPRNG.m", "line": 113 } }, "int": { "form": "extrinsic", "signature": "$$int^STDCSPRNG(min, max)", "synopsis": "Return uniform integer in [min, max] (inclusive both ends).", "params": [ { "name": "min", "type": "int", "doc": "lower bound (inclusive)" }, { "name": "max", "type": "int", "doc": "upper bound (inclusive)" } ], "returns": { "type": "int", "doc": "uniform random integer in [min, max]" }, "raises": [ { "code": "U-STDCSPRNG-BAD-RANGE", "doc": "max < min" } ], "raised_in_body": [ "U-STDCSPRNG-BAD-RANGE" ], "examples": [ "set d=$$int^STDCSPRNG(1,6) ; fair 6-sided die" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$bytes^STDCSPRNG" ], "deprecated": "", "description": "Uses rejection sampling on the smallest power of 256 covering\nthe range, so the distribution is unbiased. Range is bounded\nby M scalar precision (~10^18 ≈ 2^60).", "source": { "file": "src/STDCSPRNG.m", "line": 131 } }, "uuid4": { "form": "extrinsic", "signature": "$$uuid4^STDCSPRNG()", "synopsis": "Return a cryptographically strong RFC-4122 v4 UUID.", "params": [], "returns": { "type": "string", "doc": "canonical 36-char hex UUID v4 (lowercase, hyphenated)" }, "raises": [], "raised_in_body": [], "examples": [ "set id=$$uuid4^STDCSPRNG()" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$v4^STDUUID", "$$bytes^STDCSPRNG" ], "deprecated": "", "description": "122 bits of entropy from the kernel CSPRNG. Use this when the\nUUID is a security boundary (session tokens, signed-URL nonces,\nJWT jti) — STDUUID's $$v4 uses non-cryptographic $RANDOM.", "source": { "file": "src/STDCSPRNG.m", "line": 157 } }, "available": { "form": "extrinsic", "signature": "$$available^STDCSPRNG()", "synopsis": "Return 1 iff /dev/urandom is openable for reading; else 0.", "params": [], "returns": { "type": "bool", "doc": "1 iff /dev/urandom is readable" }, "raises": [], "raised_in_body": [ "U-MYAPP-NO-CSPRNG" ], "examples": [ "if '$$available^STDCSPRNG() set $ecode=\",U-MYAPP-NO-CSPRNG,\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$useCallout^STDCSPRNG" ], "deprecated": "", "description": "Pre-flight probe — never raises. The device is the always-\navailable soft-fall-back; see useCallout() to detect the\nperf-tier backend separately.", "source": { "file": "src/STDCSPRNG.m", "line": 177 } }, "useCallout": { "form": "extrinsic", "signature": "$$useCallout^STDCSPRNG()", "synopsis": "Return 1 iff the cs_random callout resolves; else 0.", "params": [], "returns": { "type": "bool", "doc": "1 iff $ZF → cs_random is wired and getrandom(2) succeeded" }, "raises": [], "raised_in_body": [], "examples": [ "if $$useCallout^STDCSPRNG() write \"fast path\"" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$available^STDCSPRNG", "$$bytes^STDCSPRNG" ], "deprecated": "", "description": "Pre-flight probe for the $ZF → getrandom(2) backend.\nNever raises — clears $ECODE on the way out.", "source": { "file": "src/STDCSPRNG.m", "line": 193 } } }, "source": { "file": "src/STDCSPRNG.m", "line": 1 } }, "STDCSV": { "synopsis": "m-stdlib — RFC-4180 CSV parser/writer (pure-M).", "description": "m-lint: disable-file=M-MOD-024\nM-MOD-024 false positives: the linter parses YDB OPEN/CLOSE\ndeviceparams (readonly, newversion, stream, nowrap, delete) as\nlocal-variable reads, then cascades read-of-undefined complaints\nthrough the rest of parseFile/writeFile. Tracked as a P2 in\nTOOLCHAIN-FINDINGS.md.\n\nFour public entry points:\n $$parse^STDCSV(text,.rows) — text → rows(i,j); returns row count\n $$write^STDCSV(.rows) — rows(i,j) → RFC-4180 CSV text\n parseFile^STDCSV(path,cb) — read path; dispatch cb(row,.fields) per record\n writeFile^STDCSV(path,.rows) — write rows(i,j) to path as RFC-4180 CSV\n\nBehaviours (RFC-4180 §2):\n §2.1 — records separated by CRLF; LF-only and lone-CR are also\n accepted on input. write() emits CRLF.\n §2.2 — trailing line terminator on the last record is optional\n on input; write() always emits one.\n §2.3 — header rows have the same shape as data rows; the parser\n does not distinguish them.\n §2.4 — spaces inside fields are preserved verbatim.\n §2.5 — fields may optionally be wrapped in '\"...\"'; the wrapping\n quotes are not part of the value.\n §2.6 — quoted fields may contain ',', CR, or LF as literals.\n §2.7 — '\"\"' inside a quoted field decodes to a single '\"';\n write() doubles any embedded '\"' and wraps the field.\n\nExtension over the RFC: a leading UTF-8 BOM (EF BB BF) is stripped\nfrom the input by parse(). write() never emits a BOM.\n\nErrors set $ECODE to one of:\n ,U-STDCSV-OPEN-FAIL,\n\nInput is treated as a string of bytes (one M character per byte —\nvalues 0..255 via $ASCII / $CHAR). Embedded NUL bytes are not\nsupported (M strings cannot represent them portably).", "errors": [ "U-STDCSV-OPEN-FAIL" ], "labels": { "parse": { "form": "extrinsic", "signature": "$$parse^STDCSV(text, rows)", "synopsis": "Parse CSV text into rows(i,j); return row count.", "params": [ { "name": "text", "type": "string", "doc": "CSV document (CRLF, LF, or lone-CR record terminators)" }, { "name": "rows", "type": "array", "doc": "caller-owned destination; killed before population" } ], "returns": { "type": "int", "doc": "number of rows parsed (0 if `text` is empty)" }, "raises": [], "raised_in_body": [], "examples": [ "set n=$$parse^STDCSV(\"a,b,c\"_$char(13,10),.r)" ], "since": "v0.0.6", "stable": "stable", "see_also": [ "$$write^STDCSV", "do parseFile^STDCSV" ], "deprecated": "", "description": "Strips a leading UTF-8 BOM. Quoted fields may contain commas,\nCRLF, and \"\" escapes (RFC-4180 §2.5–§2.7).", "source": { "file": "src/STDCSV.m", "line": 43 } }, "write": { "form": "extrinsic", "signature": "$$write^STDCSV(rows)", "synopsis": "Serialise rows(i,j) to RFC-4180 CSV text.", "params": [ { "name": "rows", "type": "array", "doc": "by-ref local subscripted as rows(i,j) for row i, col j" } ], "returns": { "type": "string", "doc": "RFC-4180 text with CRLF row terminators; \"\" for empty input" }, "raises": [], "raised_in_body": [], "examples": [ "set r(1,1)=\"a\",r(1,2)=\"b\" write $$write^STDCSV(.r)" ], "since": "v0.0.6", "stable": "stable", "see_also": [ "$$parse^STDCSV", "do writeFile^STDCSV" ], "deprecated": "", "description": "Fields containing ',', '\"', CR, or LF are wrapped in '\"...\"'\nwith embedded '\"' doubled per RFC-4180 §2.7. Sparse columns\nwalk via $order, so ragged rows are emitted with as many\nfields as are defined.", "source": { "file": "src/STDCSV.m", "line": 83 } }, "parseFile": { "form": "procedure", "signature": "do parseFile^STDCSV(path, callback)", "synopsis": "Parse file at path; dispatch callback per record.", "params": [ { "name": "path", "type": "string", "doc": "filesystem path to a CSV file" }, { "name": "callback", "type": "string", "doc": "M call-site as \"label^routine\" (used via @-indirection)" } ], "returns": null, "raises": [ { "code": "U-STDCSV-OPEN-FAIL", "doc": "could not open `path` for read" } ], "raised_in_body": [ "U-STDCSV-OPEN-FAIL" ], "examples": [ "do parseFile^STDCSV(\"foo.csv\",\"onrow^MYAPP\")" ], "since": "v0.0.6", "stable": "stable", "see_also": [ "$$parse^STDCSV", "do writeFile^STDCSV" ], "deprecated": "", "description": "Reads `path` line-by-line, accumulating across record boundaries\nwhen a quoted field contains an embedded line break (RFC-4180\n§2.6). For each completed record, calls\ndo @callback@(rownum, .fields)\nwhere fields(j) holds the j'th field (1-based) and rownum is\nthe 1-based record index.", "source": { "file": "src/STDCSV.m", "line": 107 } }, "writeFile": { "form": "procedure", "signature": "do writeFile^STDCSV(path, rows)", "synopsis": "Serialise rows(i,j) and write to path as RFC-4180 CSV.", "params": [ { "name": "path", "type": "string", "doc": "filesystem path; truncated if it exists" }, { "name": "rows", "type": "array", "doc": "by-ref local subscripted as rows(i,j)" } ], "returns": null, "raises": [ { "code": "U-STDCSV-OPEN-FAIL", "doc": "could not open `path` for write" } ], "raised_in_body": [ "U-STDCSV-OPEN-FAIL" ], "examples": [ "do writeFile^STDCSV(\"/tmp/out.csv\",.rows)" ], "since": "v0.0.6", "stable": "stable", "see_also": [ "$$write^STDCSV", "do parseFile^STDCSV" ], "deprecated": "", "description": "Uses STREAM mode so embedded CRLFs in quoted fields are written\nbyte-faithfully.", "source": { "file": "src/STDCSV.m", "line": 150 } } }, "source": { "file": "src/STDCSV.m", "line": 1 } }, "STDDATE": { "synopsis": "m-stdlib — ISO-8601 datetime + arithmetic (v0.0.5).", "description": "Public extrinsics:\n $$now^STDDATE() — current ISO-8601 UTC (\"...Z\")\n $$fromh^STDDATE(h) — $HOROLOG -> ISO-8601 string\n $$toh^STDDATE(iso) — ISO-8601 -> $HOROLOG form\n $$strftime^STDDATE(h,fmt) — format horolog per fmt\n $$strptime^STDDATE(text,fmt) — parse text per fmt -> horolog\n $$add^STDDATE(h,dur) — h + ISO-8601 duration -> horolog\n $$diff^STDDATE(h1,h2) — h2-h1 -> ISO-8601 duration\n\nHorolog forms accepted/emitted:\n 2-piece: D,S ($HOROLOG)\n 3-piece: D,S,U (with microseconds)\n 4-piece: D,S,U,T (with microseconds and tz offset in seconds)\n\nCalendar: proleptic Gregorian. Day 0 = 1840-12-31 (M $HOROLOG epoch);\nUnix epoch (1970-01-01) = day 47117. Civil <-> day-count conversions\nuse Howard Hinnant's \"days_from_civil\" algorithm — works for any\nyear in proleptic Gregorian.\n\nErrors set $ECODE to one of:\n ,U-STDDATE-BAD-HOROLOG,\n ,U-STDDATE-BAD-ISO,\n ,U-STDDATE-BAD-DUR,", "errors": [ "U-STDDATE-BAD-HOROLOG", "U-STDDATE-BAD-ISO", "U-STDDATE-BAD-DUR" ], "labels": { "now": { "form": "extrinsic", "signature": "$$now^STDDATE()", "synopsis": "Return current time as ISO-8601 UTC with millisecond precision.", "params": [], "returns": { "type": "string", "doc": "ISO-8601 UTC: \"YYYY-MM-DDTHH:MM:SS.sssZ\"" }, "raises": [], "raised_in_body": [], "examples": [ "write $$now^STDDATE() ; ISO-8601 UTC, e.g. 2026-05-05T17:42:31.123Z", "write $length($$now^STDDATE()) ; 24" ], "since": "v0.0.5", "stable": "stable", "see_also": [ "$$fromh^STDDATE", "$$strftime^STDDATE" ], "deprecated": "", "description": "Always trailing Z. Source: $ZHOROLOG (microsecond + tz pieces).", "source": { "file": "src/STDDATE.m", "line": 31 } }, "fromh": { "form": "extrinsic", "signature": "$$fromh^STDDATE(h)", "synopsis": "Format a $HOROLOG (2/3/4-piece) as ISO-8601.", "params": [ { "name": "h", "type": "horolog", "doc": "comma-piece form: D,S | D,S,U | D,S,U,T" } ], "returns": { "type": "string", "doc": "ISO-8601 rendering (precision matches piece-count)" }, "raises": [ { "code": "U-STDDATE-BAD-HOROLOG", "doc": "`h` is not a 2/3/4-piece comma string" } ], "raised_in_body": [ "U-STDDATE-BAD-HOROLOG" ], "examples": [ "write $$fromh^STDDATE(\"47117,0\") ; \"1970-01-01T00:00:00\"" ], "since": "v0.0.5", "stable": "stable", "see_also": [ "$$toh^STDDATE", "$$strftime^STDDATE" ], "deprecated": "", "description": "2-piece D,S -> \"YYYY-MM-DDTHH:MM:SS\"\n3-piece D,S,U -> \"...HH:MM:SS.uuuuuu\" when U>0\n4-piece D,S,U,T -> \"...\" + \"Z\" or \"+HH:MM\" / \"-HH:MM\"", "source": { "file": "src/STDDATE.m", "line": 53 } }, "toh": { "form": "extrinsic", "signature": "$$toh^STDDATE(iso)", "synopsis": "Parse an ISO-8601 string into $HOROLOG form.", "params": [ { "name": "iso", "type": "string", "doc": "ISO-8601: date, date+time, or date+time+tz" } ], "returns": { "type": "horolog", "doc": "2/3/4-piece comma string; \"\" on parse failure" }, "raises": [ { "code": "U-STDDATE-BAD-ISO", "doc": "malformed input or invalid date" } ], "raised_in_body": [ "U-STDDATE-BAD-ISO" ], "examples": [ "write $$toh^STDDATE(\"1970-01-01\") ; \"47117,0\"" ], "since": "v0.0.5", "stable": "stable", "see_also": [ "$$fromh^STDDATE", "$$strptime^STDDATE" ], "deprecated": "", "description": "2-piece D,S for date or date+time without subsec/tz;\n3-piece D,S,U if subseconds present; 4-piece D,S,U,T if tz.\n\"Z\" -> tzoff=0. \"+HH:MM\"/\"-HH:MM\" -> tzoff in seconds.", "source": { "file": "src/STDDATE.m", "line": 74 } }, "strftime": { "form": "extrinsic", "signature": "$$strftime^STDDATE(h, fmt)", "synopsis": "Format a horolog per a strftime-style format string.", "params": [ { "name": "h", "type": "horolog", "doc": "comma-piece form: D,S | D,S,U | D,S,U,T" }, { "name": "fmt", "type": "string", "doc": "format string with %Y %m %d %H %M %S %j %z %% directives" } ], "returns": { "type": "string", "doc": "the rendered date/time" }, "raises": [ { "code": "U-STDDATE-BAD-HOROLOG", "doc": "`h` is not a 2/3/4-piece comma string" } ], "raised_in_body": [ "U-STDDATE-BAD-HOROLOG" ], "examples": [ "write $$strftime^STDDATE(\"47117,0\",\"%Y-%m-%d\") ; \"1970-01-01\"" ], "since": "v0.0.5", "stable": "stable", "see_also": [ "$$strptime^STDDATE", "$$fromh^STDDATE" ], "deprecated": "", "description": "Unknown directives pass through as \"%X\". %z emits +HHMM/-HHMM\n(no colon) or \"\" if h has no tz piece.", "source": { "file": "src/STDDATE.m", "line": 131 } }, "strptime": { "form": "extrinsic", "signature": "$$strptime^STDDATE(text, fmt)", "synopsis": "Parse text per format string into a horolog.", "params": [ { "name": "text", "type": "string", "doc": "the input text to parse" }, { "name": "fmt", "type": "string", "doc": "format string with %Y %m %d %H %M %S directives" } ], "returns": { "type": "horolog", "doc": "2-piece D,S; \"\" on parse failure" }, "raises": [ { "code": "U-STDDATE-BAD-ISO", "doc": "parse mismatch or invalid date components" } ], "raised_in_body": [ "U-STDDATE-BAD-ISO" ], "examples": [ "write $$strptime^STDDATE(\"1970-01-01\",\"%Y-%m-%d\") ; \"47117,0\"" ], "since": "v0.0.5", "stable": "stable", "see_also": [ "$$strftime^STDDATE", "$$toh^STDDATE" ], "deprecated": "", "description": "Literal characters in fmt must match `text` exactly; only the\ndocumented directives are honoured.", "source": { "file": "src/STDDATE.m", "line": 165 } }, "add": { "form": "extrinsic", "signature": "$$add^STDDATE(h, dur)", "synopsis": "Add an ISO-8601 duration to a horolog. Negative prefix \"-P...\" accepted.", "params": [ { "name": "h", "type": "horolog", "doc": "comma-piece form: D,S | D,S,U | D,S,U,T" }, { "name": "dur", "type": "string", "doc": "ISO-8601 duration (\"P1Y\", \"PT2H30M\", \"-P1D\", etc.)" } ], "returns": { "type": "horolog", "doc": "2-piece D,S after addition; \"\" on error" }, "raises": [ { "code": "U-STDDATE-BAD-DUR", "doc": "`dur` is not a valid ISO-8601 duration" }, { "code": "U-STDDATE-BAD-HOROLOG", "doc": "`h` is not a 2/3/4-piece comma string" } ], "raised_in_body": [ "U-STDDATE-BAD-DUR", "U-STDDATE-BAD-HOROLOG" ], "examples": [ "write $$add^STDDATE(\"47117,0\",\"P1DT2H30M\") ; \"47118,9000\"" ], "since": "v0.0.5", "stable": "stable", "see_also": [ "$$diff^STDDATE" ], "deprecated": "", "description": "Calendar arithmetic for Y/M (with day-clamp on shorter months);\nraw day arithmetic for W/D; second-arithmetic for H/M/S.", "source": { "file": "src/STDDATE.m", "line": 201 } }, "diff": { "form": "extrinsic", "signature": "$$diff^STDDATE(h1, h2)", "synopsis": "Return h2 - h1 as an ISO-8601 duration.", "params": [ { "name": "h1", "type": "horolog", "doc": "start time (2-piece D,S minimum)" }, { "name": "h2", "type": "horolog", "doc": "end time (2-piece D,S minimum)" } ], "returns": { "type": "string", "doc": "ISO-8601 duration; \"PT0S\" if zero; \"-P...\" if h2 < h1" }, "raises": [], "raised_in_body": [], "examples": [ "write $$diff^STDDATE(\"47117,0\",\"47118,0\") ; \"P1D\"" ], "since": "v0.0.5", "stable": "stable", "see_also": [ "$$add^STDDATE" ], "deprecated": "", "description": "Days carry into hours/minutes/seconds; never emits Y or M\n(variable-length).", "source": { "file": "src/STDDATE.m", "line": 253 } } }, "source": { "file": "src/STDDATE.m", "line": 1 } }, "STDENV": { "synopsis": "m-stdlib — .env file loader with typed accessors.", "description": "Public extrinsics:\n $$parse^STDENV(text, .env) — parse .env-formatted text\n $$parseFile^STDENV(path, .env) — readFile then parse\n $$valid^STDENV(text) — predicate (parse without populate)\n $$has^STDENV(.env, key) — 1 iff key was set\n $$get^STDENV(.env, key, default) — string fetch with default\n $$getInt^STDENV(.env, key, default) — integer; default if missing or non-numeric\n $$getBool^STDENV(.env, key, default) — bool from {true,yes,on,1} / {false,no,off,0}\n $$getFloat^STDENV(.env, key, default) — float; default if missing or non-numeric\n\nFormat (typical .env subset):\n ::= | | \n ::= \"#\" .* (whole-line; trailing not stripped)\n ::= \"=\" \n ::= [A-Za-z_][A-Za-z0-9_]*\n ::= | | \n ::= raw chars (whitespace-trimmed)\n ::= \"...\" with \\n \\t \\r \\\" \\\\ escapes\n ::= '...' (no escape processing — POSIX-style)\n\nOut of scope (queued for v0.x.y under T22):\n - variable substitution (`$VAR` / `${VAR}` references)\n - export prefix (Bash `export FOO=bar`)\n - multi-line values (PEM keys etc.)\n - process-environment integration (write parsed env back into\n $ZTRNLNM space — needs setenv() callout from T15)", "errors": [ "U-STDFS-OPEN-FAIL" ], "labels": { "parse": { "form": "extrinsic", "signature": "$$parse^STDENV(text, env)", "synopsis": "Parse .env text into env tree; return 1 on success, 0 on parse error.", "params": [ { "name": "text", "type": "string", "doc": ".env-formatted text" }, { "name": "env", "type": "array", "doc": "by-ref local; killed then populated as env(KEY)=value" } ], "returns": { "type": "bool", "doc": "1 on success; 0 on parse error" }, "raises": [], "raised_in_body": [], "examples": [ "do set rc=$$parse^STDENV(text,.cfg)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$parseFile^STDENV", "$$valid^STDENV" ], "deprecated": "", "description": "On failure, env is left in whatever partial state the parse achieved.", "source": { "file": "src/STDENV.m", "line": 34 } }, "parseFile": { "form": "extrinsic", "signature": "$$parseFile^STDENV(path, env)", "synopsis": "Read path via STDFS and parse the contents.", "params": [ { "name": "path", "type": "string", "doc": "filesystem path to a .env file" }, { "name": "env", "type": "array", "doc": "by-ref local; populated as env(KEY)=value" } ], "returns": { "type": "bool", "doc": "1 on success; 0 if file is missing or parse fails" }, "raises": [ { "code": "U-STDFS-OPEN-FAIL", "doc": "could not read `path` (propagated from STDFS)" } ], "raised_in_body": [], "examples": [ "do set rc=$$parseFile^STDENV(\".env\",.cfg)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$parse^STDENV" ], "deprecated": "", "description": "A missing file returns 0 without raising; an unreadable file raises.", "source": { "file": "src/STDENV.m", "line": 56 } }, "valid": { "form": "extrinsic", "signature": "$$valid^STDENV(text)", "synopsis": "Return 1 iff text is parseable as .env. Discards the result.", "params": [ { "name": "text", "type": "string", "doc": "candidate .env text" } ], "returns": { "type": "bool", "doc": "1 iff parseable; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDENV(\".env line\\nA=1\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$parse^STDENV" ], "deprecated": "", "description": "", "source": { "file": "src/STDENV.m", "line": 71 } }, "has": { "form": "extrinsic", "signature": "$$has^STDENV(env, key)", "synopsis": "Return 1 iff key is defined in env; else 0.", "params": [ { "name": "env", "type": "array", "doc": "by-ref env tree from $$parse^STDENV" }, { "name": "key", "type": "string", "doc": "env key" } ], "returns": { "type": "bool", "doc": "1 iff key is defined; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "if $$has^STDENV(.cfg,\"DATABASE_URL\") ..." ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$get^STDENV" ], "deprecated": "", "description": "", "source": { "file": "src/STDENV.m", "line": 81 } }, "get": { "form": "extrinsic", "signature": "$$get^STDENV(env, key, default)", "synopsis": "Return env(key); else default.", "params": [ { "name": "env", "type": "array", "doc": "by-ref env tree" }, { "name": "key", "type": "string", "doc": "env key" }, { "name": "default", "type": "string", "doc": "fallback when key is absent" } ], "returns": { "type": "string", "doc": "env(key) or default" }, "raises": [], "raised_in_body": [], "examples": [ "set host=$$get^STDENV(.cfg,\"HOST\",\"localhost\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$getInt^STDENV", "$$getBool^STDENV", "$$getFloat^STDENV" ], "deprecated": "", "description": "", "source": { "file": "src/STDENV.m", "line": 91 } }, "getInt": { "form": "extrinsic", "signature": "$$getInt^STDENV(env, key, default)", "synopsis": "Return env(key) coerced to integer; default if missing or non-numeric.", "params": [ { "name": "env", "type": "array", "doc": "by-ref env tree" }, { "name": "key", "type": "string", "doc": "env key" }, { "name": "default", "type": "int", "doc": "fallback when key is absent or non-integer" } ], "returns": { "type": "int", "doc": "parsed integer or default" }, "raises": [], "raised_in_body": [], "examples": [ "set port=$$getInt^STDENV(.cfg,\"PORT\",8080)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$get^STDENV", "$$getFloat^STDENV" ], "deprecated": "", "description": "Floats and non-numeric values yield the default.", "source": { "file": "src/STDENV.m", "line": 102 } }, "getFloat": { "form": "extrinsic", "signature": "$$getFloat^STDENV(env, key, default)", "synopsis": "Return env(key) coerced to float; default if missing or non-numeric.", "params": [ { "name": "env", "type": "array", "doc": "by-ref env tree" }, { "name": "key", "type": "string", "doc": "env key" }, { "name": "default", "type": "num", "doc": "fallback when key is absent or non-numeric" } ], "returns": { "type": "num", "doc": "parsed float or default" }, "raises": [], "raised_in_body": [], "examples": [ "set ratio=$$getFloat^STDENV(.cfg,\"RATIO\",1.0)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$get^STDENV", "$$getInt^STDENV" ], "deprecated": "", "description": "", "source": { "file": "src/STDENV.m", "line": 120 } }, "getBool": { "form": "extrinsic", "signature": "$$getBool^STDENV(env, key, default)", "synopsis": "Return env(key) interpreted as boolean; default if missing or unrecognized.", "params": [ { "name": "env", "type": "array", "doc": "by-ref env tree" }, { "name": "key", "type": "string", "doc": "env key" }, { "name": "default", "type": "bool", "doc": "fallback when key is absent or unrecognized" } ], "returns": { "type": "bool", "doc": "parsed boolean or default" }, "raises": [], "raised_in_body": [], "examples": [ "set debug=$$getBool^STDENV(.cfg,\"DEBUG\",0)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$get^STDENV" ], "deprecated": "", "description": "Truthy: \"true\" / \"yes\" / \"on\" / \"1\" (case-insensitive).\nFalsy: \"false\" / \"no\" / \"off\" / \"0\" (case-insensitive).", "source": { "file": "src/STDENV.m", "line": 136 } } }, "source": { "file": "src/STDENV.m", "line": 1 } }, "STDFIX": { "synopsis": "m-stdlib — fixture lifecycle and per-test isolation.", "description": "YDB nested-transaction-based isolation. YDB enforces TPQUIT:\n``tstart`` and the matching ``trollback`` MUST live in the same\nroutine frame. STDFIX therefore exposes only one-shot wrappers —\n``with`` and ``invoke`` open AND close their scope before\nreturning. There is no standalone setup() / teardown() pair.\n\nPublic labels:\n with(tag,code) ; XECUTEs code inside an auto-managed\n transaction scope; rolls back on exit\n and re-raises any error code raised\n inside ``code``.\n $$active() ; → 1 if any nested transaction is open\n (any TSTART, not just STDFIX-owned).\n register(tag,setupCode,teardownCode) ; declarative fixture\n invoke(tag,code) ; fixture-aware variant of with(): runs\n registered setup hook, then code, then\n registered teardown hook — all inside\n one rolled-back scope.\n cleanup ; idempotent rollback of any leaked\n transaction scope; safe at $tlevel=0.\n\nState layout (under ^STDLIB($job,\"FIX\",...)):\n STACK,$tlevel = tag ; one entry per open scope, set inside\n the transaction so TROLLBACK erases it.\n REG,tag,\"SETUP\" ; registered setup code\n REG,tag,\"TEARDOWN\" ; registered teardown code\n\n``trollback $tlevel-1`` rolls back exactly the level this frame\nopened, so nested with()/invoke() pairs roll back inner-only —\nbare ``trollback`` (which targets level 0) would unbalance every\nouter transaction.\n\nErrors set $ECODE to one of:\n ,U-STDFIX-EMPTY-TAG,\n ,U-STDFIX-UNREGISTERED-TAG,", "errors": [ "U-STDFIX-EMPTY-TAG", "U-STDFIX-UNREGISTERED-TAG" ], "labels": { "with": { "form": "procedure", "signature": "do with^STDFIX(tag, code)", "synopsis": "XECUTE code inside an auto-managed transaction scope.", "params": [ { "name": "tag", "type": "string", "doc": "scope identifier (recorded in the stack)" }, { "name": "code", "type": "string", "doc": "M code XECUTEd inside the transaction" } ], "returns": null, "raises": [ { "code": "U-STDFIX-EMPTY-TAG", "doc": "tag is empty" } ], "raised_in_body": [ "U-STDFIX-EMPTY-TAG" ], "examples": [ "do with^STDFIX(\"scope\",\"do migrate^DDL\")" ], "since": "v0.1.1", "stable": "stable", "see_also": [ "do invoke^STDFIX", "do register^STDFIX", "do cleanup^STDFIX" ], "deprecated": "", "description": "Opens a YDB transaction, sets the scope tag in the stack,\nXECUTEs code, then ``trollback $tlevel-1`` to roll back\nexactly this scope. If code raises, the trap rolls back the\nscope and re-raises so the caller can observe the original\n$ECODE.", "source": { "file": "src/STDFIX.m", "line": 43 } }, "active": { "form": "extrinsic", "signature": "$$active^STDFIX()", "synopsis": "Predicate — is any nested transaction currently open?", "params": [], "returns": { "type": "bool", "doc": "1 if $tlevel > 0; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$active^STDFIX() ; 0" ], "since": "v0.1.1", "stable": "stable", "see_also": [ "do with^STDFIX", "do cleanup^STDFIX" ], "deprecated": "", "description": "STDFIX-managed scopes also appear in ^STDLIB($job,\"FIX\",\"STACK\",N)\nfor callers that need to distinguish their own from foreign transactions.", "source": { "file": "src/STDFIX.m", "line": 68 } }, "register": { "form": "procedure", "signature": "do register^STDFIX(tag, setupCode, teardownCode)", "synopsis": "Declare a reusable setup/teardown pair.", "params": [ { "name": "tag", "type": "string", "doc": "fixture tag" }, { "name": "setupCode", "type": "string", "doc": "M code XECUTEd before the body in invoke()" }, { "name": "teardownCode", "type": "string", "doc": "M code XECUTEd after the body in invoke()" } ], "returns": null, "raises": [ { "code": "U-STDFIX-EMPTY-TAG", "doc": "tag is empty" } ], "raised_in_body": [ "U-STDFIX-EMPTY-TAG" ], "examples": [ "do register^STDFIX(\"db\",\"do reset^X\",\"do drop^X\")" ], "since": "v0.1.1", "stable": "stable", "see_also": [ "do invoke^STDFIX" ], "deprecated": "", "description": "", "source": { "file": "src/STDFIX.m", "line": 78 } }, "invoke": { "form": "procedure", "signature": "do invoke^STDFIX(tag, code)", "synopsis": "Run code with registered hooks wrapping it.", "params": [ { "name": "tag", "type": "string", "doc": "fixture tag previously declared via register()" }, { "name": "code", "type": "string", "doc": "M code XECUTEd between the registered setup/teardown" } ], "returns": null, "raises": [ { "code": "U-STDFIX-UNREGISTERED-TAG", "doc": "tag was never register()ed" } ], "raised_in_body": [ "U-STDFIX-UNREGISTERED-TAG" ], "examples": [ "do invoke^STDFIX(\"dbReset\",\"do tCheck^MYTST\")" ], "since": "v0.1.1", "stable": "stable", "see_also": [ "do register^STDFIX", "do with^STDFIX" ], "deprecated": "", "description": "Looks up registered setup/teardown for tag, then runs setup\n(if any), code, teardown (if any) — all inside one transaction\nthat rolls back on exit.", "source": { "file": "src/STDFIX.m", "line": 92 } }, "cleanup": { "form": "procedure", "signature": "do cleanup^STDFIX()", "synopsis": "Best-effort rollback of any leaked transaction scope.", "params": [], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do cleanup^STDFIX" ], "since": "v0.1.1", "stable": "stable", "see_also": [ "do with^STDFIX", "$$active^STDFIX" ], "deprecated": "", "description": "TROLLBACKs all the way to $tlevel=0 if any transaction is\nopen; safe to call at $tlevel=0 (no-op). Useful as a\ndefensive between-tests reset in runner code. Note: this\nrolls back NON-STDFIX transactions too — call only at a\ntop-level frame that owns no enclosing tstart.", "source": { "file": "src/STDFIX.m", "line": 121 } } }, "source": { "file": "src/STDFIX.m", "line": 1 } }, "STDFMT": { "synopsis": "m-stdlib — printf-style formatter (subset of Python str.format).", "description": "Two public extrinsics:\n $$f^STDFMT(template,a1,a2,...,a9) — up to 9 positional\n $$fn^STDFMT(template,.args) — keyed via local array\n\nFormat spec — a subset of Python str.format:\n {} / {N} / {name} — field reference\n {:s} {:d} {:f} {:x} {:X} {:o} {:b} — type\n {:>10} {:<10} {:^10} — alignment + width\n {:*>10} — fill char with align\n {:.3f} {:.4s} — precision (rounding for f,\n truncate for s)\n {{ }} — literal { and }\n\nType defaults:\n no type / s — string, default left-align\n d f x X o b — numeric, default right-align\n f — default precision 6 (matches Python)\n\nErrors set $ECODE to one of:\n ,U-STDFMT-MISSING-ARG,\n ,U-STDFMT-UNCLOSED-BRACE,\n ,U-STDFMT-UNESCAPED-RBRACE,\n ,U-STDFMT-UNKNOWN-TYPE,", "errors": [ "U-STDFMT-MISSING-ARG", "U-STDFMT-UNCLOSED-BRACE", "U-STDFMT-UNESCAPED-RBRACE", "U-STDFMT-UNKNOWN-TYPE" ], "labels": { "f": { "form": "extrinsic", "signature": "$$f^STDFMT(template, a1, a2, a3, a4, a5, a6, a7, a8, a9)", "synopsis": "Positional formatter (up to 9 args).", "params": [ { "name": "template", "type": "string", "doc": "format template ({}, {N}, {:fmt}, {{, }})" }, { "name": "a1", "type": "string", "doc": "positional arg 0 (optional)" }, { "name": "a2", "type": "string", "doc": "positional arg 1 (optional)" }, { "name": "a3", "type": "string", "doc": "positional arg 2 (optional)" }, { "name": "a4", "type": "string", "doc": "positional arg 3 (optional)" }, { "name": "a5", "type": "string", "doc": "positional arg 4 (optional)" }, { "name": "a6", "type": "string", "doc": "positional arg 5 (optional)" }, { "name": "a7", "type": "string", "doc": "positional arg 6 (optional)" }, { "name": "a8", "type": "string", "doc": "positional arg 7 (optional)" }, { "name": "a9", "type": "string", "doc": "positional arg 8 (optional)" } ], "returns": { "type": "string", "doc": "the rendered template" }, "raises": [ { "code": "U-STDFMT-MISSING-ARG", "doc": "referenced position has no supplied value" }, { "code": "U-STDFMT-UNCLOSED-BRACE", "doc": "`{` without matching `}` in the template" }, { "code": "U-STDFMT-UNESCAPED-RBRACE", "doc": "bare `}` outside a placeholder" }, { "code": "U-STDFMT-UNKNOWN-TYPE", "doc": "`:type` is not one of s/d/f/x/X/o/b" } ], "raised_in_body": [], "examples": [ "write $$f^STDFMT(\"hi {}\",\"world\") ; \"hi world\"" ], "since": "v0.0.3", "stable": "stable", "see_also": [ "$$fn^STDFMT" ], "deprecated": "", "description": "Supplied args fill positions 0..N-1; unsupplied positions raise\n$ECODE on lookup. The 9-arg cap is M's per-extrinsic limit; for\nmore arguments use fn() with a local array.", "source": { "file": "src/STDFMT.m", "line": 31 } }, "fn": { "form": "extrinsic", "signature": "$$fn^STDFMT(template, args)", "synopsis": "Named formatter (lookups in the passed array).", "params": [ { "name": "template", "type": "string", "doc": "format template ({}, {N}, {name}, {:fmt})" }, { "name": "args", "type": "array", "doc": "by-ref local; lookups go to args(name) or args(N)" } ], "returns": { "type": "string", "doc": "the rendered template" }, "raises": [ { "code": "U-STDFMT-MISSING-ARG", "doc": "referenced field has no entry in args" }, { "code": "U-STDFMT-UNCLOSED-BRACE", "doc": "`{` without matching `}` in the template" }, { "code": "U-STDFMT-UNESCAPED-RBRACE", "doc": "bare `}` outside a placeholder" }, { "code": "U-STDFMT-UNKNOWN-TYPE", "doc": "`:type` is not one of s/d/f/x/X/o/b" } ], "raised_in_body": [], "examples": [ "set a(\"n\")=\"x\" write $$fn^STDFMT(\"{n}\",.a) ; \"x\"" ], "since": "v0.0.3", "stable": "stable", "see_also": [ "$$f^STDFMT" ], "deprecated": "", "description": "", "source": { "file": "src/STDFMT.m", "line": 66 } } }, "source": { "file": "src/STDFMT.m", "line": 1 } }, "STDFS": { "synopsis": "m-stdlib — File-system primitives (text I/O, path manipulation, bytes).", "description": "m-lint: disable-file=M-MOD-024\nm-lint: disable-file=M-MOD-022\nm-lint: disable-file=M-MOD-036\nm-lint: disable-file=M-MOD-020\nM-MOD-024 false positives: the linter parses YDB OPEN/USE/CLOSE\ndeviceparams (readonly, newversion, append, delete, exception,\nnowrap, noecho) as local-variable reads. Same finding as STDCSV\nand STDCSPRNG; tracked as P2 in TOOLCHAIN-FINDINGS.md.\nM-MOD-022: STDFS uses $ZEOF and $ZLEVEL throughout — both are YDB\nextensions to the M standard. v0.2.x ships YDB-only by design (see\n\"Engine portability\" in docs/modules/stdfs.md). The IRIS arm will\narrive when STDFS gets its $ZF→stat callout backend.\nM-MOD-036 (XECUTE injection) is intentional in the *Bytes() dispatch\nhelpers: the XECUTE wrapper is the only way to invoke $ZF without\nthe m fmt abbreviation expander mangling the token (longest-prefix\nmatch against $ZFIND). The XECUTE source is built from a literal\ntemplate only — no user data flows in. Same trick as STDCRYPTO /\nSTDCOMPRESS / STDHTTP.\nM-MOD-020 (by-ref formal not written) false positives: dispatch\nhelpers write to `out` via the XECUTE'd $ZF call.\n\nPublic extrinsics:\n $$readFile^STDFS(path) — read file as string (LF-separated)\n $$writeFile^STDFS(path,data) — write data; overwrite if file exists\n $$append^STDFS(path,data) — append data; create if missing\n readLines^STDFS(path,.lines) — populate lines(1..N) from file\n $$writeLines^STDFS(path,.lines)— write lines(1..N) as LF-separated\n $$exists^STDFS(path) — 1 iff path exists\n $$remove^STDFS(path) — delete path; no-op if absent\n $$size^STDFS(path) — size in bytes; -1 if missing\n $$basename^STDFS(path) — last path component\n $$dirname^STDFS(path) — parent path (or \".\" / \"/\")\n $$join^STDFS(left,right) — POSIX path join (absolute right wins)\n\nByte-faithful I/O via $ZF -> libc read(2)/write(2) callouts (T13+T14):\n $$readBytes^STDFS(path) — file content as bytes (no CR/LF normalisation)\n writeBytes^STDFS(path,data) — write data verbatim; no trailing LF\n appendBytes^STDFS(path,data) — append data via O_APPEND atomically\n $$available^STDFS() — 1 iff stdfs.so is loaded\n\nText I/O semantics: file is read line-by-line and rejoined with LF.\nTrailing CR (CRLF input) is normalised to LF on read; write emits LF.\nBinary I/O (readBytes / writeBytes / appendBytes) preserves bytes\nexactly — no LF added on write, no CR/LF stripped on read. Use these\nfor non-text payloads (gzipped data, binaries, signed blobs).\n\nPath semantics: POSIX-flavoured. Trailing slashes on dirname/basename\nfollow GNU coreutils conventions: basename strips them, dirname keeps\nthe parent with its trailing slash collapsed.\n\nExistence checks delegate to $ZSEARCH, which YDB resolves via stat()\non first call and caches per-process. remove() opens the file with\nthe DELETE deviceparam — succeeds for files; silently no-ops if the\nfile is already absent (idempotent contract).\n\nBackend (Bytes API): $ZF -> libc open(2)/read(2)/write(2)/close(2).\nSource at src/callouts/stdfs.c; descriptor at tools/std_fs.xc.\nWhen the .so is unavailable the *Bytes() entries set $ECODE to\n,U-STDFS-NOT-WIRED, and return; the text-I/O entries (writeFile /\nreadFile / writeLines / readLines) and append() keep working via\nthe YDB SEQ device — append() then takes the read-then-rewrite\nfallback automatically.\n\nDeployment runbook (full detail in docs/modules/stdfs.md):\n 1. tools/build-callouts.sh ; produces so//stdfs.so\n 2. export STDLIB_LIB=\n 3. export ydb_xc_std_fs=/tools/std_fs.xc", "errors": [ "U-STDFS-OPEN-FAIL", "U-STDFS-REMOVE-FAIL", "U-STDFS-NOT-WIRED", "U-STDFS-READ-TRUNCATED" ], "labels": { "basename": { "form": "extrinsic", "signature": "$$basename^STDFS(path)", "synopsis": "Return the last component of path.", "params": [ { "name": "path", "type": "path", "doc": "POSIX path" } ], "returns": { "type": "string", "doc": "last path component; \"/\" for root; \"\" for empty input" }, "raises": [], "raised_in_body": [], "examples": [ "write $$basename^STDFS(\"/etc/hosts\") ; \"hosts\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$dirname^STDFS", "$$join^STDFS" ], "deprecated": "", "description": "Trailing slash is stripped before extracting the last segment.", "source": { "file": "src/STDFS.m", "line": 74 } }, "dirname": { "form": "extrinsic", "signature": "$$dirname^STDFS(path)", "synopsis": "Return the parent path (everything but the last component).", "params": [ { "name": "path", "type": "path", "doc": "POSIX path" } ], "returns": { "type": "path", "doc": "parent path; \".\" for no-slash input; \"/\" for root" }, "raises": [], "raised_in_body": [], "examples": [ "write $$dirname^STDFS(\"/etc/hosts\") ; \"/etc\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$basename^STDFS", "$$join^STDFS" ], "deprecated": "", "description": "Trailing slashes are normalised first (\"/foo/bar/\" → \"/foo\").", "source": { "file": "src/STDFS.m", "line": 91 } }, "join": { "form": "extrinsic", "signature": "$$join^STDFS(left, right)", "synopsis": "POSIX path join: absolute right replaces left.", "params": [ { "name": "left", "type": "path", "doc": "left operand" }, { "name": "right", "type": "path", "doc": "right operand (absolute right wins)" } ], "returns": { "type": "path", "doc": "joined path" }, "raises": [], "raised_in_body": [], "examples": [ "write $$join^STDFS(\"/a\",\"b\") ; \"/a/b\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$dirname^STDFS", "$$basename^STDFS" ], "deprecated": "", "description": "Empty operand drops out. Trailing slash on left is collapsed.", "source": { "file": "src/STDFS.m", "line": 110 } }, "exists": { "form": "procedure", "signature": "do exists^STDFS(path)", "synopsis": "Return 1 iff path exists; else 0.", "params": [ { "name": "path", "type": "path", "doc": "filesystem path" } ], "returns": { "type": "bool", "doc": "1 iff openable; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$exists^STDFS(\"/etc/hosts\") ; 1" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$size^STDFS", "$$readFile^STDFS" ], "deprecated": "", "description": "Probes via OPEN with timeout=0 inside an $ETRAP — succeeds iff\nthe path is openable. Avoids $ZSEARCH's per-process cache, so\na path created and removed inside one M process round-trips\ncorrectly.", "source": { "file": "src/STDFS.m", "line": 127 } }, "size": { "form": "extrinsic", "signature": "$$size^STDFS(path)", "synopsis": "Return size of path in bytes; -1 if missing or unreadable.", "params": [ { "name": "path", "type": "path", "doc": "filesystem path" } ], "returns": { "type": "int", "doc": "byte count; -1 if missing or unreadable" }, "raises": [], "raised_in_body": [], "examples": [ "write $$size^STDFS(path) ; 4096" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$exists^STDFS", "$$readBytes^STDFS" ], "deprecated": "", "description": "Implemented via OPEN/READ-loop tally — does not depend on a stat\ncallout. Acceptable for routine-sized files; for multi-MB paths\nprefer the future $ZF→stat backend.", "source": { "file": "src/STDFS.m", "line": 150 } }, "readFile": { "form": "extrinsic", "signature": "$$readFile^STDFS(path)", "synopsis": "Return file content as a string (lines joined by $C(10)).", "params": [ { "name": "path", "type": "path", "doc": "filesystem path" } ], "returns": { "type": "string", "doc": "file content; lines LF-separated, trailing LF dropped" }, "raises": [ { "code": "U-STDFS-OPEN-FAIL", "doc": "path is missing or unreadable" } ], "raised_in_body": [ "U-STDFS-OPEN-FAIL" ], "examples": [ "set body=$$readFile^STDFS(\"/etc/hosts\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$writeFile^STDFS", "$$readBytes^STDFS", "do readLines^STDFS" ], "deprecated": "", "description": "Trailing CR on each line is dropped (CRLF normalisation).\nA trailing LF is normalised away (round-trips with writeFile).", "source": { "file": "src/STDFS.m", "line": 176 } }, "writeFile": { "form": "procedure", "signature": "do writeFile^STDFS(path, data)", "synopsis": "Write data to path (overwrite if exists).", "params": [ { "name": "path", "type": "path", "doc": "filesystem path; truncated if exists" }, { "name": "data", "type": "string", "doc": "text content (lines may be LF-separated)" } ], "returns": null, "raises": [ { "code": "U-STDFS-OPEN-FAIL", "doc": "could not open `path` for write" } ], "raised_in_body": [ "U-STDFS-OPEN-FAIL" ], "examples": [ "do writeFile^STDFS(\"/tmp/out.txt\",\"hi\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$readFile^STDFS", "do writeBytes^STDFS", "do writeLines^STDFS" ], "deprecated": "", "description": "Empty data creates a zero-byte file.", "source": { "file": "src/STDFS.m", "line": 200 } }, "append": { "form": "procedure", "signature": "do append^STDFS(path, data)", "synopsis": "Append data to path; create the file if missing.", "params": [ { "name": "path", "type": "path", "doc": "filesystem path; created if absent" }, { "name": "data", "type": "string", "doc": "text content" } ], "returns": null, "raises": [ { "code": "U-STDFS-OPEN-FAIL", "doc": "could not open for read or write" } ], "raised_in_body": [], "examples": [ "do append^STDFS(\"/tmp/log\",\"tick\"_$char(10))" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$writeFile^STDFS", "do appendBytes^STDFS" ], "deprecated": "", "description": "Implementation: text-mode read-then-rewrite. For byte-faithful\nappend at EOF use $$appendBytes^STDFS instead.", "source": { "file": "src/STDFS.m", "line": 218 } }, "remove": { "form": "procedure", "signature": "do remove^STDFS(path)", "synopsis": "Delete path; idempotent (no-op if already absent).", "params": [ { "name": "path", "type": "path", "doc": "filesystem path" } ], "returns": null, "raises": [ { "code": "U-STDFS-REMOVE-FAIL", "doc": "open-with-DELETE failed (not the missing-file case)" } ], "raised_in_body": [ "U-STDFS-REMOVE-FAIL" ], "examples": [ "do remove^STDFS(\"/tmp/out.txt\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$exists^STDFS" ], "deprecated": "", "description": "", "source": { "file": "src/STDFS.m", "line": 234 } }, "readLines": { "form": "procedure", "signature": "do readLines^STDFS(path, lines)", "synopsis": "Read path into lines(1..N) (1-indexed; CRLF normalised).", "params": [ { "name": "path", "type": "path", "doc": "filesystem path" }, { "name": "lines", "type": "array", "doc": "by-ref local; killed then populated as lines(1..N)" } ], "returns": null, "raises": [ { "code": "U-STDFS-OPEN-FAIL", "doc": "path is missing or unreadable" } ], "raised_in_body": [ "U-STDFS-OPEN-FAIL" ], "examples": [ "do readLines^STDFS(path,.lines)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$readFile^STDFS", "$$writeLines^STDFS" ], "deprecated": "", "description": "Each line is one M string under lines(i). Empty file → empty array.", "source": { "file": "src/STDFS.m", "line": 246 } }, "writeLines": { "form": "procedure", "signature": "do writeLines^STDFS(path, lines)", "synopsis": "Write lines(1..N) to path, separated and terminated by LF.", "params": [ { "name": "path", "type": "path", "doc": "filesystem path; truncated if exists" }, { "name": "lines", "type": "array", "doc": "by-ref local subscripted as lines(1..N)" } ], "returns": null, "raises": [ { "code": "U-STDFS-OPEN-FAIL", "doc": "could not open `path` for write" } ], "raised_in_body": [ "U-STDFS-OPEN-FAIL" ], "examples": [ "do writeLines^STDFS(path,.lines)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do readLines^STDFS", "$$writeFile^STDFS" ], "deprecated": "", "description": "lines must be 1-indexed and dense (no gaps in $ORDER).", "source": { "file": "src/STDFS.m", "line": 270 } }, "writeBytes": { "form": "procedure", "signature": "do writeBytes^STDFS(path, data)", "synopsis": "Write data to path verbatim — no trailing LF, no transcoding.", "params": [ { "name": "path", "type": "path", "doc": "filesystem path; truncated if exists" }, { "name": "data", "type": "byte-string", "doc": "one M character per byte (0..255)" } ], "returns": null, "raises": [ { "code": "U-STDFS-NOT-WIRED", "doc": "stdfs.so is unavailable" }, { "code": "U-STDFS-OPEN-FAIL", "doc": "open(2) failed" } ], "raised_in_body": [], "examples": [ "do writeBytes^STDFS(\"/tmp/blob.bin\",bytes)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$readBytes^STDFS", "do appendBytes^STDFS", "$$writeFile^STDFS" ], "deprecated": "", "description": "", "source": { "file": "src/STDFS.m", "line": 291 } }, "appendBytes": { "form": "procedure", "signature": "do appendBytes^STDFS(path, data)", "synopsis": "Append data to path via O_APPEND — atomic at EOF, byte-faithful.", "params": [ { "name": "path", "type": "path", "doc": "filesystem path; created if absent" }, { "name": "data", "type": "byte-string", "doc": "one M character per byte" } ], "returns": null, "raises": [ { "code": "U-STDFS-NOT-WIRED", "doc": "stdfs.so is unavailable" }, { "code": "U-STDFS-OPEN-FAIL", "doc": "open(2) failed" } ], "raised_in_body": [], "examples": [ "do appendBytes^STDFS(\"/tmp/blob.bin\",chunk)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "do writeBytes^STDFS", "do append^STDFS" ], "deprecated": "", "description": "", "source": { "file": "src/STDFS.m", "line": 303 } }, "readBytes": { "form": "extrinsic", "signature": "$$readBytes^STDFS(path)", "synopsis": "Return file content as a byte string — no CR/LF normalisation.", "params": [ { "name": "path", "type": "path", "doc": "filesystem path" } ], "returns": { "type": "byte-string", "doc": "file contents byte-for-byte" }, "raises": [ { "code": "U-STDFS-NOT-WIRED", "doc": "stdfs.so is unavailable" }, { "code": "U-STDFS-OPEN-FAIL", "doc": "open(2) failed" }, { "code": "U-STDFS-READ-TRUNCATED", "doc": "file exceeds the 16 MiB buffer cap" } ], "raised_in_body": [ "U-STDFS-NOT-WIRED" ], "examples": [ "set blob=$$readBytes^STDFS(\"/tmp/blob.bin\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$readFile^STDFS", "do writeBytes^STDFS" ], "deprecated": "", "description": "For text I/O with newline-joining and CRLF normalisation,\nprefer $$readFile^STDFS instead.", "source": { "file": "src/STDFS.m", "line": 315 } }, "available": { "form": "extrinsic", "signature": "$$available^STDFS()", "synopsis": "1 iff the stdfs callout is loaded and open(2) is reachable.", "params": [], "returns": { "type": "bool", "doc": "1 iff stdfs.so is loaded; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "if '$$available^STDFS() do warn^MYAPP(\"byte-faithful I/O unavailable\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "do writeBytes^STDFS", "$$readBytes^STDFS" ], "deprecated": "", "description": "Never raises — clears $ECODE on the way out.", "source": { "file": "src/STDFS.m", "line": 332 } } }, "source": { "file": "src/STDFS.m", "line": 1 } }, "STDHEX": { "synopsis": "m-stdlib — RFC-4648 §8 hex encoding (lowercase by default).", "description": "Four public extrinsics:\n $$encode^STDHEX(data) — bytes → lowercase hex (a..f)\n $$encodeu^STDHEX(data) — bytes → uppercase hex (A..F)\n $$decode^STDHEX(text) — hex → bytes (case-insensitive)\n $$valid^STDHEX(text) — predicate: even length, all hex digits\n\nAlgorithm: each input byte splits into two 4-bit nibbles; each\nnibble maps to one of \"0123456789abcdef\" (or the uppercase form\nfor encodeu). decode reverses the process after normalising the\ninput to lowercase via $TRANSLATE.\n\nInput is treated as a string of bytes (one M character per byte —\nvalues 0..255 via $ASCII / $CHAR). Always-byte semantics\nregardless of $ZCHSET arrive with STDCRYPTO in Phase 3.", "errors": [], "labels": { "encode": { "form": "extrinsic", "signature": "$$encode^STDHEX(data)", "synopsis": "Lowercase hex (RFC-4648 §8 default form).", "params": [ { "name": "data", "type": "string", "doc": "byte string to encode (one M char per byte)" } ], "returns": { "type": "string", "doc": "lowercase hex (a..f); \"\" for empty input" }, "raises": [], "raised_in_body": [], "examples": [ "write $$encode^STDHEX(\"foo\") ; \"666f6f\"" ], "since": "v0.0.2", "stable": "stable", "see_also": [ "$$encodeu^STDHEX", "$$decode^STDHEX", "$$valid^STDHEX" ], "deprecated": "", "description": "Returns the empty string for empty input.", "source": { "file": "src/STDHEX.m", "line": 22 } }, "encodeu": { "form": "extrinsic", "signature": "$$encodeu^STDHEX(data)", "synopsis": "Uppercase hex.", "params": [ { "name": "data", "type": "string", "doc": "byte string to encode" } ], "returns": { "type": "string", "doc": "uppercase hex (A..F); \"\" for empty input" }, "raises": [], "raised_in_body": [], "examples": [ "write $$encodeu^STDHEX(\"foo\") ; \"666F6F\"" ], "since": "v0.0.2", "stable": "stable", "see_also": [ "$$encode^STDHEX", "$$decode^STDHEX" ], "deprecated": "", "description": "Returns the empty string for empty input.", "source": { "file": "src/STDHEX.m", "line": 32 } }, "decode": { "form": "extrinsic", "signature": "$$decode^STDHEX(text)", "synopsis": "Case-insensitive hex → bytes.", "params": [ { "name": "text", "type": "string", "doc": "hex text (any case; even or odd length)" } ], "returns": { "type": "string", "doc": "decoded byte string; \"\" for empty input" }, "raises": [], "raised_in_body": [], "examples": [ "write $$decode^STDHEX(\"DeAdBeEf\") ; 4 bytes" ], "since": "v0.0.2", "stable": "stable", "see_also": [ "$$encode^STDHEX", "$$encodeu^STDHEX", "$$valid^STDHEX" ], "deprecated": "", "description": "Tolerates uppercase, lowercase, and mixed-case input.\nOdd-length input drops the trailing nibble silently — call\nvalid() first if strict validation is required.", "source": { "file": "src/STDHEX.m", "line": 42 } }, "valid": { "form": "extrinsic", "signature": "$$valid^STDHEX(text)", "synopsis": "True iff text is well-formed hex (any case).", "params": [ { "name": "text", "type": "string", "doc": "candidate hex text" } ], "returns": { "type": "bool", "doc": "1 iff well-formed; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDHEX(\"DeAdBeEf\") ; 1" ], "since": "v0.0.2", "stable": "stable", "see_also": [ "$$decode^STDHEX" ], "deprecated": "", "description": "Length must be even; every character must be 0-9, a-f, or A-F.\nEmpty string is valid.", "source": { "file": "src/STDHEX.m", "line": 64 } } }, "source": { "file": "src/STDHEX.m", "line": 1 } }, "STDHTTP": { "synopsis": "m-stdlib — HTTP/1.1 client (track H3, target tag v0.4.0).", "description": "m-lint: disable-file=M-MOD-020\nm-lint: disable-file=M-MOD-024\nm-lint: disable-file=M-MOD-036\nm-lint: disable-file=M-MOD-008\nM-MOD-008: dispatchPerform mirrors the 11-argument C-side\nhttp_perform signature; collapsing into an array would require\nflattening on both sides without simplifying anything.\nM-MOD-020: get / post pass `.req` to request as a structured\ninput — request reads req but never writes to it. The\nanalyser's \"pass by value\" suggestion is wrong for array-\nvalued formals (a value-pass would drop subscripts). The\npattern recurs in $$buildRequest($req) too — req is read-\nonly but must be a by-ref formal to receive the subscripted\ntree.\nM-MOD-024 false positives: rc / statusCode / respHeaders /\nrespBody / errMsg are initialised before every XECUTE'd\n$&stdhttp.* call but the analyser cannot follow flow through\nthe XECUTE indirection.\nM-MOD-036 (XECUTE injection) is intentional: the XECUTE\nwrapper is the only way to embed `$&stdhttp.(...)`\nwithout tree-sitter-m tripping on the namespaced $&pkg.fn\nsyntax. Same trick as STDCRYPTO; the XECUTE source is built\nfrom a literal template only.\n\nTwo layers:\n 1. Pure-M wire-format helpers (iteration 1):\n do parseStatusLine^STDHTTP(line, .s)\n do parseHeader^STDHTTP(line, .name, .value)\n do parseResponse^STDHTTP(raw, .resp)\n $$buildRequest^STDHTTP(.req)\n $$formatHeaders^STDHTTP(.headers)\n 2. Network extrinsics via $&stdhttp.* -> libcurl (iter 2):\n $$get^STDHTTP(url, .resp)\n $$post^STDHTTP(url, body, .resp, contentType)\n $$request^STDHTTP(.req, .resp)\n $$available^STDHTTP()\n The .so is loaded on demand. When it is absent these soft-\n fail with resp(\"error\")=\"STDHTTP-NOT-WIRED\" and return 0\n so callers can degrade gracefully. Deployment runbook:\n 1. tools/build-callouts.sh -> so//http.so\n 2. export STDLIB_LIB=\n 3. export ydb_xc_stdhttp=/tools/std_http.xc\n 4. ensure libcurl is on the loader path\n (or run scripts/seed-callouts.sh — does all four)\n\nResponse array shape:\n resp(\"status\") ; numeric status code\n resp(\"reason\") ; reason phrase\n resp(\"version\") ; \"HTTP/1.1\"\n resp(\"header\", lowerName) ; header value (name lowercased)\n resp(\"body\") ; response body bytes\n resp(\"error\") ; \"\" on success\n\nRequest array shape:\n req(\"method\") ; \"GET\" / \"POST\" / ...\n req(\"url\") ; absolute URL\n req(\"header\", name) ; case preserved on the wire\n req(\"body\") ; bytes\n req(\"timeout\") ; seconds; default 30 (iter 2)\n req(\"followRedirects\") ; 0/1; default 1 (iter 2)\n req(\"verifyTls\") ; 0/1; default 1 (iter 2)\n\nHeader lookup on the response side is case-insensitive (keys\nare stored lowercased per RFC 7230 §3.2 — server casing is\nnot semantically significant). On the request side we pass\nthe caller's casing through to the wire for compatibility\nwith finicky middleboxes.\n\nBodies are M strings of bytes (one M character per byte,\nvalues 0..255 via $ASCII / $CHAR). No transcoding; no\nTransfer-Encoding decoding (libcurl handles chunking before\nthe body reaches M in iteration 2).\n\nPure-M throughout in iteration 1 — no $ZF, no $Z* extensions.\nRuns unchanged on YDB and IRIS.", "errors": [], "labels": { "parseStatusLine": { "form": "procedure", "signature": "do parseStatusLine^STDHTTP(line, s)", "synopsis": "Split an HTTP/1.1 status line into version/code/reason.", "params": [ { "name": "line", "type": "string", "doc": "HTTP/1.1 status line (e.g. \"HTTP/1.1 200 OK\")" }, { "name": "s", "type": "array", "doc": "by-ref local; killed then populated with version/code/reason/ok" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do parseStatusLine^STDHTTP(\"HTTP/1.1 200 OK\",.s)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "do parseHeader^STDHTTP", "do parseResponse^STDHTTP" ], "deprecated": "", "description": "Tolerates a missing reason phrase (RFC 7230 §3.1.2). s(\"ok\")=1 if\nparsed cleanly, 0 if malformed.", "source": { "file": "src/STDHTTP.m", "line": 82 } }, "parseHeader": { "form": "procedure", "signature": "do parseHeader^STDHTTP(line, name, value)", "synopsis": "Split \"Name: value\" into (name, value).", "params": [ { "name": "line", "type": "string", "doc": "header line" }, { "name": "name", "type": "string", "doc": "by-ref out; header name (or \"\" if no colon)" }, { "name": "value", "type": "string", "doc": "by-ref out; header value (or \"\" if no colon)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do parseHeader^STDHTTP(\"Content-Type: text/plain\",.n,.v)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "do parseStatusLine^STDHTTP", "do parseResponse^STDHTTP" ], "deprecated": "", "description": "Trims leading SP/HT from value. Splits on the first colon only.", "source": { "file": "src/STDHTTP.m", "line": 106 } }, "parseResponse": { "form": "procedure", "signature": "do parseResponse^STDHTTP(raw, resp)", "synopsis": "Parse a complete HTTP/1.1 response message.", "params": [ { "name": "raw", "type": "byte-string", "doc": "full HTTP/1.1 response (headers + body)" }, { "name": "resp", "type": "array", "doc": "by-ref local; killed then populated (status/reason/version/header/body)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do parseResponse^STDHTTP(rawBytes,.resp)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$buildRequest^STDHTTP", "$$request^STDHTTP" ], "deprecated": "", "description": "Splits raw on the first CRLF-CRLF (or LF-LF) boundary. Header\nkeys are lowercased; multi-value headers join with \", \" (RFC 7230 §3.2.2).", "source": { "file": "src/STDHTTP.m", "line": 126 } }, "buildRequest": { "form": "extrinsic", "signature": "$$buildRequest^STDHTTP(req)", "synopsis": "Assemble an HTTP/1.1 request message from req array.", "params": [ { "name": "req", "type": "array", "doc": "by-ref local with method/url/header/body subscripts" } ], "returns": { "type": "byte-string", "doc": "full wire-format request (line + headers + CRLF + body)" }, "raises": [], "raised_in_body": [], "examples": [ "set req(\"method\")=\"GET\",req(\"url\")=\"http://x.com/a\" write $$buildRequest^STDHTTP(.req)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "do parseResponse^STDHTTP", "$$formatHeaders^STDHTTP" ], "deprecated": "", "description": "Synthesises Host: from the URL when not provided. Adds\nContent-Length: when a body is present and the header is absent.", "source": { "file": "src/STDHTTP.m", "line": 174 } }, "formatHeaders": { "form": "extrinsic", "signature": "$$formatHeaders^STDHTTP(headers)", "synopsis": "Join headers(name)=value into a CRLF-terminated header block.", "params": [ { "name": "headers", "type": "array", "doc": "by-ref local subscripted as headers(name)=value" } ], "returns": { "type": "string", "doc": "CRLF-terminated header block" }, "raises": [], "raised_in_body": [], "examples": [ "set h(\"X\")=\"1\" write $$formatHeaders^STDHTTP(.h)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$buildRequest^STDHTTP" ], "deprecated": "", "description": "Walks $order so output is subscript-sorted (deterministic).\nCaller is responsible for the final blank-line boundary.", "source": { "file": "src/STDHTTP.m", "line": 227 } }, "get": { "form": "extrinsic", "signature": "$$get^STDHTTP(url, resp)", "synopsis": "HTTP GET shortcut. Returns numeric status code, or 0 on error.", "params": [ { "name": "url", "type": "string", "doc": "absolute URL" }, { "name": "resp", "type": "array", "doc": "by-ref local; populated on return" } ], "returns": { "type": "int", "doc": "HTTP status code; 0 on transport / TLS / not-wired error" }, "raises": [], "raised_in_body": [], "examples": [ "set sc=$$get^STDHTTP(\"https://example.com\",.r)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$post^STDHTTP", "$$request^STDHTTP" ], "deprecated": "", "description": "Soft-fails with resp(\"error\")=\"STDHTTP-NOT-WIRED\" if the\nlibcurl callout is unavailable.", "source": { "file": "src/STDHTTP.m", "line": 244 } }, "post": { "form": "extrinsic", "signature": "$$post^STDHTTP(url, body, resp, contentType)", "synopsis": "HTTP POST shortcut. Defaults Content-Type to application/octet-stream.", "params": [ { "name": "url", "type": "string", "doc": "absolute URL" }, { "name": "body", "type": "byte-string", "doc": "request body" }, { "name": "resp", "type": "array", "doc": "by-ref local; populated on return" }, { "name": "contentType", "type": "string", "doc": "Content-Type header (default \"application/octet-stream\")" } ], "returns": { "type": "int", "doc": "HTTP status code; 0 on transport / TLS / not-wired error" }, "raises": [], "raised_in_body": [], "examples": [ "set sc=$$post^STDHTTP(\"https://example.com/api\",\"payload\",.r,\"application/json\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$get^STDHTTP", "$$request^STDHTTP" ], "deprecated": "", "description": "", "source": { "file": "src/STDHTTP.m", "line": 258 } }, "request": { "form": "extrinsic", "signature": "$$request^STDHTTP(req, resp)", "synopsis": "Generic HTTP request. Returns numeric status code, or 0 on error.", "params": [ { "name": "req", "type": "array", "doc": "by-ref local with method/url/header/body/timeout/followRedirects/verifyTls" }, { "name": "resp", "type": "array", "doc": "by-ref local; populated as documented in the routine header" } ], "returns": { "type": "int", "doc": "HTTP status code; 0 on transport / TLS / DNS failure or callout missing" }, "raises": [], "raised_in_body": [], "examples": [ "set req(\"method\")=\"DELETE\",req(\"url\")=\"https://x.com/y\" set sc=$$request^STDHTTP(.req,.r)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$get^STDHTTP", "$$post^STDHTTP", "$$available^STDHTTP" ], "deprecated": "", "description": "4xx/5xx return their status code (the caller decides what to do\nwith non-2xx); 0 means the request did not complete.", "source": { "file": "src/STDHTTP.m", "line": 274 } }, "available": { "form": "extrinsic", "signature": "$$available^STDHTTP()", "synopsis": "1 iff the libcurl callout is loaded and curl_easy_init() works.", "params": [], "returns": { "type": "bool", "doc": "1 iff stdhttp.so is loaded and libcurl resolves" }, "raises": [], "raised_in_body": [], "examples": [ "if '$$available^STDHTTP() do warn^MYAPP(\"HTTP unavailable\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$request^STDHTTP" ], "deprecated": "", "description": "Never raises — clears $ECODE on the way out.", "source": { "file": "src/STDHTTP.m", "line": 312 } } }, "source": { "file": "src/STDHTTP.m", "line": 1 } }, "STDJSON": { "synopsis": "m-stdlib — RFC 8259 JSON parser + serialiser.", "description": "m-lint: disable-file=M-MOD-024\nM-MOD-024 false positives: the linter parses OPEN/CLOSE\ndeviceparams as local reads (`(readonly)`, `(newversion)`,\n`(exception=...)`) and treats `for ... quit:c=\"\"` loops as\nreading the iteration variable before assignment.\n\nPublic API:\n $$parse^STDJSON(text,.root) — populate root, return 1/0\n $$encode^STDJSON(.root) — serialise to JSON text\n $$valid^STDJSON(text) — 1 iff text parses\n $$lastError^STDJSON() — \"line:col: msg\" or \"\"\n $$type^STDJSON(.node) — type label\n $$valueOf^STDJSON(.node) — scalar string\n parseFile^STDJSON(path,.root) — read whole file\n writeFile^STDJSON(path,.node) — write whole file\n\nStorage convention (one M tree node per JSON value):\n node=\"o\" object — children at node(key)\n node=\"a\" array — children at node(i), i=1..n\n node=\"s:VALUE\" string — VALUE is the decoded UTF-8 byte string\n node=\"n:VALUE\" number — VALUE is the canonical numeric string\n node=\"t\" / \"f\" true / false\n node=\"z\" null ('z' avoids colliding with 'n' for number)\n\nParser state lives in a local context array `ctx` passed by ref\nthrough every recursive helper; no global writes during parse.\nThe last error message is stashed at ^STDLIB($job,\"stdjson\",\"err\")\nfor $$lastError.\n\nErrors set $ECODE to one of:\n ,U-STDJSON-PARSE,\n ,U-STDJSON-ENCODE,", "errors": [ "U-STDJSON-PARSE", "U-STDJSON-ENCODE" ], "labels": { "parse": { "form": "extrinsic", "signature": "$$parse^STDJSON(text, root)", "synopsis": "Parse `text` into `root`. Returns 1/0.", "params": [ { "name": "text", "type": "string", "doc": "RFC-8259 JSON document" }, { "name": "root", "type": "array", "doc": "by-ref local; killed before population" } ], "returns": { "type": "bool", "doc": "1 on success; 0 on parse failure" }, "raises": [ { "code": "U-STDJSON-PARSE", "doc": "malformed input" } ], "raised_in_body": [], "examples": [ "do set rc=$$parse^STDJSON(\"[1,2,3]\",.t)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$valid^STDJSON", "$$lastError^STDJSON", "$$encode^STDJSON" ], "deprecated": "", "description": "Kills `root` first. On failure, $$lastError() holds the\n\"line:col: msg\" diagnostic and the partial tree is killed.", "source": { "file": "src/STDJSON.m", "line": 39 } }, "valid": { "form": "extrinsic", "signature": "$$valid^STDJSON(text)", "synopsis": "True iff `text` is conformant RFC-8259 JSON.", "params": [ { "name": "text", "type": "string", "doc": "candidate JSON document" } ], "returns": { "type": "bool", "doc": "1 iff conformant; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDJSON(\"[1,2,3]\") ; 1" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$parse^STDJSON" ], "deprecated": "", "description": "Discards the parsed tree; returns just the validity bit.\nEmpty input is invalid (RFC 8259 §2).", "source": { "file": "src/STDJSON.m", "line": 64 } }, "lastError": { "form": "extrinsic", "signature": "$$lastError^STDJSON()", "synopsis": "Return the message from the most recent failed parse.", "params": [], "returns": { "type": "string", "doc": "\"line:col: msg\" of last failure; \"\" if last call succeeded" }, "raises": [], "raised_in_body": [], "examples": [ "if '$$parse^STDJSON(s,.t) write $$lastError^STDJSON()" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$parse^STDJSON" ], "deprecated": "", "description": "", "source": { "file": "src/STDJSON.m", "line": 76 } }, "type": { "form": "extrinsic", "signature": "$$type^STDJSON(node)", "synopsis": "Return the JSON type label of `node` (or \"\" if undef).", "params": [ { "name": "node", "type": "node", "doc": "by-ref node from a parsed JSON tree" } ], "returns": { "type": "string", "doc": "one of object/array/string/number/true/false/null; \"\" if undef" }, "raises": [], "raised_in_body": [], "examples": [ "write $$type^STDJSON(.t) ; \"array\"" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$valueOf^STDJSON" ], "deprecated": "", "description": "", "source": { "file": "src/STDJSON.m", "line": 84 } }, "valueOf": { "form": "extrinsic", "signature": "$$valueOf^STDJSON(node)", "synopsis": "Return the scalar value for s/n leaves; \"\" otherwise.", "params": [ { "name": "node", "type": "node", "doc": "by-ref node from a parsed JSON tree" } ], "returns": { "type": "string", "doc": "scalar value for s/n leaves; \"\" for containers/literals/undef" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valueOf^STDJSON(.t(\"name\"))" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$type^STDJSON" ], "deprecated": "", "description": "For s, returns the decoded string content; for n, the\ncanonical numeric string as parsed from the source.", "source": { "file": "src/STDJSON.m", "line": 103 } }, "encode": { "form": "extrinsic", "signature": "$$encode^STDJSON(node)", "synopsis": "Serialise `node` to JSON text.", "params": [ { "name": "node", "type": "node", "doc": "by-ref tree to serialise" } ], "returns": { "type": "string", "doc": "RFC-8259-conformant JSON text; \"\" on failure" }, "raises": [ { "code": "U-STDJSON-ENCODE", "doc": "malformed tree (e.g. gappy array)" } ], "raised_in_body": [], "examples": [ "write $$encode^STDJSON(.t)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$parse^STDJSON", "do writeFile^STDJSON" ], "deprecated": "", "description": "Object members emit in M collation order (numeric subscripts\nfirst, then string subscripts in byte order). A gappy array\n(e.g. node(1) and node(3) without node(2)) raises U-STDJSON-ENCODE\nrather than inventing a `null`.", "source": { "file": "src/STDJSON.m", "line": 118 } }, "parseFile": { "form": "procedure", "signature": "do parseFile^STDJSON(path, root)", "synopsis": "Stream-read `path`, parse into `root`.", "params": [ { "name": "path", "type": "path", "doc": "filesystem path to a JSON file" }, { "name": "root", "type": "array", "doc": "by-ref local; killed before population" } ], "returns": null, "raises": [ { "code": "U-STDJSON-PARSE", "doc": "open failure or malformed input" } ], "raised_in_body": [ "U-STDJSON-PARSE" ], "examples": [ "do parseFile^STDJSON(\"/etc/cfg.json\",.t)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$parse^STDJSON", "do writeFile^STDJSON" ], "deprecated": "", "description": "Reads the whole file into memory then defers to parse().", "source": { "file": "src/STDJSON.m", "line": 137 } }, "writeFile": { "form": "procedure", "signature": "do writeFile^STDJSON(path, node)", "synopsis": "Serialise `node` and write to `path`.", "params": [ { "name": "path", "type": "path", "doc": "filesystem path; truncated if exists" }, { "name": "node", "type": "node", "doc": "by-ref tree to serialise" } ], "returns": null, "raises": [ { "code": "U-STDJSON-ENCODE", "doc": "malformed tree or open failure" } ], "raised_in_body": [ "U-STDJSON-ENCODE" ], "examples": [ "do writeFile^STDJSON(\"/tmp/out.json\",.t)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$encode^STDJSON", "do parseFile^STDJSON" ], "deprecated": "", "description": "", "source": { "file": "src/STDJSON.m", "line": 160 } } }, "source": { "file": "src/STDJSON.m", "line": 1 } }, "STDLOG": { "synopsis": "m-stdlib — structured key=value logger (v0.0.4).", "description": "m-lint: disable-file=M-MOD-024\nM-MOD-024 false positives: the linter parses YDB OPEN deviceparams\n(e.g. APPEND) in writeLine() as local-variable reads. Same cause as\nSTDCSV's file-wide disable; tracked in TOOLCHAIN-FINDINGS.md.\n\nPublic entry points:\n DEBUG^STDLOG(event,k1,v1,...,k5,v5) — up to 5 kv pairs\n INFO^STDLOG(event,...)\n WARN^STDLOG(event,...)\n ERROR^STDLOG(event,...)\n FATAL^STDLOG(event,...)\n LEVEL^STDLOG(threshold) — \"DEBUG\"|\"INFO\"|\"WARN\"|\"ERROR\"|\"FATAL\"\n SINK^STDLOG(target) — \"stderr\"|\"stdout\"|\"global\"|\"global:^GREF\"\n FORMAT^STDLOG(name) — \"kv\" (default) | \"json\"\n\nOutput line format (kv, default):\n level= event= k=v k=v ...\n\nOutput line format (json):\n {\"ts\":\"\",\"level\":\"\",\"event\":\"\",\"k\":\"v\",...}\n All values are emitted as JSON strings (preserves the kv contract\n that values are opaque text). Built via $$encode^STDJSON, so the\n line is byte-exactly conformant RFC 8259.\n\nValue escaping (kv): a value with no space, '=', '\"', or '\\' is\nemitted raw. Otherwise it is wrapped in double quotes, with embedded\n'\\' doubled to '\\\\' and embedded '\"' escaped to '\\\"'.\n\nDefaults: threshold=INFO, sink=stderr, format=kv. Configuration is\nprocess-local (held under ^STDLIB($job,\"stdlog\",\"...\")).\n\nErrors set $ECODE to one of:\n ,U-STDLOG-INVALID-LEVEL,\n ,U-STDLOG-INVALID-SINK,\n ,U-STDLOG-INVALID-FORMAT,\n\nTimestamp source: $$now^STDDATE() (millisecond-precision ISO-8601\nUTC ending in Z). v0.0.4 shipped an inline helper; track L4b\n(this commit) bumps to STDDATE now that v0.0.5 is in.", "errors": [ "U-STDLOG-INVALID-LEVEL", "U-STDLOG-INVALID-SINK", "U-STDLOG-INVALID-FORMAT" ], "labels": { "DEBUG": { "form": "procedure", "signature": "do DEBUG^STDLOG(event, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5)", "synopsis": "Emit a DEBUG line.", "params": [ { "name": "event", "type": "string", "doc": "short event name (one token, no spaces ideally)" }, { "name": "k1", "type": "string", "doc": "key 1 (optional)" }, { "name": "v1", "type": "string", "doc": "value 1 (optional)" }, { "name": "k2", "type": "string", "doc": "key 2 (optional)" }, { "name": "v2", "type": "string", "doc": "value 2 (optional)" }, { "name": "k3", "type": "string", "doc": "key 3 (optional)" }, { "name": "v3", "type": "string", "doc": "value 3 (optional)" }, { "name": "k4", "type": "string", "doc": "key 4 (optional)" }, { "name": "v4", "type": "string", "doc": "value 4 (optional)" }, { "name": "k5", "type": "string", "doc": "key 5 (optional)" }, { "name": "v5", "type": "string", "doc": "value 5 (optional)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do DEBUG^STDLOG(\"cache_miss\",\"key\",\"u:42\")" ], "since": "v0.0.4", "stable": "stable", "see_also": [ "do INFO^STDLOG", "do WARN^STDLOG", "do ERROR^STDLOG", "do FATAL^STDLOG" ], "deprecated": "", "description": "Suppressed when the configured threshold is above DEBUG.", "source": { "file": "src/STDLOG.m", "line": 46 } }, "INFO": { "form": "procedure", "signature": "do INFO^STDLOG(event, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5)", "synopsis": "Emit an INFO line (default level).", "params": [ { "name": "event", "type": "string", "doc": "short event name" }, { "name": "k1", "type": "string", "doc": "key 1 (optional)" }, { "name": "v1", "type": "string", "doc": "value 1 (optional)" }, { "name": "k2", "type": "string", "doc": "key 2 (optional)" }, { "name": "v2", "type": "string", "doc": "value 2 (optional)" }, { "name": "k3", "type": "string", "doc": "key 3 (optional)" }, { "name": "v3", "type": "string", "doc": "value 3 (optional)" }, { "name": "k4", "type": "string", "doc": "key 4 (optional)" }, { "name": "v4", "type": "string", "doc": "value 4 (optional)" }, { "name": "k5", "type": "string", "doc": "key 5 (optional)" }, { "name": "v5", "type": "string", "doc": "value 5 (optional)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do INFO^STDLOG(\"login\",\"user\",\"alice\",\"ip\",\"1.2.3.4\")" ], "since": "v0.0.4", "stable": "stable", "see_also": [ "do DEBUG^STDLOG", "do WARN^STDLOG", "do ERROR^STDLOG", "do FATAL^STDLOG" ], "deprecated": "", "description": "Emitted when threshold is INFO or below (DEBUG). The default level.", "source": { "file": "src/STDLOG.m", "line": 67 } }, "WARN": { "form": "procedure", "signature": "do WARN^STDLOG(event, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5)", "synopsis": "Emit a WARN line.", "params": [ { "name": "event", "type": "string", "doc": "short event name" }, { "name": "k1", "type": "string", "doc": "key 1 (optional)" }, { "name": "v1", "type": "string", "doc": "value 1 (optional)" }, { "name": "k2", "type": "string", "doc": "key 2 (optional)" }, { "name": "v2", "type": "string", "doc": "value 2 (optional)" }, { "name": "k3", "type": "string", "doc": "key 3 (optional)" }, { "name": "v3", "type": "string", "doc": "value 3 (optional)" }, { "name": "k4", "type": "string", "doc": "key 4 (optional)" }, { "name": "v4", "type": "string", "doc": "value 4 (optional)" }, { "name": "k5", "type": "string", "doc": "key 5 (optional)" }, { "name": "v5", "type": "string", "doc": "value 5 (optional)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do WARN^STDLOG(\"retry\",\"attempt\",\"3\")" ], "since": "v0.0.4", "stable": "stable", "see_also": [ "do INFO^STDLOG", "do ERROR^STDLOG" ], "deprecated": "", "description": "Suppressed when threshold is ERROR or higher.", "source": { "file": "src/STDLOG.m", "line": 88 } }, "ERROR": { "form": "procedure", "signature": "do ERROR^STDLOG(event, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5)", "synopsis": "Emit an ERROR line.", "params": [ { "name": "event", "type": "string", "doc": "short event name" }, { "name": "k1", "type": "string", "doc": "key 1 (optional)" }, { "name": "v1", "type": "string", "doc": "value 1 (optional)" }, { "name": "k2", "type": "string", "doc": "key 2 (optional)" }, { "name": "v2", "type": "string", "doc": "value 2 (optional)" }, { "name": "k3", "type": "string", "doc": "key 3 (optional)" }, { "name": "v3", "type": "string", "doc": "value 3 (optional)" }, { "name": "k4", "type": "string", "doc": "key 4 (optional)" }, { "name": "v4", "type": "string", "doc": "value 4 (optional)" }, { "name": "k5", "type": "string", "doc": "key 5 (optional)" }, { "name": "v5", "type": "string", "doc": "value 5 (optional)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do ERROR^STDLOG(\"db_failed\",\"sqlcode\",\"-803\")" ], "since": "v0.0.4", "stable": "stable", "see_also": [ "do WARN^STDLOG", "do FATAL^STDLOG" ], "deprecated": "", "description": "Suppressed when threshold is FATAL.", "source": { "file": "src/STDLOG.m", "line": 109 } }, "FATAL": { "form": "procedure", "signature": "do FATAL^STDLOG(event, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5)", "synopsis": "Emit a FATAL line.", "params": [ { "name": "event", "type": "string", "doc": "short event name" }, { "name": "k1", "type": "string", "doc": "key 1 (optional)" }, { "name": "v1", "type": "string", "doc": "value 1 (optional)" }, { "name": "k2", "type": "string", "doc": "key 2 (optional)" }, { "name": "v2", "type": "string", "doc": "value 2 (optional)" }, { "name": "k3", "type": "string", "doc": "key 3 (optional)" }, { "name": "v3", "type": "string", "doc": "value 3 (optional)" }, { "name": "k4", "type": "string", "doc": "key 4 (optional)" }, { "name": "v4", "type": "string", "doc": "value 4 (optional)" }, { "name": "k5", "type": "string", "doc": "key 5 (optional)" }, { "name": "v5", "type": "string", "doc": "value 5 (optional)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do FATAL^STDLOG(\"crash\",\"reason\",\"oom\")" ], "since": "v0.0.4", "stable": "stable", "see_also": [ "do ERROR^STDLOG" ], "deprecated": "", "description": "Always emitted (threshold cannot be set above FATAL).", "source": { "file": "src/STDLOG.m", "line": 130 } }, "LEVEL": { "form": "procedure", "signature": "do LEVEL^STDLOG(threshold)", "synopsis": "Set the runtime threshold. Levels at or above pass.", "params": [ { "name": "threshold", "type": "string", "doc": "one of \"DEBUG\", \"INFO\", \"WARN\", \"ERROR\", \"FATAL\"" } ], "returns": null, "raises": [ { "code": "U-STDLOG-INVALID-LEVEL", "doc": "`threshold` is not one of the five names" } ], "raised_in_body": [ "U-STDLOG-INVALID-LEVEL" ], "examples": [ "do LEVEL^STDLOG(\"WARN\") ; suppress DEBUG and INFO" ], "since": "v0.0.4", "stable": "stable", "see_also": [ "do SINK^STDLOG", "do FORMAT^STDLOG" ], "deprecated": "", "description": "Numeric ranks: DEBUG=10, INFO=20, WARN=30, ERROR=40, FATAL=50.\nAn emitter at rank n is suppressed when threshold > n.", "source": { "file": "src/STDLOG.m", "line": 151 } }, "SINK": { "form": "procedure", "signature": "do SINK^STDLOG(target)", "synopsis": "Configure where log lines go.", "params": [ { "name": "target", "type": "string", "doc": "one of \"stderr\", \"stdout\", \"global\", or \"global:^GREF\"" } ], "returns": null, "raises": [ { "code": "U-STDLOG-INVALID-SINK", "doc": "`target` is not one of the documented forms" } ], "raised_in_body": [ "U-STDLOG-INVALID-SINK" ], "examples": [ "do SINK^STDLOG(\"global:^MYLOG\") ; write to ^MYLOG(N)" ], "since": "v0.0.4", "stable": "stable", "see_also": [ "do LEVEL^STDLOG", "do FORMAT^STDLOG" ], "deprecated": "", "description": "\"stderr\" / \"stdout\" — write to /dev/stderr or current device.\n\"global\" — write to ^STDLIB($job,\"stdlog\",\"buf\",N).\n\"global:^FOO\" — write to ^FOO(N) using $increment for N.", "source": { "file": "src/STDLOG.m", "line": 166 } }, "FORMAT": { "form": "procedure", "signature": "do FORMAT^STDLOG(name)", "synopsis": "Select line-rendering format. \"kv\" (default) or \"json\".", "params": [ { "name": "name", "type": "string", "doc": "\"kv\" (default) or \"json\"" } ], "returns": null, "raises": [ { "code": "U-STDLOG-INVALID-FORMAT", "doc": "`name` is not \"kv\" or \"json\"" } ], "raised_in_body": [ "U-STDLOG-INVALID-FORMAT" ], "examples": [ "do FORMAT^STDLOG(\"json\") ; emit JSON-line output" ], "since": "v0.0.4", "stable": "stable", "see_also": [ "do LEVEL^STDLOG", "do SINK^STDLOG", "$$encode^STDJSON" ], "deprecated": "", "description": "kv format: level= event= k=v k=v ...\njson format: {\"ts\":...,\"level\":...,\"event\":...,\"k\":\"v\",...}\nJSON output uses $$encode^STDJSON internally so every line\nround-trips through $$parse^STDJSON without loss. All kv values\nrender as JSON strings (matches the kv-line semantic that\nvalues are opaque text); callers wanting typed JSON should\nbuild a tree directly and call $$encode^STDJSON themselves.", "source": { "file": "src/STDLOG.m", "line": 184 } } }, "source": { "file": "src/STDLOG.m", "line": 1 } }, "STDMATH": { "synopsis": "m-stdlib — Numeric helpers (clamp / min / max / sum / count / mean over arrays).", "description": "Public extrinsics:\n $$clamp^STDMATH(x,lo,hi) — clamp scalar x into [lo, hi]\n $$min^STDMATH(.arr) — smallest value in arr (1st-level $ORDER walk)\n $$max^STDMATH(.arr) — largest value in arr\n $$sum^STDMATH(.arr) — sum of arr's values (unary-+ coercion)\n $$count^STDMATH(.arr) — number of $ORDER-visible values at depth 1\n $$mean^STDMATH(.arr) — sum / count; \"\" on empty (no /0)\n\nAll array-walking entry points operate on the FIRST subscript level\nonly (the canonical \"1-D vector\" shape). Subscripts are walked via\n$ORDER so any subscript shape works (1-indexed, string-keyed, sparse\ninteger keys, etc.). Multi-dim arrays read only their first level\n— descend yourself if you want a deeper walk.\n\nEmpty-array convention:\n sum, count → 0 (additive identity)\n min, max, mean → \"\" (no value to report; mean avoids /0)\n\nNon-numeric values are coerced via M's standard unary-`+` rule:\n +\"abc\"=0, +\"3.14\"=3.14, +\"\"=0, +\"42-extra\"=42. This matches\n how every other M arithmetic primitive treats string operands.\n\nPure-M throughout — no $Z* extensions, no STDREGEX dep. Runs\nunchanged on YDB and IRIS.", "errors": [], "labels": { "clamp": { "form": "extrinsic", "signature": "$$clamp^STDMATH(x, lo, hi)", "synopsis": "Clamp x into [lo, hi]. Returns lo if xhi, else x.", "params": [ { "name": "x", "type": "num", "doc": "value to clamp" }, { "name": "lo", "type": "num", "doc": "lower bound" }, { "name": "hi", "type": "num", "doc": "upper bound (caller must ensure lo <= hi)" } ], "returns": { "type": "num", "doc": "clamped value" }, "raises": [], "raised_in_body": [], "examples": [ "write $$clamp^STDMATH(99,0,10) ; 10" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$min^STDMATH", "$$max^STDMATH" ], "deprecated": "", "description": "", "source": { "file": "src/STDMATH.m", "line": 32 } }, "min": { "form": "extrinsic", "signature": "$$min^STDMATH(arr)", "synopsis": "Smallest value in arr (1st-level $ORDER walk). \"\" if empty.", "params": [ { "name": "arr", "type": "array", "doc": "by-ref local; values walked at depth 1" } ], "returns": { "type": "num", "doc": "smallest value; \"\" if empty" }, "raises": [], "raised_in_body": [], "examples": [ "new a set a(1)=3,a(2)=1,a(3)=4 write $$min^STDMATH(.a) ; 1" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$max^STDMATH", "$$mean^STDMATH" ], "deprecated": "", "description": "", "source": { "file": "src/STDMATH.m", "line": 47 } }, "max": { "form": "extrinsic", "signature": "$$max^STDMATH(arr)", "synopsis": "Largest value in arr. \"\" if empty.", "params": [ { "name": "arr", "type": "array", "doc": "by-ref local; values walked at depth 1" } ], "returns": { "type": "num", "doc": "largest value; \"\" if empty" }, "raises": [], "raised_in_body": [], "examples": [ "new a set a(1)=3,a(2)=9,a(3)=4 write $$max^STDMATH(.a) ; 9" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$min^STDMATH", "$$mean^STDMATH" ], "deprecated": "", "description": "", "source": { "file": "src/STDMATH.m", "line": 62 } }, "sum": { "form": "extrinsic", "signature": "$$sum^STDMATH(arr)", "synopsis": "Sum of arr's values (unary-+ coercion). 0 if empty.", "params": [ { "name": "arr", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "num", "doc": "sum of values; 0 if empty" }, "raises": [], "raised_in_body": [], "examples": [ "new a set a(1)=10,a(2)=-3,a(3)=5 write $$sum^STDMATH(.a) ; 12" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$mean^STDMATH", "$$count^STDMATH" ], "deprecated": "", "description": "", "source": { "file": "src/STDMATH.m", "line": 77 } }, "count": { "form": "extrinsic", "signature": "$$count^STDMATH(arr)", "synopsis": "Number of $ORDER-visible values at depth 1. 0 if empty.", "params": [ { "name": "arr", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "int", "doc": "number of values at depth 1" }, "raises": [], "raised_in_body": [], "examples": [ "new a set a(1)=10,a(\"k\")=20 write $$count^STDMATH(.a) ; 2" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$sum^STDMATH" ], "deprecated": "", "description": "", "source": { "file": "src/STDMATH.m", "line": 89 } }, "mean": { "form": "extrinsic", "signature": "$$mean^STDMATH(arr)", "synopsis": "Arithmetic mean = sum / count. \"\" if arr is empty (no /0).", "params": [ { "name": "arr", "type": "array", "doc": "by-ref local" } ], "returns": { "type": "num", "doc": "arithmetic mean; \"\" if arr is empty" }, "raises": [], "raised_in_body": [], "examples": [ "new a set a(1)=2,a(2)=4,a(3)=6 write $$mean^STDMATH(.a) ; 4" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$sum^STDMATH", "$$count^STDMATH" ], "deprecated": "", "description": "", "source": { "file": "src/STDMATH.m", "line": 101 } } }, "source": { "file": "src/STDMATH.m", "line": 1 } }, "STDMOCK": { "synopsis": "m-stdlib — opt-in test-time call interception (mock registry).", "description": "Three procedure-form labels:\n register^STDMOCK(target,replacement) — record a redirect\n unregister^STDMOCK(target) — remove one redirect\n clear^STDMOCK — wipe every registration\n\nThree extrinsics:\n $$resolve^STDMOCK(target) — replacement, or target\n $$called^STDMOCK(target) — call count since clear\n $$args^STDMOCK(target,n,i) — arg i of call n\n\nAnd one procedure that exercises the redirect + records the call:\n invoke^STDMOCK(target,.args) — record + call resolve(target)\n\nMechanism — opt-in at the call site. Production code that wants\nto be mockable calls invoke^STDMOCK(\"LBL^ROU\",.args) instead of\ndo ^LBL^ROU(.args), or uses do @$$resolve^STDMOCK(\"LBL^ROU\")(.args)\nfor the same effect without recording. Tests register a stub and\nthe indirection picks it up.\n\nStorage — process-scoped (no cross-process leakage):\n ^STDLIB($job,\"stdmock\",\"reg\",target) = replacement\n ^STDLIB($job,\"stdmock\",\"cnt\",target) = call count\n ^STDLIB($job,\"stdmock\",\"arg\",target,n,i) = arg i of call n\n\nNote on transactions: the registry lives in a transactional\nglobal, so a TROLLBACK reverts mock registrations. v0.1.2 does\nnot provide rollback-immune mocks. The m-cli runner clears the\nregistry between tests so cross-test leakage is also a non-issue.", "errors": [], "labels": { "register": { "form": "procedure", "signature": "do register^STDMOCK(target, replacement)", "synopsis": "Record a target -> replacement redirect.", "params": [ { "name": "target", "type": "string", "doc": "M call-site to intercept (e.g. \"EN^DIE\")" }, { "name": "replacement", "type": "string", "doc": "M call-site to invoke instead" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do register^STDMOCK(\"EN^DIE\",\"stub^DIETST\")" ], "since": "v0.1.2", "stable": "stable", "see_also": [ "do unregister^STDMOCK", "$$resolve^STDMOCK", "do invoke^STDMOCK" ], "deprecated": "", "description": "Overwrites any prior registration for target.", "source": { "file": "src/STDMOCK.m", "line": 36 } }, "unregister": { "form": "procedure", "signature": "do unregister^STDMOCK(target)", "synopsis": "Remove one redirect (idempotent).", "params": [ { "name": "target", "type": "string", "doc": "M call-site previously register()ed" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do unregister^STDMOCK(\"EN^DIE\")" ], "since": "v0.1.2", "stable": "stable", "see_also": [ "do register^STDMOCK", "do clear^STDMOCK" ], "deprecated": "", "description": "Drops the call count and recorded args for that target so a\nsubsequent re-register starts fresh.", "source": { "file": "src/STDMOCK.m", "line": 47 } }, "clear": { "form": "procedure", "signature": "do clear^STDMOCK()", "synopsis": "Remove every redirect, counter, and recorded args list.", "params": [], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do clear^STDMOCK" ], "since": "v0.1.2", "stable": "stable", "see_also": [ "do unregister^STDMOCK" ], "deprecated": "", "description": "Idempotent. The m-cli test runner calls this between tests\nso registrations don't leak across cases.", "source": { "file": "src/STDMOCK.m", "line": 60 } }, "resolve": { "form": "extrinsic", "signature": "$$resolve^STDMOCK(target)", "synopsis": "Return the replacement if registered, else target itself.", "params": [ { "name": "target", "type": "string", "doc": "M call-site" } ], "returns": { "type": "string", "doc": "registered replacement; target itself if no registration" }, "raises": [], "raised_in_body": [], "examples": [ "write $$resolve^STDMOCK(\"EN^DIE\") ; e.g. \"stub^DIETST\" after `do register^STDMOCK`", "write $$resolve^STDMOCK(\"noSuchTarget^XYZ\") ; \"noSuchTarget^XYZ\"" ], "since": "v0.1.2", "stable": "stable", "see_also": [ "do register^STDMOCK", "do invoke^STDMOCK" ], "deprecated": "", "description": "Single-level lookup; chains are NOT followed.", "source": { "file": "src/STDMOCK.m", "line": 70 } }, "invoke": { "form": "procedure", "signature": "do invoke^STDMOCK(target, args)", "synopsis": "Record this call + invoke resolve(target).", "params": [ { "name": "target", "type": "string", "doc": "M call-site" }, { "name": "args", "type": "array", "doc": "by-ref local; passed verbatim to the resolved target" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "new a set a(1)=42 do invoke^STDMOCK(\"LBL^ROU\",.a)" ], "since": "v0.1.2", "stable": "stable", "see_also": [ "$$resolve^STDMOCK", "$$called^STDMOCK", "$$args^STDMOCK" ], "deprecated": "", "description": "Records the call (count + arg copy) before calling.", "source": { "file": "src/STDMOCK.m", "line": 81 } }, "called": { "form": "extrinsic", "signature": "$$called^STDMOCK(target)", "synopsis": "Number of invocations for target since clear / unregister.", "params": [ { "name": "target", "type": "string", "doc": "M call-site" } ], "returns": { "type": "int", "doc": "invocation count; 0 if never invoked" }, "raises": [], "raised_in_body": [], "examples": [ "write $$called^STDMOCK(\"EN^DIE\") ; e.g. 3, after `do invoke^STDMOCK` calls", "write $$called^STDMOCK(\"noSuchTarget^XYZ\") ; 0" ], "since": "v0.1.2", "stable": "stable", "see_also": [ "do invoke^STDMOCK", "$$args^STDMOCK" ], "deprecated": "", "description": "", "source": { "file": "src/STDMOCK.m", "line": 99 } }, "args": { "form": "extrinsic", "signature": "$$args^STDMOCK(target, n, i)", "synopsis": "Return arg i of call n for target; \"\" if absent.", "params": [ { "name": "target", "type": "string", "doc": "M call-site" }, { "name": "n", "type": "int", "doc": "1-based call number" }, { "name": "i", "type": "int", "doc": "1-based argument position" } ], "returns": { "type": "string", "doc": "recorded arg value; \"\" if absent" }, "raises": [], "raised_in_body": [], "examples": [ "$$args^STDMOCK(\"LBL\",1,2) — second arg of first call." ], "since": "v0.1.2", "stable": "stable", "see_also": [ "$$called^STDMOCK", "do invoke^STDMOCK" ], "deprecated": "", "description": "", "source": { "file": "src/STDMOCK.m", "line": 109 } } }, "source": { "file": "src/STDMOCK.m", "line": 1 } }, "STDOS": { "synopsis": "m-stdlib — Process / env / cmdline helpers (YDB-only v1).", "description": "m-lint: disable-file=M-MOD-020\nm-lint: disable-file=M-MOD-021\nm-lint: disable-file=M-MOD-022\nm-lint: disable-file=M-MOD-023\nM-MOD-020: splitArgs writes to its by-ref second formal `args` but\nnot to `s`; the by-ref analyzer flags every caller as a candidate\nwithout seeing the `args` write inside splitArgs.\nM-MOD-021/022/023: STDOS is a thin layer over $ZTRNLNM / $J /\n$ZCMDLINE / ZHALT — all YDB extensions to the M standard. v0.2.x\nships YDB-only by design; the IRIS arm lands when STDOS gets its\n$CLASSMETHOD-driven helpers (T15, post-v0.3.0).\n\nPublic extrinsics:\n $$env^STDOS(name) — environment variable lookup (\"\" if unset)\n $$pid^STDOS() — current process ID (integer)\n $$cmdline^STDOS() — raw $ZCMDLINE\n $$splitArgs^STDOS(s,.args) — populate args(1..N), return N\n $$argc^STDOS() — count of $ZCMDLINE arguments\n $$arg^STDOS(i) — i-th $ZCMDLINE arg (1-indexed; \"\" out of bounds)\n argv^STDOS(.args) — populate args(1..N) from $ZCMDLINE\n $$cwd^STDOS() — current working directory (from $PWD)\n $$user^STDOS() — current username (from $USER)\n $$hostname^STDOS() — host name (from $HOSTNAME; may be \"\")\n exit^STDOS(rc) — terminate the process with exit code rc\n\nArgument splitting in v1 is whitespace-only — runs of spaces are\ncollapsed to a single separator and leading / trailing whitespace\nis dropped. Quote handling (single and double quotes preserving\nembedded spaces) lands in v0.2.y when STDARGS' quote-aware\ntokeniser is back-ported. For now, callers that need quote-aware\nparsing should pre-tokenise via the shell or use STDARGS directly.", "errors": [], "labels": { "env": { "form": "extrinsic", "signature": "$$env^STDOS(name)", "synopsis": "Return the value of environment variable `name`, or \"\" if unset.", "params": [ { "name": "name", "type": "string", "doc": "environment variable name" } ], "returns": { "type": "string", "doc": "value, or \"\" if `name` is empty or unset" }, "raises": [], "raised_in_body": [], "examples": [ "write $$env^STDOS(\"HOME\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$user^STDOS", "$$cwd^STDOS", "$$hostname^STDOS" ], "deprecated": "", "description": "", "source": { "file": "src/STDOS.m", "line": 38 } }, "pid": { "form": "extrinsic", "signature": "$$pid^STDOS()", "synopsis": "Return the current process ID as an integer.", "params": [], "returns": { "type": "int", "doc": "process ID" }, "raises": [], "raised_in_body": [], "examples": [ "write $$pid^STDOS() ; e.g. 12345" ], "since": "v0.3.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "Equivalent to YDB's $J / $JOB special variable.", "source": { "file": "src/STDOS.m", "line": 48 } }, "cmdline": { "form": "extrinsic", "signature": "$$cmdline^STDOS()", "synopsis": "Return the raw $ZCMDLINE string.", "params": [], "returns": { "type": "string", "doc": "whole command-line tail (post-`-run ENTRY`), un-tokenised" }, "raises": [], "raised_in_body": [], "examples": [ "write $$cmdline^STDOS()" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$argc^STDOS", "$$arg^STDOS", "do argv^STDOS", "$$splitArgs^STDOS" ], "deprecated": "", "description": "", "source": { "file": "src/STDOS.m", "line": 56 } }, "splitArgs": { "form": "extrinsic", "signature": "$$splitArgs^STDOS(s, args)", "synopsis": "Tokenise `s` on whitespace; populate args(1..N); return N.", "params": [ { "name": "s", "type": "string", "doc": "input string" }, { "name": "args", "type": "array", "doc": "by-ref local; killed then populated as args(1..N)" } ], "returns": { "type": "int", "doc": "number of tokens" }, "raises": [], "raised_in_body": [], "examples": [ "set n=$$splitArgs^STDOS(\"a b c\",.args) ; args(1..3)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do argv^STDOS", "$$cmdline^STDOS" ], "deprecated": "", "description": "Runs of spaces collapse; leading and trailing whitespace are\ndropped. Tab and LF are NOT treated as separators in v1\n(cmdline tails rarely contain them). Empty input yields 0.", "source": { "file": "src/STDOS.m", "line": 64 } }, "argc": { "form": "extrinsic", "signature": "$$argc^STDOS()", "synopsis": "Return the number of $ZCMDLINE arguments.", "params": [], "returns": { "type": "int", "doc": "count of whitespace-separated tokens in $ZCMDLINE" }, "raises": [], "raised_in_body": [], "examples": [ "if $$argc^STDOS()<2 do usage^MYAPP" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$arg^STDOS", "do argv^STDOS" ], "deprecated": "", "description": "", "source": { "file": "src/STDOS.m", "line": 89 } }, "arg": { "form": "extrinsic", "signature": "$$arg^STDOS(i)", "synopsis": "Return the i-th $ZCMDLINE argument (1-indexed); \"\" if out of bounds.", "params": [ { "name": "i", "type": "int", "doc": "1-based argument index" } ], "returns": { "type": "string", "doc": "the i-th token, or \"\" if i is out of bounds" }, "raises": [], "raised_in_body": [], "examples": [ "set inputPath=$$arg^STDOS(1)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$argc^STDOS", "do argv^STDOS" ], "deprecated": "", "description": "", "source": { "file": "src/STDOS.m", "line": 98 } }, "argv": { "form": "procedure", "signature": "do argv^STDOS(args)", "synopsis": "Populate args(1..N) from $ZCMDLINE; N is the implicit return.", "params": [ { "name": "args", "type": "array", "doc": "by-ref local; killed then populated from $ZCMDLINE tokens" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do argv^STDOS(.args)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$argc^STDOS", "$$arg^STDOS", "$$splitArgs^STDOS" ], "deprecated": "", "description": "", "source": { "file": "src/STDOS.m", "line": 111 } }, "cwd": { "form": "extrinsic", "signature": "$$cwd^STDOS()", "synopsis": "Return the current working directory (from $PWD).", "params": [], "returns": { "type": "path", "doc": "value of $PWD; \"\" if unset" }, "raises": [], "raised_in_body": [], "examples": [ "write $$cwd^STDOS() ; e.g. /home/user/project (host-specific)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$env^STDOS" ], "deprecated": "", "description": "For container environments where $PWD is unset, this returns\n\"\"; callers that need stat-based getcwd() should wait on the\n$ZF→getcwd(2) callout backend.", "source": { "file": "src/STDOS.m", "line": 122 } }, "user": { "form": "extrinsic", "signature": "$$user^STDOS()", "synopsis": "Return the current username (from $USER).", "params": [], "returns": { "type": "string", "doc": "$USER if set; otherwise $LOGNAME; \"\" if neither" }, "raises": [], "raised_in_body": [], "examples": [ "write $$user^STDOS() ; e.g. alice (host-specific)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$env^STDOS", "$$hostname^STDOS" ], "deprecated": "", "description": "Falls back to $LOGNAME if $USER is unset (System V convention).", "source": { "file": "src/STDOS.m", "line": 133 } }, "hostname": { "form": "extrinsic", "signature": "$$hostname^STDOS()", "synopsis": "Return the host name (from $HOSTNAME) or \"\" if unset.", "params": [], "returns": { "type": "string", "doc": "value of $HOSTNAME; \"\" if unset" }, "raises": [], "raised_in_body": [], "examples": [ "write $$hostname^STDOS() ; e.g. vista-meta-1 (host-specific)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$env^STDOS", "$$user^STDOS" ], "deprecated": "", "description": "$HOSTNAME is exported by some shells (bash) but stripped in\nminimal containers; callers that always need a value should\nwait on the $ZF→gethostname(2) callout backend.", "source": { "file": "src/STDOS.m", "line": 145 } }, "exit": { "form": "procedure", "signature": "do exit^STDOS(rc)", "synopsis": "Terminate the YDB process with exit code rc (default 0).", "params": [ { "name": "rc", "type": "int", "doc": "exit code; defaults to 0 if unsupplied" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do exit^STDOS(2) ; rc=2 to the calling shell" ], "since": "v0.3.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "Implemented via ZHALT. The process exits immediately; no\n$ETRAP fires, no cleanup runs, no further M code executes.", "source": { "file": "src/STDOS.m", "line": 156 } } }, "source": { "file": "src/STDOS.m", "line": 1 } }, "STDPROF": { "synopsis": "m-stdlib — Wall-clock profiler with per-tag aggregates + percentiles.", "description": "m-lint: disable-file=M-MOD-022\nM-MOD-022: STDPROF uses $ZHOROLOG for microsecond-resolution timing\n($HOROLOG is only second-resolution — too coarse for profiling).\n$ZHOROLOG is YDB extension, also supported by IRIS — listed in\nSTDDATE's precedent. v0.2.x ships YDB-first; IRIS arm tracks the\n$ZTIMESTAMP equivalent under STDDATE's IRIS pass.\n\nPublic extrinsics:\n new^STDPROF(.prof) — initialise empty profiler\n start^STDPROF(.prof, tag) — open a timer for tag\n stop^STDPROF(.prof, tag) — close the timer; record sample\n $$count^STDPROF(.prof, tag) — completed cycles\n $$total^STDPROF(.prof, tag) — sum of elapsed (microseconds)\n $$mean^STDPROF(.prof, tag) — total / count (integer floor)\n $$min^STDPROF(.prof, tag) — fastest sample\n $$max^STDPROF(.prof, tag) — slowest sample\n $$percentile^STDPROF(.prof, tag, p) — p-th percentile (0..100)\n $$tags^STDPROF(.prof, .out) — populate out(1..N) with tag names\n clear^STDPROF(.prof) — drop every tag's data\n\nTree shape (caller-owned; pass by reference):\n prof(\"active\",tag) — start time of an in-progress cycle\n prof(\"count\",tag) — completed cycles\n prof(\"total\",tag) — sum of elapsed microseconds\n prof(\"min\",tag) — fastest sample\n prof(\"max\",tag) — slowest sample\n prof(\"samples\",tag,value,seq)=\"\" — per-sample, sorted by value\n\nTime source: $ZHOROLOG = \"DDDDD,SSSSS,US,TZ\" (days, seconds, microseconds,\ntimezone). nowMicros() collapses to a single integer microsecond count\nsince the M epoch (1840-12-31). Sample resolution is microseconds; the\nunderlying system clock typically delivers ~1ms granularity on\ncontainer hosts and ~10us on bare metal.", "errors": [], "labels": { "new": { "form": "procedure", "signature": "do new^STDPROF(prof)", "synopsis": "Initialise / wipe the profiler.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local; killed" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do new^STDPROF(.p)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do start^STDPROF", "do clear^STDPROF" ], "deprecated": "", "description": "Idempotent — calling new() on a populated profiler clears it.", "source": { "file": "src/STDPROF.m", "line": 40 } }, "start": { "form": "procedure", "signature": "do start^STDPROF(prof, tag)", "synopsis": "Open a timer for tag. Stamps prof(\"active\",tag) with $ZHOROLOG.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local from new^STDPROF" }, { "name": "tag", "type": "string", "doc": "per-tag identifier (e.g. \"db.query\")" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do start^STDPROF(.p,\"db.query\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do stop^STDPROF" ], "deprecated": "", "description": "Calling start() while a timer is already active is a no-op\n(the existing start time is preserved).", "source": { "file": "src/STDPROF.m", "line": 50 } }, "stop": { "form": "procedure", "signature": "do stop^STDPROF(prof, tag)", "synopsis": "Close the timer; record one sample. No-op if no matching start.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local from new^STDPROF" }, { "name": "tag", "type": "string", "doc": "per-tag identifier matching a prior start()" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do stop^STDPROF(.p,\"db.query\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do start^STDPROF" ], "deprecated": "", "description": "", "source": { "file": "src/STDPROF.m", "line": 63 } }, "count": { "form": "extrinsic", "signature": "$$count^STDPROF(prof, tag)", "synopsis": "Return number of completed cycles for tag; 0 if untracked.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local" }, { "name": "tag", "type": "string", "doc": "per-tag identifier" } ], "returns": { "type": "int", "doc": "completed cycles; 0 if tag is untracked" }, "raises": [], "raised_in_body": [], "examples": [ "write $$count^STDPROF(.p,\"db.query\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$total^STDPROF", "$$mean^STDPROF" ], "deprecated": "", "description": "", "source": { "file": "src/STDPROF.m", "line": 88 } }, "total": { "form": "extrinsic", "signature": "$$total^STDPROF(prof, tag)", "synopsis": "Return sum of elapsed microseconds across all cycles; 0 if untracked.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local" }, { "name": "tag", "type": "string", "doc": "per-tag identifier" } ], "returns": { "type": "int", "doc": "sum of elapsed microseconds; 0 if untracked" }, "raises": [], "raised_in_body": [], "examples": [ "write $$total^STDPROF(.p,\"db.query\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$count^STDPROF", "$$mean^STDPROF" ], "deprecated": "", "description": "", "source": { "file": "src/STDPROF.m", "line": 98 } }, "mean": { "form": "extrinsic", "signature": "$$mean^STDPROF(prof, tag)", "synopsis": "Return total\\count (integer floor); 0 if no cycles.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local" }, { "name": "tag", "type": "string", "doc": "per-tag identifier" } ], "returns": { "type": "int", "doc": "average elapsed microseconds; 0 if no cycles" }, "raises": [], "raised_in_body": [], "examples": [ "write $$mean^STDPROF(.p,\"db.query\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$total^STDPROF", "$$count^STDPROF", "$$percentile^STDPROF" ], "deprecated": "", "description": "", "source": { "file": "src/STDPROF.m", "line": 108 } }, "min": { "form": "extrinsic", "signature": "$$min^STDPROF(prof, tag)", "synopsis": "Return fastest sample; 0 if no cycles.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local" }, { "name": "tag", "type": "string", "doc": "per-tag identifier" } ], "returns": { "type": "int", "doc": "fastest sample (microseconds); 0 if no cycles" }, "raises": [], "raised_in_body": [], "examples": [ "write $$min^STDPROF(.p,\"db.query\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$max^STDPROF", "$$percentile^STDPROF" ], "deprecated": "", "description": "", "source": { "file": "src/STDPROF.m", "line": 121 } }, "max": { "form": "extrinsic", "signature": "$$max^STDPROF(prof, tag)", "synopsis": "Return slowest sample; 0 if no cycles.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local" }, { "name": "tag", "type": "string", "doc": "per-tag identifier" } ], "returns": { "type": "int", "doc": "slowest sample (microseconds); 0 if no cycles" }, "raises": [], "raised_in_body": [], "examples": [ "write $$max^STDPROF(.p,\"db.query\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$min^STDPROF", "$$percentile^STDPROF" ], "deprecated": "", "description": "", "source": { "file": "src/STDPROF.m", "line": 131 } }, "percentile": { "form": "extrinsic", "signature": "$$percentile^STDPROF(prof, tag, p)", "synopsis": "Return the p-th percentile sample (0..100).", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local" }, { "name": "tag", "type": "string", "doc": "per-tag identifier" }, { "name": "p", "type": "int", "doc": "percentile in [0,100]" } ], "returns": { "type": "int", "doc": "p-th percentile sample (microseconds); 0 if no cycles" }, "raises": [], "raised_in_body": [], "examples": [ "write $$percentile^STDPROF(.p,\"db.query\",95)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$mean^STDPROF", "$$min^STDPROF", "$$max^STDPROF" ], "deprecated": "", "description": "p=0 returns min; p=100 returns max; intermediate values use\nnearest-rank: ceil(p*N/100) into the sorted samples (1-based).", "source": { "file": "src/STDPROF.m", "line": 141 } }, "tags": { "form": "extrinsic", "signature": "$$tags^STDPROF(prof, out)", "synopsis": "Populate out(1..N) with tag names that have at least one cycle.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local" }, { "name": "out", "type": "array", "doc": "by-ref local; killed then populated as out(1..N)" } ], "returns": { "type": "int", "doc": "count of tags" }, "raises": [], "raised_in_body": [], "examples": [ "do set n=$$tags^STDPROF(.p,.list)" ], "since": "v0.3.0", "stable": "stable", "see_also": [], "deprecated": "", "description": "Walk order is M's $ORDER (alphabetical for plain string tags).", "source": { "file": "src/STDPROF.m", "line": 169 } }, "clear": { "form": "procedure", "signature": "do clear^STDPROF(prof)", "synopsis": "Drop every tag's data; preserves nothing.", "params": [ { "name": "prof", "type": "array", "doc": "by-ref local" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do clear^STDPROF(.p)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do new^STDPROF" ], "deprecated": "", "description": "Equivalent to new() — kept as a separate name so call sites\nthat read \"clear\" register the intent.", "source": { "file": "src/STDPROF.m", "line": 185 } } }, "source": { "file": "src/STDPROF.m", "line": 1 } }, "STDREGEX": { "synopsis": "m-stdlib — regular expressions (track L12, v0.2.0).", "description": "Public API. The compiled-pattern handle is a positive integer keyed\nunder ^STDLIB($job,\"stdregex\",h,...); state is per-process and\nper-handle. free() drops it.\n\n $$compile^STDREGEX(pattern) — alloc handle, return h\n $$valid^STDREGEX(pattern) — 1 iff pattern parses\n $$match^STDREGEX(h,s) — 1 iff the entire s matches\n $$search^STDREGEX(h,s) — 1 iff any substring matches\n $$find^STDREGEX(h,s) — 1-indexed start of 1st match (0 = none)\n findall^STDREGEX(h,s,.out) — out(n)=match-string for every non-overlap\n groups^STDREGEX(h,s,.g) — g(0)=full match; g(k)=k-th capture group\n $$replace^STDREGEX(h,s,repl) — every match replaced by repl (\\1..\\9 in repl)\n split^STDREGEX(h,s,.out) — out(n)=segments between matches\n free^STDREGEX(h) — release state\n\nEngine: Thompson-NFA on YDB; wraps $MATCH / $LOCATE on IRIS.\nPass A (this commit) ships the lexer + parser → AST. Passes B–E\nland the NFA construction, simulation, capture tracking, and\nfindall/replace/split. Until then, the engine entry points\n(match/search/find/findall/groups/replace/split) remain safe-\ndefault stubs so the harness can report per-pass progress.\n\nv0.2.0 supported subset:\n Literals, \".\" (any char except newline), \"^\"/\"$\" (string-anchor),\n quantifiers \"*\", \"+\", \"?\", \"{n}\", \"{n,}\", \"{n,m}\" (greedy),\n character classes \"[abc]\" / \"[^abc]\" / \"[a-z]\", predefined\n classes \\d \\D \\w \\W \\s \\S, escapes \\\\ \\. \\^ \\$ \\( \\) \\[ \\]\n \\{ \\} \\| \\* \\+ \\? \\n \\t \\r, alternation \"|\", grouping \"(...)\"\n (capturing) and \"(?:...)\" (non-capturing).\n\nOut of scope at v0.2.0 — compile() rejects with U-STDREGEX-UNSUPPORTED:\n Back-references in the pattern (\\1..\\9), lookaround ((?=...),\n (?!...), (?<=...), (?, (?<...>)),\n Unicode property classes (\\p{...}, \\P{...}), inline modifiers\n ((?i), (?m), …), possessive (*+, ++, ?+) and lazy (*?, +?, ??)\n quantifiers.\nA follow-on STDREGEX_PCRE (Phase 3-adjacent) ships full PCRE\nvia $ZF to libpcre2.\n\nAST representation. After a successful parse, compile() commits the\nAST to ^STDLIB($job,\"stdregex\",h,\"ast\",id,...) under integer ids\nallocated densely from 1; ^...,h,\"root\") names the root id. Each\nnode carries a \"type\" subscript:\n literal — char — \"char\"\n dot — (no extras)\n anchor — \"sym\" = \"^\"|\"$\"\n pred — \"sym\" = d|D|w|W|s|S\n klass — \"negated\" = 0|1; \"item\",N,\"kind\" = char|range|pred,\n with \"char\" or (\"lo\"+\"hi\") or \"sym\"\n star,plus,quest — \"child\" = childId\n range — \"min\", \"max\" (max=\"\" = unbounded), \"child\"\n concat — \"child\",1..N\n alt — \"branch\",1..N\n group — \"capturing\" = 0|1; \"groupNum\" (when capturing); \"child\"\n\nErrors set $ECODE to one of:\n ,U-STDREGEX-BAD-PATTERN, — parse error in pattern\n ,U-STDREGEX-UNSUPPORTED, — feature outside the v0.2.0 subset\n ,U-STDREGEX-NO-MATCH, — groups() called but pattern did not match", "errors": [ "U-STDREGEX-BAD-PATTERN", "U-STDREGEX-UNSUPPORTED", "U-STDREGEX-NO-MATCH" ], "labels": { "compile": { "form": "extrinsic", "signature": "$$compile^STDREGEX(pattern)", "synopsis": "Compile pattern into a handle.", "params": [ { "name": "pattern", "type": "string", "doc": "regex source" } ], "returns": { "type": "int", "doc": "positive handle; pass to match/search/find/etc." }, "raises": [ { "code": "U-STDREGEX-BAD-PATTERN", "doc": "parse error" }, { "code": "U-STDREGEX-UNSUPPORTED", "doc": "feature outside v0.2.0 subset" } ], "raised_in_body": [], "examples": [ "set h=$$compile^STDREGEX(\"\\d+\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$valid^STDREGEX", "do free^STDREGEX", "$$match^STDREGEX" ], "deprecated": "", "description": "", "source": { "file": "src/STDREGEX.m", "line": 67 } }, "free": { "form": "procedure", "signature": "do free^STDREGEX(h)", "synopsis": "Release the compiled-pattern state.", "params": [ { "name": "h", "type": "int", "doc": "handle from compile()" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do free^STDREGEX(h)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$compile^STDREGEX" ], "deprecated": "", "description": "Idempotent. The handle must not be reused after free().", "source": { "file": "src/STDREGEX.m", "line": 101 } }, "valid": { "form": "extrinsic", "signature": "$$valid^STDREGEX(pattern)", "synopsis": "True iff pattern parses cleanly under the v0.2.0 subset.", "params": [ { "name": "pattern", "type": "string", "doc": "regex source" } ], "returns": { "type": "bool", "doc": "1 iff parseable; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDREGEX(\"[a-z]+\") ; 1" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$compile^STDREGEX" ], "deprecated": "", "description": "Does not distinguish BAD-PATTERN from UNSUPPORTED — compile() does.", "source": { "file": "src/STDREGEX.m", "line": 111 } }, "match": { "form": "extrinsic", "signature": "$$match^STDREGEX(h, s)", "synopsis": "True iff the entire string s matches the pattern.", "params": [ { "name": "h", "type": "int", "doc": "handle from compile()" }, { "name": "s", "type": "string", "doc": "candidate string" } ], "returns": { "type": "bool", "doc": "1 iff entire s matches; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$match^STDREGEX(h,\"42\") ; 1 if h compiled \"\\d+\"" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$search^STDREGEX", "$$find^STDREGEX" ], "deprecated": "", "description": "Anchored on both ends — equivalent to \"^pattern$\" semantics.", "source": { "file": "src/STDREGEX.m", "line": 123 } }, "search": { "form": "extrinsic", "signature": "$$search^STDREGEX(h, s)", "synopsis": "True iff any substring of s matches the pattern.", "params": [ { "name": "h", "type": "int", "doc": "handle from compile()" }, { "name": "s", "type": "string", "doc": "candidate string" } ], "returns": { "type": "bool", "doc": "1 iff any substring matches" }, "raises": [], "raised_in_body": [], "examples": [ "write $$search^STDREGEX(h,\"the 42 cats\") ; 1 for \"\\d+\"" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$match^STDREGEX", "$$find^STDREGEX" ], "deprecated": "", "description": "", "source": { "file": "src/STDREGEX.m", "line": 137 } }, "find": { "form": "extrinsic", "signature": "$$find^STDREGEX(h, s)", "synopsis": "1-indexed start of the first match in s; 0 if no match.", "params": [ { "name": "h", "type": "int", "doc": "handle from compile()" }, { "name": "s", "type": "string", "doc": "candidate string" } ], "returns": { "type": "int", "doc": "1-based start index of first match; 0 if none" }, "raises": [], "raised_in_body": [], "examples": [ "write $$find^STDREGEX(h,\"the 42 cats\") ; 5 for \"\\d+\"" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$findall^STDREGEX", "$$search^STDREGEX" ], "deprecated": "", "description": "", "source": { "file": "src/STDREGEX.m", "line": 150 } }, "findall": { "form": "procedure", "signature": "do findall^STDREGEX(h, s, out)", "synopsis": "Populate out(1..N) with every non-overlapping match text.", "params": [ { "name": "h", "type": "int", "doc": "handle from compile()" }, { "name": "s", "type": "string", "doc": "candidate string" }, { "name": "out", "type": "array", "doc": "by-ref local; populated as out(1..N)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do findall^STDREGEX(h,\"a 1 b 22\",.out)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$find^STDREGEX", "do split^STDREGEX" ], "deprecated": "", "description": "", "source": { "file": "src/STDREGEX.m", "line": 163 } }, "groups": { "form": "procedure", "signature": "do groups^STDREGEX(h, s, g)", "synopsis": "Populate g(0..N) with the full match text and each capture group.", "params": [ { "name": "h", "type": "int", "doc": "handle from compile()" }, { "name": "s", "type": "string", "doc": "candidate string" }, { "name": "g", "type": "array", "doc": "by-ref local; killed then populated as g(0..N)" } ], "returns": null, "raises": [ { "code": "U-STDREGEX-NO-MATCH", "doc": "pattern does not match s" } ], "raised_in_body": [], "examples": [ "do groups^STDREGEX(h,\"42-foo\",.g)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$find^STDREGEX", "$$replace^STDREGEX" ], "deprecated": "", "description": "g(0) is the full match; g(k) for k>=1 is the k-th capture group.", "source": { "file": "src/STDREGEX.m", "line": 183 } }, "replace": { "form": "extrinsic", "signature": "$$replace^STDREGEX(h, s, repl)", "synopsis": "Return s with every match replaced by repl.", "params": [ { "name": "h", "type": "int", "doc": "handle from compile()" }, { "name": "s", "type": "string", "doc": "candidate string" }, { "name": "repl", "type": "string", "doc": "replacement template (\\1..\\9 = capture groups; \\\\ = literal \\)" } ], "returns": { "type": "string", "doc": "s with every non-overlapping match replaced" }, "raises": [], "raised_in_body": [], "examples": [ "write $$replace^STDREGEX(h,\"x42y\",\"[\\1]\") ; \"x[42]y\"" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$findall^STDREGEX", "$$groups^STDREGEX" ], "deprecated": "", "description": "", "source": { "file": "src/STDREGEX.m", "line": 207 } }, "split": { "form": "procedure", "signature": "do split^STDREGEX(h, s, out)", "synopsis": "Populate out(1..N) with the segments of s between matches.", "params": [ { "name": "h", "type": "int", "doc": "handle from compile() (e.g. for the separator pattern)" }, { "name": "s", "type": "string", "doc": "candidate string" }, { "name": "out", "type": "array", "doc": "by-ref local; killed then populated as out(1..N)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do split^STDREGEX(h,\"a,b,c\",.out)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$findall^STDREGEX" ], "deprecated": "", "description": "Adjacent matches produce empty segments; leading/trailing matches\nproduce leading/trailing empty segments.", "source": { "file": "src/STDREGEX.m", "line": 253 } } }, "source": { "file": "src/STDREGEX.m", "line": 1 } }, "STDSEED": { "synopsis": "m-stdlib — declarative test data loader (v0.1.3).", "description": "Public API:\n load^STDSEED(path,filer) ; load TSV manifest via `filer`\n (default: fileViaDie -> FILE^DIE)\n $$loaded^STDSEED(path) ; 1 iff path is currently tracked\n clear^STDSEED(path) ; drop bookkeeping for path\n $$validate^STDSEED(path) ; 1 if manifest parses; raises on syntax\n loadJson^STDSEED(jsonText,filer) ; load JSON-array manifest via `filer`\n (each element: {\"file\":..,\"fields\":{..}})\n\nManifest format (TSV, one row per record):\n \\t=\\t=...\nLines beginning with '#' are comments. Whitespace-only lines skip.\n\nFiler hook: the optional `filer` argument is a \"tag^routine\"\nreference invoked once per row as\n do @filer@(file,.fda,.iens)\nwith fda(file,\"+1,\",field)=value and `iens` an output IEN. The\ndefault — when filer is empty — calls FILE^DIE; that path\nassumes FileMan is loaded in the runtime environment.\n\nState per loaded path lives under ^STDLIB($job,\"stdseed\",path,...).\nclear() drops it. STDSEED does NOT open its own transaction;\ncallers wanting rollback semantics wrap in STDFIX (v0.1.1+).\n\nErrors set $ECODE to one of:\n ,U-STDSEED-FILE-NOT-FOUND,\n ,U-STDSEED-MISSING-FILE,\n ,U-STDSEED-MISSING-FIELD,\n ,U-STDSEED-FILER-ERROR,\n ,U-STDSEED-INVALID-JSON,\n ,U-STDSEED-INVALID-MANIFEST,", "errors": [ "U-STDSEED-FILE-NOT-FOUND", "U-STDSEED-MISSING-FILE", "U-STDSEED-MISSING-FIELD", "U-STDSEED-FILER-ERROR", "U-STDSEED-INVALID-JSON", "U-STDSEED-INVALID-MANIFEST" ], "labels": { "load": { "form": "procedure", "signature": "do load^STDSEED(path, filer)", "synopsis": "Load manifest at `path` via `filer` (default FILE^DIE).", "params": [ { "name": "path", "type": "string", "doc": "filesystem path to a TSV manifest" }, { "name": "filer", "type": "string", "doc": "M call-site \"label^routine\" (default fileViaDie^STDSEED)" } ], "returns": null, "raises": [ { "code": "U-STDSEED-FILE-NOT-FOUND", "doc": "could not open `path`" }, { "code": "U-STDSEED-MISSING-FILE", "doc": "a row's first TSV column is empty" }, { "code": "U-STDSEED-MISSING-FIELD", "doc": "a non-empty TSV piece does not contain \"=\"" }, { "code": "U-STDSEED-FILER-ERROR", "doc": "filer raised; propagated as a STDSEED code" } ], "raised_in_body": [], "examples": [ "do load^STDSEED(\"/etc/seed.tsv\")" ], "since": "v0.1.3", "stable": "stable", "see_also": [ "$$validate^STDSEED", "do loadJson^STDSEED", "do clear^STDSEED" ], "deprecated": "", "description": "Each parsed row is dispatched once.", "source": { "file": "src/STDSEED.m", "line": 39 } }, "loaded": { "form": "extrinsic", "signature": "$$loaded^STDSEED(path)", "synopsis": "Predicate — 1 iff `path` is currently loaded.", "params": [ { "name": "path", "type": "string", "doc": "filesystem path" } ], "returns": { "type": "bool", "doc": "1 iff `path` has been load()ed in this job; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$loaded^STDSEED(\"/etc/seed.tsv\")" ], "since": "v0.1.3", "stable": "stable", "see_also": [ "do load^STDSEED", "do clear^STDSEED" ], "deprecated": "", "description": "", "source": { "file": "src/STDSEED.m", "line": 57 } }, "clear": { "form": "procedure", "signature": "do clear^STDSEED(path)", "synopsis": "Drop bookkeeping for `path`. Idempotent.", "params": [ { "name": "path", "type": "string", "doc": "filesystem path of a previously-loaded manifest" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do clear^STDSEED(\"/etc/seed.tsv\")" ], "since": "v0.1.3", "stable": "stable", "see_also": [ "do load^STDSEED", "do with^STDFIX" ], "deprecated": "", "description": "Best-effort — does not delete already-filed records (caller's\nresponsibility, typically via STDFIX rollback).", "source": { "file": "src/STDSEED.m", "line": 66 } }, "validate": { "form": "extrinsic", "signature": "$$validate^STDSEED(path)", "synopsis": "Parse-only check — return 1 on success; raise on syntax error.", "params": [ { "name": "path", "type": "string", "doc": "filesystem path to a TSV manifest" } ], "returns": { "type": "bool", "doc": "1 on success" }, "raises": [ { "code": "U-STDSEED-FILE-NOT-FOUND", "doc": "could not open `path`" }, { "code": "U-STDSEED-MISSING-FILE", "doc": "a row's first TSV column is empty" }, { "code": "U-STDSEED-MISSING-FIELD", "doc": "a non-empty TSV piece does not contain \"=\"" } ], "raised_in_body": [], "examples": [ "write $$validate^STDSEED(\"/etc/seed.tsv\")" ], "since": "v0.1.3", "stable": "stable", "see_also": [ "do load^STDSEED" ], "deprecated": "", "description": "Never invokes the filer. Use as a pre-flight before load().", "source": { "file": "src/STDSEED.m", "line": 77 } }, "loadJson": { "form": "procedure", "signature": "do loadJson^STDSEED(jsonText, filer)", "synopsis": "Load JSON-array manifest via `filer`.", "params": [ { "name": "jsonText", "type": "string", "doc": "JSON array; each element {\"file\":..,\"fields\":{..}}" }, { "name": "filer", "type": "string", "doc": "M call-site \"label^routine\" (default fileViaDie^STDSEED)" } ], "returns": null, "raises": [ { "code": "U-STDSEED-INVALID-JSON", "doc": "jsonText does not parse as JSON" }, { "code": "U-STDSEED-INVALID-MANIFEST", "doc": "parsed JSON is not an array of objects with \"file\"" }, { "code": "U-STDSEED-MISSING-FILE", "doc": "element lacks a \"file\" string member" }, { "code": "U-STDSEED-FILER-ERROR", "doc": "filer raised; propagated as a STDSEED code" } ], "raised_in_body": [ "U-STDSEED-INVALID-JSON", "U-STDSEED-INVALID-MANIFEST" ], "examples": [ "do loadJson^STDSEED(\"[{\"\"file\"\":\"\"PATIENT\"\",\"\"fields\"\":{\"\".01\"\":\"\"Smith\"\"}}]\")" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "do load^STDSEED", "$$parse^STDJSON" ], "deprecated": "", "description": "", "source": { "file": "src/STDSEED.m", "line": 91 } } }, "source": { "file": "src/STDSEED.m", "line": 1 } }, "STDSEMVER": { "synopsis": "m-stdlib — SemVer 2.0.0 parse / compare / range matching.", "description": "Public extrinsics:\n $$valid^STDSEMVER(s) — 1 iff s is a valid SemVer string\n $$parse^STDSEMVER(s,.v) — populate v(1..5); return 1/0\n $$major^STDSEMVER(s) — major component, or \"\" if invalid\n $$minor^STDSEMVER(s) — minor component, or \"\" if invalid\n $$patch^STDSEMVER(s) — patch component, or \"\" if invalid\n $$prerelease^STDSEMVER(s) — prerelease tail, or \"\" if absent\n $$build^STDSEMVER(s) — build tail, or \"\" if absent\n $$compare^STDSEMVER(a,b) — -1/0/1 per SemVer §11 precedence\n $$matches^STDSEMVER(v,range) — 1 iff v satisfies range\n\nGrammar (SemVer 2.0.0 §2):\n ..('-')?('+')?\n each numeric part: non-negative integer, no leading zeros (except 0)\n : dot-separated IDs; each is [0-9A-Za-z-]+; numeric IDs\n have no leading zeros; alphanumeric IDs may include hyphens.\n : dot-separated IDs; same charset; numeric leading zeros OK.\n\nRange syntax (npm subset):\n exact: \"1.2.3\"\n comparator: \">\"|\"<\"|\">=\"|\"<=\"|\"=\" prefixing a SemVer\n caret: \"^1.2.3\" ≡ \">=1.2.3 <2.0.0\"\n tilde: \"~1.2.3\" ≡ \">=1.2.3 <1.3.0\"\n AND: space-separated comparators must all hold", "errors": [], "labels": { "valid": { "form": "extrinsic", "signature": "$$valid^STDSEMVER(s)", "synopsis": "Return 1 iff s is a valid SemVer 2.0.0 string; else 0.", "params": [ { "name": "s", "type": "string", "doc": "candidate SemVer text" } ], "returns": { "type": "bool", "doc": "1 iff well-formed per SemVer 2.0.0; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDSEMVER(\"1.0.0-rc.1+exp\") ; 1" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$parse^STDSEMVER", "$$compare^STDSEMVER" ], "deprecated": "", "description": "Empty input is invalid. Leading 'v' is NOT accepted (callers\nmust strip it). A '+' or '-' delimiter present but followed by\nan empty tail is invalid.", "source": { "file": "src/STDSEMVER.m", "line": 32 } }, "parse": { "form": "extrinsic", "signature": "$$parse^STDSEMVER(s, v)", "synopsis": "Populate v(1..5)=major,minor,patch,prerelease,build; return 1/0.", "params": [ { "name": "s", "type": "string", "doc": "candidate SemVer text" }, { "name": "v", "type": "array", "doc": "by-ref local; killed then populated as v(1..5)" } ], "returns": { "type": "bool", "doc": "1 on success; 0 (and v left empty) on invalid input" }, "raises": [], "raised_in_body": [], "examples": [ "do set rc=$$parse^STDSEMVER(\"1.2.3-rc.1+meta\",.v)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$valid^STDSEMVER", "$$major^STDSEMVER" ], "deprecated": "", "description": "Numeric parts are stored as integers (no leading zeros surface in v).", "source": { "file": "src/STDSEMVER.m", "line": 67 } }, "major": { "form": "extrinsic", "signature": "$$major^STDSEMVER(s)", "synopsis": "Return the major component; \"\" if s is invalid.", "params": [ { "name": "s", "type": "string", "doc": "candidate SemVer text" } ], "returns": { "type": "int", "doc": "major component; \"\" if s is invalid" }, "raises": [], "raised_in_body": [], "examples": [ "write $$major^STDSEMVER(\"1.2.3\") ; 1" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$minor^STDSEMVER", "$$patch^STDSEMVER", "$$parse^STDSEMVER" ], "deprecated": "", "description": "", "source": { "file": "src/STDSEMVER.m", "line": 92 } }, "minor": { "form": "extrinsic", "signature": "$$minor^STDSEMVER(s)", "synopsis": "Return the minor component; \"\" if s is invalid.", "params": [ { "name": "s", "type": "string", "doc": "candidate SemVer text" } ], "returns": { "type": "int", "doc": "minor component; \"\" if s is invalid" }, "raises": [], "raised_in_body": [], "examples": [ "write $$minor^STDSEMVER(\"1.2.3\") ; 2" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$major^STDSEMVER", "$$patch^STDSEMVER" ], "deprecated": "", "description": "", "source": { "file": "src/STDSEMVER.m", "line": 104 } }, "patch": { "form": "extrinsic", "signature": "$$patch^STDSEMVER(s)", "synopsis": "Return the patch component; \"\" if s is invalid.", "params": [ { "name": "s", "type": "string", "doc": "candidate SemVer text" } ], "returns": { "type": "int", "doc": "patch component; \"\" if s is invalid" }, "raises": [], "raised_in_body": [], "examples": [ "write $$patch^STDSEMVER(\"1.2.3\") ; 3" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$major^STDSEMVER", "$$minor^STDSEMVER" ], "deprecated": "", "description": "", "source": { "file": "src/STDSEMVER.m", "line": 116 } }, "prerelease": { "form": "extrinsic", "signature": "$$prerelease^STDSEMVER(s)", "synopsis": "Return the prerelease tail (no leading '-'); \"\" if absent or invalid.", "params": [ { "name": "s", "type": "string", "doc": "candidate SemVer text" } ], "returns": { "type": "string", "doc": "prerelease tail (no leading '-'); \"\" if absent or invalid" }, "raises": [], "raised_in_body": [], "examples": [ "write $$prerelease^STDSEMVER(\"1.0.0-rc.1+meta\") ; \"rc.1\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$build^STDSEMVER", "$$compare^STDSEMVER" ], "deprecated": "", "description": "", "source": { "file": "src/STDSEMVER.m", "line": 128 } }, "build": { "form": "extrinsic", "signature": "$$build^STDSEMVER(s)", "synopsis": "Return the build tail (no leading '+'); \"\" if absent or invalid.", "params": [ { "name": "s", "type": "string", "doc": "candidate SemVer text" } ], "returns": { "type": "string", "doc": "build tail (no leading '+'); \"\" if absent or invalid" }, "raises": [], "raised_in_body": [], "examples": [ "write $$build^STDSEMVER(\"1.0.0-rc.1+meta\") ; \"meta\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$prerelease^STDSEMVER" ], "deprecated": "", "description": "", "source": { "file": "src/STDSEMVER.m", "line": 140 } }, "compare": { "form": "extrinsic", "signature": "$$compare^STDSEMVER(a, b)", "synopsis": "Return -1/0/1 per SemVer §11 precedence (build ignored).", "params": [ { "name": "a", "type": "string", "doc": "first SemVer" }, { "name": "b", "type": "string", "doc": "second SemVer" } ], "returns": { "type": "int", "doc": "-1 if ab; \"\" if either operand is invalid" }, "raises": [], "raised_in_body": [], "examples": [ "write $$compare^STDSEMVER(\"1.0.0-rc.1\",\"1.0.0\") ; -1" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$matches^STDSEMVER" ], "deprecated": "", "description": "Build metadata is ignored per SemVer §10. Prerelease precedence\nfollows §11.4 (release > prerelease; numeric < alphanumeric).", "source": { "file": "src/STDSEMVER.m", "line": 152 } }, "matches": { "form": "extrinsic", "signature": "$$matches^STDSEMVER(v, range)", "synopsis": "Return 1 iff v satisfies the range expression.", "params": [ { "name": "v", "type": "string", "doc": "SemVer to test" }, { "name": "range", "type": "string", "doc": "range expression (exact, comparator, caret, tilde, AND)" } ], "returns": { "type": "bool", "doc": "1 iff v satisfies range; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$matches^STDSEMVER(\"1.5.0\",\"^1.2.3\") ; 1" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$compare^STDSEMVER", "$$valid^STDSEMVER" ], "deprecated": "", "description": "range may be a bare SemVer (exact match), a single comparator\n('>'/'<'/'>='/'<='/'='-prefixed), a caret/tilde expansion, or\na space-separated AND of comparators.", "source": { "file": "src/STDSEMVER.m", "line": 181 } } }, "source": { "file": "src/STDSEMVER.m", "line": 1 } }, "STDSNAP": { "synopsis": "m-stdlib — Snapshot testing: serialize an M tree, diff against a baseline.", "description": "Public extrinsics:\n $$serialize^STDSNAP(.data) — canonical text dump of data tree\n save^STDSNAP(path, .data) — write serialize(data) to path\n $$matches^STDSNAP(path, .data) — 1 iff serialize(data) equals file content\n asserts^STDSNAP(.pass, .fail, path, .data, desc) — STDASSERT-style integration\n\nWorkflow:\n First run: caller calls save() to capture the baseline snapshot.\n Subsequent runs: caller calls matches() (or asserts()) to compare\n the current data against the saved baseline. Mismatches surface as\n STDASSERT failures with a one-line summary.\n\nCanonical format (line-per-leaf):\n (subscripts)=value\nwhere subscripts is a comma-separated M-syntax list (numeric\nsubscripts unquoted; string subscripts double-quoted with embedded\ndoubles per M convention) and value is the leaf node's M-quoted\nscalar. Numeric values emit unquoted; everything else is wrapped in\n\"...\" with internal \" doubled.\n\nLines are emitted in $ORDER walk order — natural M-collation, which\ngives numeric sort for numeric subscripts and string sort for the\nrest. The walk is deterministic; two calls on the same tree produce\nbyte-identical output.\n\nImplementation: $QUERY-driven recursive descent. The `data` formal\nbinds to the caller's array via pass-by-reference; $QUERY(data) walks\ndescendants via M's natural collation order.", "errors": [ "U-STDFS-OPEN-FAIL" ], "labels": { "serialize": { "form": "extrinsic", "signature": "$$serialize^STDSNAP(data)", "synopsis": "Walk data tree; return the canonical line-per-leaf dump.", "params": [ { "name": "data", "type": "array", "doc": "by-ref local; the tree to serialize" } ], "returns": { "type": "string", "doc": "canonical line-per-leaf dump; \"\" for an empty tree" }, "raises": [], "raised_in_body": [], "examples": [ "write $$serialize^STDSNAP(.cfg)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do save^STDSNAP", "$$matches^STDSNAP" ], "deprecated": "", "description": "Trailing LF is *not* emitted — keeps round-trip clean against\nwriteFile/readFile, which add and strip a trailing LF.", "source": { "file": "src/STDSNAP.m", "line": 36 } }, "save": { "form": "procedure", "signature": "do save^STDSNAP(path, data)", "synopsis": "Write serialize(data) to path. Overwrites if exists.", "params": [ { "name": "path", "type": "string", "doc": "filesystem path; truncated if it exists" }, { "name": "data", "type": "array", "doc": "by-ref local; the tree to serialize" } ], "returns": null, "raises": [ { "code": "U-STDFS-OPEN-FAIL", "doc": "could not open `path` for write (propagated from STDFS)" } ], "raised_in_body": [], "examples": [ "do save^STDSNAP(\"snapshots/cfg.snap\",.cfg)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$matches^STDSNAP", "do asserts^STDSNAP" ], "deprecated": "", "description": "", "source": { "file": "src/STDSNAP.m", "line": 59 } }, "matches": { "form": "extrinsic", "signature": "$$matches^STDSNAP(path, data)", "synopsis": "Return 1 iff serialize(data) equals the file's content.", "params": [ { "name": "path", "type": "string", "doc": "filesystem path to the baseline snapshot" }, { "name": "data", "type": "array", "doc": "by-ref local; current tree" } ], "returns": { "type": "bool", "doc": "1 iff current matches baseline; 0 otherwise (incl. missing file)" }, "raises": [], "raised_in_body": [], "examples": [ "write $$matches^STDSNAP(\"snapshots/cfg.snap\",.cfg)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do save^STDSNAP", "do asserts^STDSNAP" ], "deprecated": "", "description": "A missing file returns 0 (no match — first run typically calls\nsave() to seed the snapshot before relying on matches).", "source": { "file": "src/STDSNAP.m", "line": 72 } }, "asserts": { "form": "procedure", "signature": "do asserts^STDSNAP(p, f, path, data, desc)", "synopsis": "STDASSERT-style snapshot assertion.", "params": [ { "name": "p", "type": "int", "doc": "pass counter (by-ref; incremented on match)" }, { "name": "f", "type": "int", "doc": "fail counter (by-ref; incremented on mismatch)" }, { "name": "path", "type": "string", "doc": "filesystem path to the baseline snapshot" }, { "name": "data", "type": "array", "doc": "by-ref local; current tree" }, { "name": "desc", "type": "string", "doc": "human-readable assertion description" } ], "returns": null, "raises": [ { "code": "U-STDFS-OPEN-FAIL", "doc": "in update mode if the write fails (propagated from STDFS)" } ], "raised_in_body": [], "examples": [ "do asserts^STDSNAP(.pass,.fail,\"cfg.snap\",.cfg,\"config matches baseline\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "do save^STDSNAP", "$$matches^STDSNAP" ], "deprecated": "", "description": "On match: increments p and emits PASS via STDASSERT.\nOn mismatch: increments f and emits FAIL with a brief diagnostic.\nUpdate mode: when ^STDLIB($job,\"stdsnap\",\"update\")=1, writes the\ncurrent snapshot to `path` and records PASS instead of comparing.\nUsed by m-cli's `m test --update-snapshots` to regenerate\nbaselines after an intentional change in test output.", "source": { "file": "src/STDSNAP.m", "line": 88 } } }, "source": { "file": "src/STDSNAP.m", "line": 1 } }, "STDSTR": { "synopsis": "m-stdlib — String helpers (pad / trim / split / replaceAll / case / repeat).", "description": "Public extrinsics:\n $$pad^STDSTR(s,n,c?) — alias for padLeft (numeric formatting default)\n $$padLeft^STDSTR(s,n,c?) — left-pad s to width n with c (default \" \")\n $$padRight^STDSTR(s,n,c?) — right-pad s to width n with c (default \" \")\n $$trim^STDSTR(s) — strip leading and trailing whitespace\n $$trimLeft^STDSTR(s) — strip leading whitespace only\n $$trimRight^STDSTR(s) — strip trailing whitespace only\n $$replaceAll^STDSTR(s,find,repl) — replace every non-overlapping occurrence\n $$split^STDSTR(s,sep,.out) — split on sep; populate out(1..N); return N\n $$startsWith^STDSTR(s,prefix) — predicate: does s begin with prefix?\n $$endsWith^STDSTR(s,suffix) — predicate: does s end with suffix?\n $$toLowerASCII^STDSTR(s) — A-Z → a-z (ASCII only; preserves non-alpha)\n $$toUpperASCII^STDSTR(s) — a-z → A-Z (ASCII only; preserves non-alpha)\n $$repeat^STDSTR(s,n) — concatenate s with itself n times\n\nWhitespace for trim/trimLeft/trimRight is the four ASCII characters\nspace ($C(32)), tab ($C(9)), LF ($C(10)), CR ($C(13)). Unicode\nwhitespace classes (NBSP, ideographic space, etc.) are deliberately\nnot stripped — keeps trim() byte-faithful and idempotent under any\n$ZCHSET mode.\n\nPure-M throughout: $translate, $piece, $find, $extract, $length —\nno STDREGEX dep, no $Z* extensions. Runs unchanged on YDB and IRIS.", "errors": [], "labels": { "pad": { "form": "extrinsic", "signature": "$$pad^STDSTR(s, n, c)", "synopsis": "Alias for padLeft — common numeric-formatting shorthand.", "params": [ { "name": "s", "type": "string", "doc": "the string to pad" }, { "name": "n", "type": "int", "doc": "target width (no-op if $LENGTH(s) >= n)" }, { "name": "c", "type": "string", "doc": "fill character (default \" \"; first char only used)" } ], "returns": { "type": "string", "doc": "s left-padded with c to width n" }, "raises": [], "raised_in_body": [], "examples": [ "write $$pad^STDSTR(\"5\",3,\"0\") ; \"005\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$padLeft^STDSTR", "$$padRight^STDSTR" ], "deprecated": "", "description": "", "source": { "file": "src/STDSTR.m", "line": 31 } }, "padLeft": { "form": "extrinsic", "signature": "$$padLeft^STDSTR(s, n, c)", "synopsis": "Left-pad s to width n with c (default \" \"). Returns s unchanged", "params": [ { "name": "s", "type": "string", "doc": "the string to pad" }, { "name": "n", "type": "int", "doc": "target width" }, { "name": "c", "type": "string", "doc": "fill character (default \" \"; first char only used)" } ], "returns": { "type": "string", "doc": "s left-padded; s unchanged if $LENGTH(s) >= n" }, "raises": [], "raised_in_body": [], "examples": [ "write $$padLeft^STDSTR(\"ab\",6,\"-\") ; \"----ab\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$pad^STDSTR", "$$padRight^STDSTR" ], "deprecated": "", "description": "if $LENGTH(s) ≥ n. c may be multi-char; pad is built by char-wise\nreplication of $EXTRACT(c,1).", "source": { "file": "src/STDSTR.m", "line": 42 } }, "padRight": { "form": "extrinsic", "signature": "$$padRight^STDSTR(s, n, c)", "synopsis": "Right-pad s to width n with c (default \" \"). Returns s unchanged", "params": [ { "name": "s", "type": "string", "doc": "the string to pad" }, { "name": "n", "type": "int", "doc": "target width" }, { "name": "c", "type": "string", "doc": "fill character (default \" \"; first char only used)" } ], "returns": { "type": "string", "doc": "s right-padded; s unchanged if $LENGTH(s) >= n" }, "raises": [], "raised_in_body": [], "examples": [ "write $$padRight^STDSTR(\"ab\",6,\"-\") ; \"ab----\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$pad^STDSTR", "$$padLeft^STDSTR" ], "deprecated": "", "description": "if $LENGTH(s) ≥ n.", "source": { "file": "src/STDSTR.m", "line": 60 } }, "trim": { "form": "extrinsic", "signature": "$$trim^STDSTR(s)", "synopsis": "Strip leading and trailing whitespace (space / tab / LF / CR).", "params": [ { "name": "s", "type": "string", "doc": "the string to trim" } ], "returns": { "type": "string", "doc": "s with outer whitespace stripped" }, "raises": [], "raised_in_body": [], "examples": [ "write $$trim^STDSTR(\" hello \") ; \"hello\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$trimLeft^STDSTR", "$$trimRight^STDSTR" ], "deprecated": "", "description": "Internal whitespace is preserved verbatim. Empty input returns \"\".", "source": { "file": "src/STDSTR.m", "line": 79 } }, "trimLeft": { "form": "extrinsic", "signature": "$$trimLeft^STDSTR(s)", "synopsis": "Strip leading whitespace only.", "params": [ { "name": "s", "type": "string", "doc": "the string to trim" } ], "returns": { "type": "string", "doc": "s with leading whitespace stripped" }, "raises": [], "raised_in_body": [], "examples": [ "write $$trimLeft^STDSTR(\" x \") ; \"x \"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$trim^STDSTR", "$$trimRight^STDSTR" ], "deprecated": "", "description": "", "source": { "file": "src/STDSTR.m", "line": 89 } }, "trimRight": { "form": "extrinsic", "signature": "$$trimRight^STDSTR(s)", "synopsis": "Strip trailing whitespace only.", "params": [ { "name": "s", "type": "string", "doc": "the string to trim" } ], "returns": { "type": "string", "doc": "s with trailing whitespace stripped" }, "raises": [], "raised_in_body": [], "examples": [ "write $$trimRight^STDSTR(\" x \") ; \" x\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$trim^STDSTR", "$$trimLeft^STDSTR" ], "deprecated": "", "description": "", "source": { "file": "src/STDSTR.m", "line": 102 } }, "replaceAll": { "form": "extrinsic", "signature": "$$replaceAll^STDSTR(s, find, repl)", "synopsis": "Replace every non-overlapping left-to-right occurrence.", "params": [ { "name": "s", "type": "string", "doc": "the string to scan" }, { "name": "find", "type": "string", "doc": "the substring to match (multi-char allowed)" }, { "name": "repl", "type": "string", "doc": "the replacement" } ], "returns": { "type": "string", "doc": "s with every non-overlapping match replaced" }, "raises": [], "raised_in_body": [], "examples": [ "write $$replaceAll^STDSTR(\"a-b-c\",\"-\",\"+\") ; \"a+b+c\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$split^STDSTR" ], "deprecated": "", "description": "An empty `find` returns s unchanged (no infinite loop). Replacement\nis non-recursive — the new bytes inserted by `repl` are not rescanned.\nImplementation: $piece-based join — split s on find, rejoin with repl.", "source": { "file": "src/STDSTR.m", "line": 116 } }, "split": { "form": "extrinsic", "signature": "$$split^STDSTR(s, sep, out)", "synopsis": "Split s on sep; populate out(1..N); return N.", "params": [ { "name": "s", "type": "string", "doc": "the string to split" }, { "name": "sep", "type": "string", "doc": "the separator (multi-char allowed)" }, { "name": "out", "type": "array", "doc": "by-ref local; killed then populated as out(1..N)" } ], "returns": { "type": "int", "doc": "number of pieces (0 if s=\"\" or sep=\"\")" }, "raises": [], "raised_in_body": [], "examples": [ "set n=$$split^STDSTR(\"a,b,c\",\",\",.out) ; n=3" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$replaceAll^STDSTR" ], "deprecated": "", "description": "Trailing separator yields a trailing empty element; \"a,b,\" → 3 pieces.", "source": { "file": "src/STDSTR.m", "line": 138 } }, "startsWith": { "form": "extrinsic", "signature": "$$startsWith^STDSTR(s, prefix)", "synopsis": "Return 1 iff s begins with prefix; else 0. Empty prefix → 1.", "params": [ { "name": "s", "type": "string", "doc": "the string to test" }, { "name": "prefix", "type": "string", "doc": "the prefix to look for" } ], "returns": { "type": "bool", "doc": "1 iff s begins with prefix; empty prefix returns 1" }, "raises": [], "raised_in_body": [], "examples": [ "write $$startsWith^STDSTR(\"hello world\",\"hello\") ; 1" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$endsWith^STDSTR" ], "deprecated": "", "description": "", "source": { "file": "src/STDSTR.m", "line": 158 } }, "endsWith": { "form": "extrinsic", "signature": "$$endsWith^STDSTR(s, suffix)", "synopsis": "Return 1 iff s ends with suffix; else 0. Empty suffix → 1.", "params": [ { "name": "s", "type": "string", "doc": "the string to test" }, { "name": "suffix", "type": "string", "doc": "the suffix to look for" } ], "returns": { "type": "bool", "doc": "1 iff s ends with suffix; empty suffix returns 1" }, "raises": [], "raised_in_body": [], "examples": [ "write $$endsWith^STDSTR(\"hello world\",\"world\") ; 1" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$startsWith^STDSTR" ], "deprecated": "", "description": "", "source": { "file": "src/STDSTR.m", "line": 170 } }, "toLowerASCII": { "form": "extrinsic", "signature": "$$toLowerASCII^STDSTR(s)", "synopsis": "A-Z → a-z; preserves all other characters.", "params": [ { "name": "s", "type": "string", "doc": "the string to lowercase" } ], "returns": { "type": "string", "doc": "s with A-Z mapped to a-z (other chars unchanged)" }, "raises": [], "raised_in_body": [], "examples": [ "write $$toLowerASCII^STDSTR(\"Hello-World\") ; \"hello-world\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$toUpperASCII^STDSTR" ], "deprecated": "", "description": "Operates byte-wise — no locale awareness, no Unicode handling.\nFor full Unicode case folding wait on a future STDUNICODE.", "source": { "file": "src/STDSTR.m", "line": 186 } }, "toUpperASCII": { "form": "extrinsic", "signature": "$$toUpperASCII^STDSTR(s)", "synopsis": "a-z → A-Z; preserves all other characters.", "params": [ { "name": "s", "type": "string", "doc": "the string to uppercase" } ], "returns": { "type": "string", "doc": "s with a-z mapped to A-Z (other chars unchanged)" }, "raises": [], "raised_in_body": [], "examples": [ "write $$toUpperASCII^STDSTR(\"Hello-World\") ; \"HELLO-WORLD\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$toLowerASCII^STDSTR" ], "deprecated": "", "description": "Operates byte-wise — no locale awareness, no Unicode handling.", "source": { "file": "src/STDSTR.m", "line": 197 } }, "repeat": { "form": "extrinsic", "signature": "$$repeat^STDSTR(s, n)", "synopsis": "Concatenate s with itself n times. Returns \"\" for n ≤ 0 or s=\"\".", "params": [ { "name": "s", "type": "string", "doc": "the string to repeat" }, { "name": "n", "type": "int", "doc": "repetition count (n <= 0 yields \"\")" } ], "returns": { "type": "string", "doc": "s concatenated with itself n times" }, "raises": [], "raised_in_body": [], "examples": [ "write $$repeat^STDSTR(\"ab\",3) ; \"ababab\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$padLeft^STDSTR", "$$padRight^STDSTR" ], "deprecated": "", "description": "", "source": { "file": "src/STDSTR.m", "line": 209 } } }, "source": { "file": "src/STDSTR.m", "line": 1 } }, "STDTOML": { "synopsis": "m-stdlib — TOML 1.0 parser (deliberately narrow v1 subset).", "description": "Public extrinsics:\n $$parse^STDTOML(text,.root) — parse TOML doc into root tree; return 1/0\n $$valid^STDTOML(text) — predicate: 1 iff parse succeeds\n $$get^STDTOML(.root,key) — value lookup; \"section.key\" addresses tables\n $$type^STDTOML(.root,key) — \"string\" / \"integer\" / \"float\" / \"bool\" / \"\"\n\nTree representation:\n root(\"v\",path) — value (the M scalar after coercion)\n root(\"t\",path) — type tag (\"string\"/\"integer\"/\"float\"/\"bool\")\n path is the dotted address: \"k\" for top-level, \"section.k\" for sectioned.\n\nGrammar (TOML 1.0 subset shipped in v1):\n ::= ( NL)*\n ::= | | | \n ::= \"#\" .* (whole-line or trailing — stripped before pair parse)\n
::= \"[\" \"]\"\n ::= \"=\" \n ::= [A-Za-z0-9_-]+\n ::= | | | \n ::= '\"' (chars with \\n \\t \\r \\\" \\\\ escapes) '\"'\n ::= \"-\"? [0-9]+\n ::= \"-\"? [0-9]+ \".\" [0-9]+\n ::= \"true\" | \"false\"\n\nOut of scope (queued for v0.x.y under T18):\n - arrays, inline tables, dotted keys, [[array-of-tables]]\n - literal strings ('...'), multi-line strings (\"\"\"...\" or '''...''')\n - integer literals with underscores, hex/oct/bin int prefixes\n - special floats (inf, -inf, nan)\n - exponent notation in floats (1.5e3)\n - datetime values (TOML offset / local datetime / local date / local time)", "errors": [], "labels": { "parse": { "form": "extrinsic", "signature": "$$parse^STDTOML(text, root)", "synopsis": "Parse TOML text into root tree; return 1 on success, 0 on parse error.", "params": [ { "name": "text", "type": "string", "doc": "TOML 1.0 document (subset documented in routine header)" }, { "name": "root", "type": "array", "doc": "by-ref local; killed before population" } ], "returns": { "type": "bool", "doc": "1 on success; 0 on parse error" }, "raises": [], "raised_in_body": [], "examples": [ "do set rc=$$parse^STDTOML(text,.cfg)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$valid^STDTOML", "$$get^STDTOML", "$$type^STDTOML" ], "deprecated": "", "description": "On failure, root is left in whatever partial state the parse\nachieved (caller may want to KILL it).", "source": { "file": "src/STDTOML.m", "line": 39 } }, "valid": { "form": "extrinsic", "signature": "$$valid^STDTOML(text)", "synopsis": "Return 1 iff text parses as valid TOML; else 0.", "params": [ { "name": "text", "type": "string", "doc": "TOML document" } ], "returns": { "type": "bool", "doc": "1 iff text parses; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDTOML(\"k = 1\") ; 1" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$parse^STDTOML" ], "deprecated": "", "description": "Same as parse() but discards the resulting tree.", "source": { "file": "src/STDTOML.m", "line": 67 } }, "get": { "form": "extrinsic", "signature": "$$get^STDTOML(root, key)", "synopsis": "Return the value at key (dotted path); \"\" if absent.", "params": [ { "name": "root", "type": "array", "doc": "by-ref tree from $$parse^STDTOML" }, { "name": "key", "type": "string", "doc": "dotted path: \"k\" for top-level; \"section.k\" for sectioned" } ], "returns": { "type": "string", "doc": "the scalar value; \"\" if key is absent" }, "raises": [], "raised_in_body": [], "examples": [ "write $$get^STDTOML(.cfg,\"server.port\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$type^STDTOML", "$$parse^STDTOML" ], "deprecated": "", "description": "", "source": { "file": "src/STDTOML.m", "line": 78 } }, "type": { "form": "extrinsic", "signature": "$$type^STDTOML(root, key)", "synopsis": "Return the type tag at key, or \"\" if absent.", "params": [ { "name": "root", "type": "array", "doc": "by-ref tree from $$parse^STDTOML" }, { "name": "key", "type": "string", "doc": "dotted path" } ], "returns": { "type": "string", "doc": "one of \"string\", \"integer\", \"float\", \"bool\"; \"\" if absent" }, "raises": [], "raised_in_body": [], "examples": [ "write $$type^STDTOML(.cfg,\"server.port\") ; \"integer\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$get^STDTOML" ], "deprecated": "", "description": "", "source": { "file": "src/STDTOML.m", "line": 89 } } }, "source": { "file": "src/STDTOML.m", "line": 1 } }, "STDURL": { "synopsis": "m-stdlib — RFC 3986 URI parser, builder, encoder, resolver.", "description": "Seven public extrinsics:\n $$parse^STDURL(url,.parts) — split URL into components; → 1/0\n $$build^STDURL(.parts) — assemble URL from components\n $$encode^STDURL(s,safe) — percent-encode (RFC 3986 §2.1)\n $$decode^STDURL(s) — percent-decode (lenient — leaves\n malformed % as literal text)\n $$valid^STDURL(url) — RFC 3986 well-formedness predicate\n $$normalize^STDURL(url) — case + percent + dot-segment normalization\n $$resolve^STDURL(base,ref) — resolve a relative reference (§5.3)\n\nThe .parts array is a flat namespace with these keys:\n parts(\"scheme\") parts(\"userinfo\") parts(\"host\")\n parts(\"port\") parts(\"path\") parts(\"query\")\n parts(\"fragment\")\nparse() initialises every key (empty when absent) so callers can\nindex without $get.\n\nStrict-mode resolve: a same-scheme reference like \"http:g\" against\nbase \"http://a/b/c/d;p?q\" resolves to \"http:g\" (RFC 3986 §5.3\nstrict; non-strict back-compat is not implemented).\n\nvalid() is the strict gate. decode() is intentionally lenient\n(matches Python urllib.parse.unquote) — bad %-sequences pass through\nas literal text. Use valid() first if strict input is required.\n\nInput is treated as a string of bytes (one M character per byte —\nvalues 0..255 via $ASCII / $CHAR). RFC 3986 §2.5 specifies UTF-8\nfor non-ASCII; producers/consumers should percent-encode UTF-8\nbytes before passing to encode().", "errors": [], "labels": { "parse": { "form": "procedure", "signature": "do parse^STDURL(url, parts)", "synopsis": "Split url into parts(scheme/userinfo/host/port/path/query/fragment).", "params": [ { "name": "url", "type": "string", "doc": "URL or relative reference" }, { "name": "parts", "type": "array", "doc": "by-ref local; killed then populated with 7 keys" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do parse^STDURL(\"https://example.com/foo?x=1\",.p)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$build^STDURL", "$$valid^STDURL", "$$normalize^STDURL" ], "deprecated": "", "description": "All seven keys (scheme/userinfo/host/port/path/query/fragment)\nare written; absent components are set to \"\". Empty input is\nvalid and yields all-empty parts.", "source": { "file": "src/STDURL.m", "line": 37 } }, "build": { "form": "extrinsic", "signature": "$$build^STDURL(parts)", "synopsis": "Reassemble parts into a URL string.", "params": [ { "name": "parts", "type": "array", "doc": "by-ref local with scheme/userinfo/host/port/path/query/fragment" } ], "returns": { "type": "string", "doc": "reassembled URL" }, "raises": [], "raised_in_body": [], "examples": [ "set p(\"scheme\")=\"https\",p(\"host\")=\"x.com\" w $$build^STDURL(.p)" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$parse^STDURL" ], "deprecated": "", "description": "Emits authority (\"//user@host:port\") iff any of userinfo, host,\nor port is non-empty. The result round-trips parse() for\ncanonical inputs.", "source": { "file": "src/STDURL.m", "line": 71 } }, "encode": { "form": "extrinsic", "signature": "$$encode^STDURL(s, safe)", "synopsis": "Percent-encode s. Unreserved chars + chars in safe pass through.", "params": [ { "name": "s", "type": "string", "doc": "input string (one M character per byte)" }, { "name": "safe", "type": "string", "doc": "additional pass-through characters" } ], "returns": { "type": "string", "doc": "percent-encoded text" }, "raises": [], "raised_in_body": [], "examples": [ "write $$encode^STDURL(\"hello world\",\"\") ; \"hello%20world\"" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$decode^STDURL" ], "deprecated": "", "description": "Unreserved set is ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n(RFC 3986 §2.3). Space becomes %20 (per RFC; not \"+\", which\nis the application/x-www-form-urlencoded convention).", "source": { "file": "src/STDURL.m", "line": 96 } }, "decode": { "form": "extrinsic", "signature": "$$decode^STDURL(s)", "synopsis": "Percent-decode all valid %HH; leave malformed % as literal.", "params": [ { "name": "s", "type": "string", "doc": "percent-encoded text" } ], "returns": { "type": "string", "doc": "decoded text (lenient — bad %-sequences pass through)" }, "raises": [], "raised_in_body": [], "examples": [ "write $$decode^STDURL(\"hello%20world\") ; \"hello world\"" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$encode^STDURL", "$$valid^STDURL" ], "deprecated": "", "description": "Use valid() first if strict input is required. \"+\" is treated\nas a literal \"+\" (form-encoding semantics belong to the caller).", "source": { "file": "src/STDURL.m", "line": 118 } }, "valid": { "form": "extrinsic", "signature": "$$valid^STDURL(url)", "synopsis": "True iff url is a well-formed RFC 3986 URI (or relative reference).", "params": [ { "name": "url", "type": "string", "doc": "candidate URL" } ], "returns": { "type": "bool", "doc": "1 iff well-formed" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDURL(\"/foo\") ; 1" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$parse^STDURL" ], "deprecated": "", "description": "Empty string is valid. Rejects raw spaces, control characters,\nand malformed %HH.", "source": { "file": "src/STDURL.m", "line": 137 } }, "normalize": { "form": "extrinsic", "signature": "$$normalize^STDURL(url)", "synopsis": "Apply RFC 3986 §6.2 syntax-based normalization.", "params": [ { "name": "url", "type": "string", "doc": "URL to normalize" } ], "returns": { "type": "string", "doc": "normalized URL" }, "raises": [], "raised_in_body": [], "examples": [ "write $$normalize^STDURL(\"HTTPS://EX.COM/a/./b\") ; \"https://ex.com/a/b\"" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$resolve^STDURL", "$$parse^STDURL" ], "deprecated": "", "description": "Lowercases scheme + host, uppercases %HH hex digits,\npercent-decodes unreserved characters, and removes\ndot-segments from the path.", "source": { "file": "src/STDURL.m", "line": 163 } }, "resolve": { "form": "extrinsic", "signature": "$$resolve^STDURL(base, ref)", "synopsis": "Resolve ref against base per RFC 3986 §5.3 (strict mode).", "params": [ { "name": "base", "type": "string", "doc": "absolute base URL" }, { "name": "ref", "type": "string", "doc": "relative or absolute reference" } ], "returns": { "type": "string", "doc": "absolute URI string" }, "raises": [], "raised_in_body": [], "examples": [ "write $$resolve^STDURL(\"http://a/b/c/d\",\"../g\") ; \"http://a/b/g\"" ], "since": "v0.2.0", "stable": "stable", "see_also": [ "$$normalize^STDURL", "$$parse^STDURL" ], "deprecated": "", "description": "Strict mode: a reference that begins with the same scheme\nas base is still treated as scheme-bearing.", "source": { "file": "src/STDURL.m", "line": 184 } } }, "source": { "file": "src/STDURL.m", "line": 1 } }, "STDUUID": { "synopsis": "m-stdlib — UUID v4 + v7 (RFC 4122 / RFC 9562).", "description": "Five public extrinsics:\n $$v4^STDUUID() — random UUID v4 (\"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\")\n $$v7^STDUUID() — time-ordered UUID v7\n $$valid^STDUUID(u) — 1 if u is canonical 36-char hex form\n $$version^STDUUID(u) — integer 1..15 from the version nibble, \"\" if invalid\n $$variant^STDUUID(u) — \"ncs\" | \"rfc4122\" | \"microsoft\" | \"future\" | \"\"\n\nv4 randomness is from $RANDOM (Mersenne Twister) — NOT cryptographically\nstrong. Adequate for distributed primary keys; do not use for tokens.\nv7 timestamp is ms since 1970-01-01 UTC (48 bits): high 48 bits encode\nthe timestamp so byte-wise sort = generation order.\n\nAll output is lowercase hex per RFC 9562 §4 recommendation.", "errors": [], "labels": { "v4": { "form": "extrinsic", "signature": "$$v4^STDUUID()", "synopsis": "Return a new RFC-4122 v4 UUID.", "params": [], "returns": { "type": "string", "doc": "canonical 36-char hex UUID v4 (lowercase, hyphenated)" }, "raises": [], "raised_in_body": [], "examples": [ "set id=$$v4^STDUUID() ; \"550e8400-e29b-41d4-a716-446655440000\"" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "$$v7^STDUUID", "$$valid^STDUUID", "$$version^STDUUID" ], "deprecated": "", "description": "122 bits of randomness; version nibble='4'; variant nibble in 8/9/a/b.\nRandomness is from $RANDOM (Mersenne Twister) — adequate for distributed\nprimary keys; not cryptographically strong (do not use for tokens).", "source": { "file": "src/STDUUID.m", "line": 21 } }, "v7": { "form": "extrinsic", "signature": "$$v7^STDUUID()", "synopsis": "Return a new RFC-9562 v7 UUID (time-ordered).", "params": [], "returns": { "type": "string", "doc": "canonical 36-char hex UUID v7; byte-wise sort = generation order" }, "raises": [], "raised_in_body": [], "examples": [ "set id=$$v7^STDUUID() ; sorts in generation order" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "$$v4^STDUUID", "$$valid^STDUUID" ], "deprecated": "", "description": "First 48 bits = ms-since-Unix-epoch (sortable). 12-bit rand_a,\nvariant nibble (8/9/a/b), 12-bit rand_b, 50-bit rand_c.", "source": { "file": "src/STDUUID.m", "line": 38 } }, "valid": { "form": "extrinsic", "signature": "$$valid^STDUUID(u)", "synopsis": "Return 1 iff u is a canonical 36-char hex UUID; else 0.", "params": [ { "name": "u", "type": "string", "doc": "candidate UUID text" } ], "returns": { "type": "bool", "doc": "1 iff canonical 36-char hex; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDUUID(id) ; 1 or 0" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "$$version^STDUUID", "$$variant^STDUUID" ], "deprecated": "", "description": "Accepts both lowercase and uppercase hex. Hyphens must sit\nat exactly positions 9, 14, 19, 24.", "source": { "file": "src/STDUUID.m", "line": 56 } }, "version": { "form": "extrinsic", "signature": "$$version^STDUUID(u)", "synopsis": "Return integer version (1..15) from position 15, or \"\" if invalid.", "params": [ { "name": "u", "type": "string", "doc": "candidate UUID" } ], "returns": { "type": "int", "doc": "1..15 from the version nibble; \"\" if `u` is not valid" }, "raises": [], "raised_in_body": [], "examples": [ "write $$version^STDUUID($$v4^STDUUID()) ; 4" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "$$valid^STDUUID", "$$variant^STDUUID" ], "deprecated": "", "description": "For a v4 UUID this returns 4; for v7, 7. Empty string for malformed.", "source": { "file": "src/STDUUID.m", "line": 77 } }, "variant": { "form": "extrinsic", "signature": "$$variant^STDUUID(u)", "synopsis": "Classify UUID variant from the high bits of position 20.", "params": [ { "name": "u", "type": "string", "doc": "candidate UUID" } ], "returns": { "type": "string", "doc": "one of \"ncs\", \"rfc4122\", \"microsoft\", \"future\"; \"\" if `u` invalid" }, "raises": [], "raised_in_body": [], "examples": [ "write $$variant^STDUUID($$v4^STDUUID()) ; \"rfc4122\"" ], "since": "v0.0.1", "stable": "stable", "see_also": [ "$$valid^STDUUID", "$$version^STDUUID" ], "deprecated": "", "description": "\"ncs\" (high bit 0), \"rfc4122\" (high 10), \"microsoft\" (high 110),\n\"future\" (high 111). Empty string for malformed input.", "source": { "file": "src/STDUUID.m", "line": 92 } } }, "source": { "file": "src/STDUUID.m", "line": 1 } }, "STDXFRM": { "synopsis": "m-stdlib — Higher-order array transforms (map / filter / reduce via @-indirection lambdas).", "description": "m-lint: disable-file=M-MOD-036\nM-MOD-036 flags M's `@` indirection on a \"tainted\" local — but\nXECUTE-via-@ of a caller-supplied expression IS the contract of\nthis module: the lambda is the abstraction. Same shape as STDMOCK's\n`do @resolved@(.args)` and STDFIX's `xecute @cleanupCmd`.\n\nPublic entry points:\n do map^STDXFRM(.in, expr, .out) — out(k) := for each k\n do filter^STDXFRM(.in, expr, .out) — copy in(k)→out(k) iff \n $$reduce^STDXFRM(.in, expr, init) — fold left; is new acc\n\nThe lambda string `expr` is evaluated via `@expr` in this module's\nstack frame, so it sees these locals:\n value — the current element's value (in(k))\n key — the current subscript (k)\n acc — (reduce only) the accumulator carried forward\n\nWalk discipline:\n - $ORDER-walk at depth 1 only (the canonical \"1-D vector\" shape).\n - Subscript shape doesn't matter — int, string, sparse all work.\n - For map/filter, `out` is killed before the walk so stale\n leftovers from a prior call do not leak through.\n - For reduce, the empty-input case returns `init` unchanged.\n\nError semantics: if `expr` raises (compile error, $ECODE set,\ndivision by zero, etc.) the error propagates to the caller's\n$ETRAP unmodified. STDXFRM does not catch.\n\nPure-M throughout — no $Z* extensions. Runs unchanged on YDB and\nIRIS. The @-indirection idiom is ANSI standard since the M[UMPS]\nX11.1 standard.", "errors": [], "labels": { "map": { "form": "procedure", "signature": "do map^STDXFRM(in, expr, out)", "synopsis": "out(k) := for each k in $ORDER(in,k).", "params": [ { "name": "in", "type": "array", "doc": "by-ref local; source array (depth 1)" }, { "name": "expr", "type": "string", "doc": "M expression; locals `value` and `key` available" }, { "name": "out", "type": "array", "doc": "by-ref local; killed then populated as out(k)" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "new a,out set a(1)=1,a(2)=2,a(3)=3 do map^STDXFRM(.a,\"value*2\",.out)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "do filter^STDXFRM", "$$reduce^STDXFRM" ], "deprecated": "", "description": "Lambda locals visible to expr: `value` (in(k)) and `key` (k).", "source": { "file": "src/STDXFRM.m", "line": 38 } }, "filter": { "form": "procedure", "signature": "do filter^STDXFRM(in, expr, out)", "synopsis": "Copy in(k)→out(k) iff is truthy.", "params": [ { "name": "in", "type": "array", "doc": "by-ref local; source array" }, { "name": "expr", "type": "string", "doc": "M predicate expression; `value` and `key` visible" }, { "name": "out", "type": "array", "doc": "by-ref local; killed then populated with kept entries" } ], "returns": null, "raises": [], "raised_in_body": [], "examples": [ "do filter^STDXFRM(.a,\"value>10\",.out)" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "do map^STDXFRM", "$$reduce^STDXFRM" ], "deprecated": "", "description": "Subscripts are preserved. Values are copied verbatim.", "source": { "file": "src/STDXFRM.m", "line": 57 } }, "reduce": { "form": "extrinsic", "signature": "$$reduce^STDXFRM(in, expr, init)", "synopsis": "Fold left: walk in, evaluate expr with `acc`+`value`+`key`.", "params": [ { "name": "in", "type": "array", "doc": "by-ref local; source array" }, { "name": "expr", "type": "string", "doc": "M expression; locals `acc`, `value`, `key` available" }, { "name": "init", "type": "string", "doc": "initial accumulator" } ], "returns": { "type": "string", "doc": "final accumulator (init if `in` is empty)" }, "raises": [], "raised_in_body": [], "examples": [ "write $$reduce^STDXFRM(.a,\"acc+value\",0) ; sum" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "do map^STDXFRM", "do filter^STDXFRM" ], "deprecated": "", "description": "", "source": { "file": "src/STDXFRM.m", "line": 76 } } }, "source": { "file": "src/STDXFRM.m", "line": 1 } }, "STDXML": { "synopsis": "m-stdlib — XML parser (well-formed XML 1.0 subset, in-progress).", "description": "m-lint: disable-file=M-MOD-036\nM-MOD-036 flags M's `@` indirection on a \"tainted\" local. The\nXPath helpers (T27) build subscript references from path strings\nthat are 100% generated from internal `for i=1:1:childCount` loops\n— no user input flows into the indirection target. The pattern is\ndocumented in `docs/modules/stdxml.md` \"T27 path-walk indirection\".\n\nPublic extrinsics (v0):\n $$parse^STDXML(text,.root) — parse text into root tree; 1/0\n $$valid^STDXML(text) — predicate\n $$rootName^STDXML(.node) — element tag name\n $$attr^STDXML(.node, name) — attribute value or \"\"\n $$text^STDXML(.node) — direct text content\n $$childCount^STDXML(.node) — count of element children\n $$childByName^STDXML(.node, name, .out) — first child with name → .out; 1/0\n $$lastError^STDXML() — diagnostic string or \"\"\n\nTree shape (caller-owned; pass by reference):\n node(\"name\") — element tag\n node(\"attr\", attrName) — attribute value (decoded)\n node(\"text\") — direct text content (decoded; concatenated text nodes)\n node(\"childCount\") — number of element children\n node(\"child\", n) — n-th child element (recursive structure)\n\nChild traversal MUST go through `childByName` (or analogous helpers\nthat internally `merge` the child subtree to a non-subscripted local).\nDirect passing of `.node(\"child\", n)` is **invalid YDB syntax** —\npass-by-reference of a subscripted local is disallowed at compile\ntime (TOOLCHAIN-FINDINGS row 2026-05-06, demoted to docs 2026-05-07).\nThe merge-then-pass idiom is canonical for any STDXML descent.\n\nGrammar (v0 subset of XML 1.0):\n ::= ? ?\n ::= | \n ::= \"<\" ? ? \"/>\"\n ::= \"<\" ? ? \">\"\n ::= \" ? \">\"\n ::= ( )+\n ::= ? \"=\" ? \n ::= '\"' '\"' | \"'\" \"'\"\n ::= ? ( ? )*\n ::= [A-Za-z_:] [A-Za-z0-9_:.-]*\n ::= text with the 5 standard entities decoded\n\nT26 — DTDs / DOCTYPE / internal subset / custom entities (closed\n2026-05-08): `` is consumed at the prolog;\n`` declarations populate ctx(\"entity\",name)\nand expand in subsequent text + attribute content. `` /\n`` / `` decls are parsed but not enforced\n(skipped through the next `>`). External DTDs (`SYSTEM \"url\"`,\n`PUBLIC \"id\" \"url\"`) are accepted in the prolog and silently\nignored — only the internal subset is materialised. Parameter\nentities (`%name;`) and external entity references are out of\nscope; if a real consumer needs them, lift through a follow-up.", "errors": [], "labels": { "parse": { "form": "extrinsic", "signature": "$$parse^STDXML(text, root)", "synopsis": "Parse text into root tree; return 1/0.", "params": [ { "name": "text", "type": "string", "doc": "XML 1.0 document" }, { "name": "root", "type": "array", "doc": "by-ref local; killed before population" } ], "returns": { "type": "bool", "doc": "1 on success; 0 on parse failure" }, "raises": [], "raised_in_body": [], "examples": [ "do set rc=$$parse^STDXML(text,.tree)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$valid^STDXML", "$$lastError^STDXML", "$$xpath^STDXML" ], "deprecated": "", "description": "Sets ^STDLIB($job,\"stdxml\",\"err\") with a diagnostic on failure.", "source": { "file": "src/STDXML.m", "line": 61 } }, "valid": { "form": "extrinsic", "signature": "$$valid^STDXML(text)", "synopsis": "Return 1 iff text parses as valid XML; else 0.", "params": [ { "name": "text", "type": "string", "doc": "candidate XML" } ], "returns": { "type": "bool", "doc": "1 iff parseable; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "write $$valid^STDXML(\"\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$parse^STDXML" ], "deprecated": "", "description": "", "source": { "file": "src/STDXML.m", "line": 83 } }, "rootName": { "form": "extrinsic", "signature": "$$rootName^STDXML(node)", "synopsis": "Return the element tag name; \"\" if missing.", "params": [ { "name": "node", "type": "node", "doc": "by-ref tree from $$parse^STDXML" } ], "returns": { "type": "string", "doc": "element tag name" }, "raises": [], "raised_in_body": [], "examples": [ "write $$rootName^STDXML(.tree) ; \"foo\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$ns^STDXML", "$$attr^STDXML" ], "deprecated": "", "description": "", "source": { "file": "src/STDXML.m", "line": 93 } }, "attr": { "form": "extrinsic", "signature": "$$attr^STDXML(node, name)", "synopsis": "Return attribute value; \"\" if missing.", "params": [ { "name": "node", "type": "node", "doc": "by-ref tree" }, { "name": "name", "type": "string", "doc": "attribute name" } ], "returns": { "type": "string", "doc": "attribute value; \"\" if missing" }, "raises": [], "raised_in_body": [], "examples": [ "write $$attr^STDXML(.tree,\"id\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$attrNs^STDXML" ], "deprecated": "", "description": "", "source": { "file": "src/STDXML.m", "line": 102 } }, "ns": { "form": "extrinsic", "signature": "$$ns^STDXML(node)", "synopsis": "Return the namespace URI for the element; \"\" if not in any namespace.", "params": [ { "name": "node", "type": "node", "doc": "by-ref tree" } ], "returns": { "type": "string", "doc": "namespace URI; \"\" if element is not in any namespace" }, "raises": [], "raised_in_body": [], "examples": [ "write $$ns^STDXML(.tree) ; \"urn:hl7-org:v3\"" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$attrNs^STDXML", "$$rootName^STDXML" ], "deprecated": "", "description": "T25 — uses xmlns / xmlns:prefix declarations in scope.", "source": { "file": "src/STDXML.m", "line": 112 } }, "attrNs": { "form": "extrinsic", "signature": "$$attrNs^STDXML(node, name)", "synopsis": "Return the namespace URI for an attribute; \"\" if unprefixed or absent.", "params": [ { "name": "node", "type": "node", "doc": "by-ref tree" }, { "name": "name", "type": "string", "doc": "attribute name (with or without prefix)" } ], "returns": { "type": "string", "doc": "namespace URI; \"\" if unprefixed or absent" }, "raises": [], "raised_in_body": [], "examples": [ "write $$attrNs^STDXML(.tree,\"xsi:type\")" ], "since": "v0.4.0", "stable": "stable", "see_also": [ "$$attr^STDXML", "$$ns^STDXML" ], "deprecated": "", "description": "Per XML Namespaces 1.0 §6.2, default xmlns does NOT apply to\nunprefixed attributes; only prefixed attrs carry a namespace URI.", "source": { "file": "src/STDXML.m", "line": 122 } }, "xpath": { "form": "extrinsic", "signature": "$$xpath^STDXML(tree, expr, results)", "synopsis": "Run an XPath query; populate results(1..N); return N.", "params": [ { "name": "tree", "type": "array", "doc": "by-ref parsed XML tree" }, { "name": "expr", "type": "string", "doc": "XPath 1.0 subset expression" }, { "name": "results", "type": "array", "doc": "by-ref local; killed then populated as results(1..N)" } ], "returns": { "type": "int", "doc": "match count; 0 for an unparseable expression" }, "raises": [], "raised_in_body": [], "examples": [ "do set n=$$xpath^STDXML(.doc,\"/r/items/item[2]\",.r)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$xpathOne^STDXML", "$$xpathText^STDXML" ], "deprecated": "", "description": "Supports element paths, absolute paths, descendant axis (`//`),\nposition predicates, wildcards (`*` / `@*`), attribute axis\n(`@attr`), and predicate expressions with comparison operators\nand functions (position, last, name, text, count, etc.).", "source": { "file": "src/STDXML.m", "line": 134 } }, "xpathOne": { "form": "extrinsic", "signature": "$$xpathOne^STDXML(tree, expr, out)", "synopsis": "First match into .out; return 1/0.", "params": [ { "name": "tree", "type": "array", "doc": "by-ref parsed XML tree" }, { "name": "expr", "type": "string", "doc": "XPath expression" }, { "name": "out", "type": "array", "doc": "by-ref local; merged with first match" } ], "returns": { "type": "bool", "doc": "1 iff at least one match; 0 otherwise" }, "raises": [], "raised_in_body": [], "examples": [ "do if $$xpathOne^STDXML(.doc,\"/r/title\",.t) ..." ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$xpath^STDXML", "$$xpathText^STDXML" ], "deprecated": "", "description": "", "source": { "file": "src/STDXML.m", "line": 162 } }, "xpathText": { "form": "extrinsic", "signature": "$$xpathText^STDXML(tree, expr)", "synopsis": "Return the direct text of the first match; \"\" if none.", "params": [ { "name": "tree", "type": "array", "doc": "by-ref parsed XML tree" }, { "name": "expr", "type": "string", "doc": "XPath expression" } ], "returns": { "type": "string", "doc": "direct text of first match; \"\" if no match" }, "raises": [], "raised_in_body": [], "examples": [ "write $$xpathText^STDXML(.doc,\"/cfg/host\")" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$xpath^STDXML", "$$xpathOne^STDXML" ], "deprecated": "", "description": "", "source": { "file": "src/STDXML.m", "line": 178 } }, "text": { "form": "extrinsic", "signature": "$$text^STDXML(node)", "synopsis": "Return direct text content; \"\" if no text.", "params": [ { "name": "node", "type": "node", "doc": "by-ref tree" } ], "returns": { "type": "string", "doc": "direct text content; \"\" if no text" }, "raises": [], "raised_in_body": [], "examples": [ "write $$text^STDXML(.tree)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$xpathText^STDXML" ], "deprecated": "", "description": "", "source": { "file": "src/STDXML.m", "line": 191 } }, "childCount": { "form": "extrinsic", "signature": "$$childCount^STDXML(node)", "synopsis": "Return number of element children; 0 if none.", "params": [ { "name": "node", "type": "node", "doc": "by-ref tree" } ], "returns": { "type": "int", "doc": "number of element children" }, "raises": [], "raised_in_body": [], "examples": [ "write $$childCount^STDXML(.tree)" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$childByName^STDXML" ], "deprecated": "", "description": "", "source": { "file": "src/STDXML.m", "line": 200 } }, "childByName": { "form": "extrinsic", "signature": "$$childByName^STDXML(node, name, out)", "synopsis": "Find first child with `name`; merge into `.out`. 1/0.", "params": [ { "name": "node", "type": "node", "doc": "by-ref tree" }, { "name": "name", "type": "string", "doc": "child element name" }, { "name": "out", "type": "array", "doc": "by-ref local; killed then populated with the child subtree" } ], "returns": { "type": "bool", "doc": "1 iff a matching child exists" }, "raises": [], "raised_in_body": [], "examples": [ "do if $$childByName^STDXML(.tree,\"book\",.b) ..." ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$childCount^STDXML", "$$xpath^STDXML" ], "deprecated": "", "description": "Pass-by-ref of `.out` allows the caller to receive the child\nsubtree without violating YDB's `.x(SUBS)` syntax limit.", "source": { "file": "src/STDXML.m", "line": 209 } }, "lastError": { "form": "extrinsic", "signature": "$$lastError^STDXML()", "synopsis": "Return the last parse error diagnostic; \"\" if none / parse succeeded.", "params": [], "returns": { "type": "string", "doc": "last diagnostic; \"\" if last parse succeeded" }, "raises": [], "raised_in_body": [], "examples": [ "if 'rc write $$lastError^STDXML(),!" ], "since": "v0.3.0", "stable": "stable", "see_also": [ "$$parse^STDXML" ], "deprecated": "", "description": "", "source": { "file": "src/STDXML.m", "line": 230 } } }, "source": { "file": "src/STDXML.m", "line": 1 } } }, "errors": { "U-STDARGS-UNKNOWN-ACTION": { "module": "STDARGS", "labels": [ "addflag" ] }, "U-STDARGS-UNKNOWN-FLAG": { "module": "STDARGS", "labels": [ "parse" ] }, "U-STDARGS-UNKNOWN-SUBCOMMAND": { "module": "STDARGS", "labels": [ "parse" ] }, "U-STDARGS-MISSING-VALUE": { "module": "STDARGS", "labels": [ "parse" ] }, "U-STDARGS-MISSING-POSITIONAL": { "module": "STDARGS", "labels": [ "parse" ] }, "U-STDCOMPRESS-BAD-LEVEL": { "module": "STDCOMPRESS", "labels": [ "gzip", "deflate", "zstdCompress" ] }, "U-STDCOMPRESS-CALLOUT-MISSING": { "module": "STDCOMPRESS", "labels": [ "gzip", "gunzip", "deflate", "inflate", "zstdCompress", "zstdDecompress" ] }, "U-STDCOMPRESS-LIBZ-FAIL": { "module": "STDCOMPRESS", "labels": [ "gzip", "gunzip", "deflate", "inflate" ] }, "U-STDCOMPRESS-LIBZSTD-FAIL": { "module": "STDCOMPRESS", "labels": [ "zstdCompress", "zstdDecompress" ] }, "U-STDCRYPTO-CALLOUT-MISSING": { "module": "STDCRYPTO", "labels": [ "sha256", "sha384", "sha512", "sha256Bytes", "sha384Bytes", "sha512Bytes", "hmacSha256", "hmacSha384", "hmacSha512", "hmacSha256Bytes", "hmacSha384Bytes", "hmacSha512Bytes" ] }, "U-STDCRYPTO-DIGEST-FAIL": { "module": "STDCRYPTO", "labels": [ "sha256", "sha384", "sha512", "sha256Bytes", "sha384Bytes", "sha512Bytes" ] }, "U-STDCRYPTO-HMAC-FAIL": { "module": "STDCRYPTO", "labels": [ "hmacSha256", "hmacSha384", "hmacSha512", "hmacSha256Bytes", "hmacSha384Bytes", "hmacSha512Bytes" ] }, "U-STDCSPRNG-BAD-COUNT": { "module": "STDCSPRNG", "labels": [ "bytes", "hex", "base64", "token" ] }, "U-STDCSPRNG-OPEN-FAIL": { "module": "STDCSPRNG", "labels": [ "bytes" ] }, "U-STDCSPRNG-BAD-RANGE": { "module": "STDCSPRNG", "labels": [ "int" ] }, "U-STDCSV-OPEN-FAIL": { "module": "STDCSV", "labels": [ "parseFile", "writeFile" ] }, "U-STDDATE-BAD-HOROLOG": { "module": "STDDATE", "labels": [ "fromh", "strftime", "add" ] }, "U-STDDATE-BAD-ISO": { "module": "STDDATE", "labels": [ "toh", "strptime" ] }, "U-STDDATE-BAD-DUR": { "module": "STDDATE", "labels": [ "add" ] }, "U-STDFS-OPEN-FAIL": { "module": "STDENV", "labels": [ "parseFile", "readFile", "writeFile", "append", "readLines", "writeLines", "writeBytes", "appendBytes", "readBytes", "save", "asserts" ] }, "U-STDFIX-EMPTY-TAG": { "module": "STDFIX", "labels": [ "with", "register" ] }, "U-STDFIX-UNREGISTERED-TAG": { "module": "STDFIX", "labels": [ "invoke" ] }, "U-STDFMT-MISSING-ARG": { "module": "STDFMT", "labels": [ "f", "fn" ] }, "U-STDFMT-UNCLOSED-BRACE": { "module": "STDFMT", "labels": [ "f", "fn" ] }, "U-STDFMT-UNESCAPED-RBRACE": { "module": "STDFMT", "labels": [ "f", "fn" ] }, "U-STDFMT-UNKNOWN-TYPE": { "module": "STDFMT", "labels": [ "f", "fn" ] }, "U-STDFS-REMOVE-FAIL": { "module": "STDFS", "labels": [ "remove" ] }, "U-STDFS-NOT-WIRED": { "module": "STDFS", "labels": [ "writeBytes", "appendBytes", "readBytes" ] }, "U-STDFS-READ-TRUNCATED": { "module": "STDFS", "labels": [ "readBytes" ] }, "U-STDJSON-PARSE": { "module": "STDJSON", "labels": [ "parse", "parseFile" ] }, "U-STDJSON-ENCODE": { "module": "STDJSON", "labels": [ "encode", "writeFile" ] }, "U-STDLOG-INVALID-LEVEL": { "module": "STDLOG", "labels": [ "LEVEL" ] }, "U-STDLOG-INVALID-SINK": { "module": "STDLOG", "labels": [ "SINK" ] }, "U-STDLOG-INVALID-FORMAT": { "module": "STDLOG", "labels": [ "FORMAT" ] }, "U-STDREGEX-BAD-PATTERN": { "module": "STDREGEX", "labels": [ "compile" ] }, "U-STDREGEX-UNSUPPORTED": { "module": "STDREGEX", "labels": [ "compile" ] }, "U-STDREGEX-NO-MATCH": { "module": "STDREGEX", "labels": [ "groups" ] }, "U-STDSEED-FILE-NOT-FOUND": { "module": "STDSEED", "labels": [ "load", "validate" ] }, "U-STDSEED-MISSING-FILE": { "module": "STDSEED", "labels": [ "load", "validate", "loadJson" ] }, "U-STDSEED-MISSING-FIELD": { "module": "STDSEED", "labels": [ "load", "validate" ] }, "U-STDSEED-FILER-ERROR": { "module": "STDSEED", "labels": [ "load", "loadJson" ] }, "U-STDSEED-INVALID-JSON": { "module": "STDSEED", "labels": [ "loadJson" ] }, "U-STDSEED-INVALID-MANIFEST": { "module": "STDSEED", "labels": [ "loadJson" ] } } }