Plugin reference

print

Console output — printf-style formatting plus raw line/text writes. Built in since rev31zzti: plugin "builtin:print"; — no plugin file, and the format of a literal printf is checked at compile time.

What changed when print became a builtin

The four verbs, their names (both cases), the flush contract and the output order are exactly what the print plugin gave; the formatter is the plugin’s, ported — a checked wrapper over the system printf. The format string is parsed by the runtime, directive by directive; each directive is rebuilt from a whitelist and handed to snprintf with exactly one argument, so libc never sees the script’s string as a whole.

The directive grammar: %[flags][width][.precision]conv — flags - + space 0 #; width and precision are digits only, at most 1 048 576; conversions d i u o x X (integer), f F e E g G (double; an integer argument is accepted), s (string), c (one byte 0..255), %%. Everything else — %n %p %a, a * width or precision, a length modifier written in the script, a width above the ceiling, an unterminated directive — is an error that names the directive and the reason: print.printf: directive #1 ('%n') is not supported (supported: d i u o x X f F e E g G s c %).

Checked at compile time when the format is a string literal, at the directive’s position: directive #2 has no argument (1 given)., 1 directive, 2 arguments given., directive #1 expects an integer, argument 1 is a string. A variable or interpolated format is checked at run time by the same grammar, with the same texts.

Style rule (owner, 2026-10-04): where no formatting is needed, write print.Line("text") (with a newline) or print.Print("text"), not printf("text\n") — printf is for formatting (%d, %s, …). A Line text is not a format: a % in it is a character, never a directive. The examples in the tree and on this site follow the rule.

The old plugin line: plugin "../plugins/print/PrintPlugin"; names a plugin that no longer exists (print is built in since rev31zzti), so it fails like any missing plugin file; there is no alias and no special message — the canonical line is plugin "builtin:print";. %f prints a C-locale decimal point on every platform.

14 functionsnamespace printsource Source/DominExecBuiltinPrint.c (builtin)

Introduction

The print plugin is the most basic text-output operation in DominScript: following the traditional C-style printf pattern, it builds a string from a format string and any number of values, and writes the result to standard output (stdout). The plugin flushes automatically at the end of every call, so the written text appears at once. It has a formatting verb under two names (PrintF and printf — both call exactly the same function), and two unformatted companions, each also under two names: Line/line (text plus a newline) and Print/print (text as-is). The unformatted verbs interpret no % characters at all.

The two names

print.printf follows the familiar lower-case C convention and most sample scripts use this name. print.PrintF follows the PascalCase convention of DominScript plugins. Same behavior, same implementation — the choice is stylistic. The examples in this reference use the lower-case printf form, since it is the most common.

Loading the plugin

plugin "builtin:print";

A typical flow — formatted output

i32 $n;
double $pi;
$n = 42;
$pi = 3.14159;
printf("n=%d, pi=%.2f\n", $n, $pi);

Supported format specifiers

The format string is a simple C-like pattern. A “%” character must be followed by an optional width, an optional “.precision”, and a specifier character. Five specifiers are supported: %d (integer), %x (hexadecimal integer, lower-case), %f (floating-point), %s (string), and %% (a literal % character). The width applies to every specifier as left-padding with spaces to the given width; the precision specifies, for %f, the number of decimal digits (default 6).

What to know about every function (the basics)

  • The first argument MUST be a string (the format string); the following arguments must have types matching the specifiers.

  • Type strictness: %d accepts only int, %f only float, %s only string. A different type raises a runtime error.

  • Argument count strictness: if there are fewer arguments than specifiers, a runtime error.

  • The specifiers may have width and precision (e.g. %5d, %.2f, %10s). The width left-pads with spaces; %0-prefixed padding is NOT supported.

  • The output goes to standard output (stdout), and is flushed automatically at the end of every call (line buffering does not prevent the output from appearing).

  • The return value is ALWAYS 0 (the function does not return the number of characters, only a success indicator).

  • An unknown specifier (e.g. %z) or an invalid character after a numeric width raises a runtime error.

How to read the signatures

format is the format string, and the following ... is the variable number of evaluated arguments (integer, floating-point, or string). The type after the -> arrow is the return type. print.printf(format, ...) -> int expects a format string and zero or more values, and always returns 0.

Formatted output

Writes formatted text to standard output (stdout). Both names of the function (PrintF and printf) perform the same operation.

print.printf

print.printf(format, ...) -> int

Builds a string from a format string and any number of values, and writes it to standard output.

Parameters
Parameter Type Description
format string The format string (required). It knows the %d, %x, %f, %s, and %% specifiers; each supports a width (e.g. %5d), and — for %f — a .precision (e.g. %.2f).
... variadic The values matching the specifiers in the format string (integer, floating-point, or string), in the corresponding order and type.
Return value

Always 0 (success indicator). A bad format, wrong type, or missing argument raises a runtime error.

Example
printf("dec=[%d] width5=[%5d]\n", 42, 42);
printf("hex=[%x] width4=[%4x]\n", 255, 255);
printf("float=[%f] p2=[%.2f] p0=[%.0f]\n", 3.14159, 3.14159,
3.14159);
printf("str=[%s] width10=[%10s]\n", "hi", "hi");
print.Line($"escape: 100%");
Output after running
dec=[42] width5=[ 42]
hex=[ff] width4=[ ff]
float=[3.141590] p2=[3.14] p0=[3]
str=[hi] width10=[ hi]
escape: 100%
When to use

The most common text-output operation: in every script you use this to write out computed values, states, and check messages. You can combine several values in one call; the type strictness helps catch mistakes early.

print.FastPrintF / print.fastprintf

print.FastPrintF(format, ...) -> int

The exact twin of PrintF — same formatting engine, byte-for-byte the same output — except that it does NOT flush on every call. Meant for writing large volumes of output to a pipe or file, where a per-call flush forces one write() syscall per line.

Parameters
Parameter Type Description
format string A printf-style format string.
... any The values substituted into the format.
Return value

Returns the number of characters written.

When to use

Bulk output where throughput matters. If you need each line to appear immediately (progress on a terminal, interleaving with another writer), use PrintF instead — or the output may sit in the buffer until it fills or the program exits.

print.PrintF

print.PrintF(format, ...) -> int

Exactly the same as printf — a PascalCase alias for the same function.

Parameters
Parameter Type Description
format string See printf.
... variadic See printf.
Return value

Always 0. printf and PrintF are semantically identical.

Example
print.PrintF("int=%d, string=%s\n", 7, "apple");
Output after running
int=7, string=apple
When to use

Use the PrintF name if you want to consistently follow the DominScript plugin-API PascalCase convention in your source code. There is no behavioral difference from the lower-case printf.

Practical notes

What builtin:print is good for

  • Diagnostic messages and intermediate values during development and debugging.

  • Log-like output in command-line scripts (simpler than the full log plugin).

  • User feedback: status, errors, results — all formatted nicely.

  • Mixing numeric values and strings into one piece of text in a single call (no need for separate string concatenation).

The specifiers exactly

%d for the decimal integer (signed, if negative). %x for the hexadecimal integer (lower-case “a”..“f”), without sign. %f for the floating-point, by default with 6 decimal digits; with .precision (e.g. %.2f) you can set the desired number of decimals. %s for the string (unchanged). %% places a single literal % character in the output. The width left-pads with spaces in every case.

What it does not support

The plugin provides a focused, minimal printf implementation. It does NOT know: %0-prefix padding (zero-padding), left-alignment (% - flag), %u (unsigned), %o (octal), %c (character), %p (pointer), %e/%g (scientific float), %lld/long modifiers, or any length modifiers. The supported %d/%x/%f/%s/%% with width/.precision covers typical script needs; if you need more complex formatting, preprocess with the str.* functions.

Return value

printf ALWAYS returns 0 (success), not the count of characters written. If you need the character count, build the string first (with the str plugin), query its length, and then write it with printf. The 0-return lets you embed printf into a complex expression without disturbing the order of the output.

Error handling

A wrong argument count (fewer arguments than specifiers), a type mismatch (for example passing a double to %d), or an unknown specifier are reported by the runtime as a runtime error, and the script stops. Non-printf errors (for example memory exhaustion) are rare, but also raise a runtime error. On a successful call, the output appears on stdout at once (flushing is automatic).

Unformatted output

Writes the text with no format-string interpretation — % characters pass through verbatim. Each operation is available in PascalCase and lowercase (Line/line, Print/print), following the printf/PrintF dual-naming convention. These are the recommended companions of the interpolated string literals ($"..."): the substituted value can never cause a formatting error.

print.Line / print.line

print.Line(text) -> int

Writes the text unchanged, appends a newline, and flushes. The text is NOT a format string. Always returns 0.

string $Offer[32] = "50% off";
print.Line($"deal: $Offer");
print.Line("raw: %d %s %%");
Output after running
deal: 50% off
raw: %d %s %%

The counter-example matters: the same call through printf is a data-dependent runtime error — in printf($"deal: $Offer") the interpolated text lands in the format-string position, and once $Offer contains a %, the call stops with a runtime error. When mixing with real formatting, keep the interpolated part behind %s.

print.Print / print.print

print.Print(text) -> int

The same as Line without the trailing newline — for prompts, partial lines, and continued output. Always returns 0.

print.Print("prompt> ");
print.print("continued");
print.Line(" <end");
Output after running
prompt> continued <end

print.Error / print.error

print.Error(text) -> int

The script’s own error channel (since rev31zztt): the text plus a newline to stderr, flushed. In a pipeline (domin x.dom | sort) the script’s diagnostics stay out of the data. Not a format: a % in the text is a character.

print.ErrorF / print.errorf

print.ErrorF(format, ...) -> int

printf’s shape and checks (the same directive grammar, the same compile-time check of a literal format), written to stderr and flushed on every call. It first drains anything FastErrorF left in its buffer, so the family’s own order holds.

print.FastErrorF / print.fasterrorf

print.FastErrorF(format, ...) -> int

ErrorF without the per-call flush — the FastPrintF contract mirrored for stderr. The C library leaves stderr unbuffered (so the runtime’s own error lines leave at once), therefore this verb keeps its own 64 KiB buffer: Error/ErrorF drain it first, a full buffer drains itself, and exit() drains the rest — nothing is lost on a normal termination or a runtime error, but a runtime-error line may precede text still in the buffer, exactly as with FastPrintF.