Landin library reference source

core/diag

Shared: available on every enabled target.

Bounded diagnostic storage and streaming diagnostics through a writer capability.

A bounded log stores at most its fixed number of entries and drops messages exceeding 256 bytes. It counts dropped entries and remembers error diagnostics even when they are dropped. A streaming log borrows a writer and file binding, emits severity and position prefixes, and propagates I/O failure.

Items

Executable example

This complete program is maintained in the repository runtime tests. View source.

import core/diag
import core/mem

exercise: () -> (ok: bool) ! mem.out_of_bounds =
    ok = false
    mut value := diag.new(capacity: 1)
    return when diag.stored(addr value) <> 0 or diag.dropped(addr value) <> 0
    _ = diag.note_at(addr value, usize(0)) else (problem)
        ok = problem == mem.out_of_bounds
        return
    end
end exercise

public main: () -> (code: i32) =
    code = 1
    ok := exercise() else false
    if ok then
        code = 42
    end if
end main

log concept

public log: type = concept (logger: type)
    --- Record a diagnostic, copying or consuming the message during the call.
    --- I/O failure is returned separately from error severity.
    note: (self: ptr mut logger, where: text.position, kind: severity,
           what: []u8) -> none ! io.io_failed
    --- Report whether an error diagnostic has been observed.
    failed: (self: ptr logger) -> (yes: bool)
end log

core/diag/diag.ldn:34

Diagnostic capability. note records severity, position and message; failed reports whether an error diagnostic has been observed. I/O failures propagate separately from note.

bounded type

public bounded: type (fixed capacity: usize) = bounded_value(capacity)

core/diag/diag.ldn:53

Fixed-capacity diagnostic log. Stores entries without allocation, counts messages dropped for capacity or excessive length, and remembers errors even if their entries are dropped.

entry type

public entry: type = entry_value

core/diag/diag.ldn:26

Opaque stored diagnostic containing severity, position and a bounded message copy.

severity type

public severity: type = u8

core/diag/diag.ldn:11

Byte carrier for diagnostic severity. Use the named warning and error values.

streaming type

public streaming: type = streaming_value

core/diag/diag.ldn:148

Diagnostic provider borrowing a writer and destination handle. Emits severity-prefixed messages and propagates write failures to the caller.

error value

public error: severity = 1

core/diag/diag.ldn:15

Error severity; recording it marks the log as failed.

message_capacity value

public message_capacity: usize = 256

core/diag/diag.ldn:29

Maximum byte count stored for one bounded diagnostic message. Longer messages are dropped as whole entries.

warning value

public warning: severity = 0

core/diag/diag.ldn:13

Warning severity; recording it does not by itself mark a log as failed.

dropped function

public dropped: (fixed capacity: usize, value: ptr bounded(capacity))
                -> (count: usize)

core/diag/diag.ldn:101

Return the number of entries not retained because the log was full or the message exceeded message_capacity.

message_byte function

public message_byte: (value: entry, index: usize)
                     -> (byte: u8) ! mem.out_of_bounds

core/diag/diag.ldn:131

Read one retained message byte. Reports mem.out_of_bounds past the message length.

message_length function

public message_length: (value: entry) -> (length: usize)

core/diag/diag.ldn:125

Return the number of message bytes retained in an entry.

new function

public new: (fixed capacity: usize) -> (result: bounded(capacity))

core/diag/diag.ldn:86

Create an empty bounded log with zero stored and dropped counts.

note_at function

public note_at: (fixed capacity: usize, value: ptr bounded(capacity), index: usize)
                -> (result: entry) ! mem.out_of_bounds

core/diag/diag.ldn:108

Copy a retained entry by index. Reports mem.out_of_bounds if the index is not stored.

position_of function

public position_of: (value: entry) -> (where: usize)

core/diag/diag.ldn:115

Return the caller-supplied source position associated with an entry.

severity_of function

public severity_of: (value: entry) -> (kind: severity)

core/diag/diag.ldn:120

Return the severity recorded in an entry.

stored function

public stored: (fixed capacity: usize, value: ptr bounded(capacity))
               -> (count: usize)

core/diag/diag.ldn:94

Return the number of retained diagnostic entries.

Read-only pointers let both mutable and immutable log owners query without copying the bounded note array.

to function

public to: (state: ptr any io.writer, where_to: ptr io.file)
           -> (result: streaming from state, where_to)

core/diag/diag.ldn:176

Create a streaming logger over an erased writer and file identifier. Keep both referenced bindings and the underlying provider alive while logging.

A streaming log needs only a writer. A root holding an any io.world builds the writer from the same provider pointer; the two erased values do not convert.