Skip to content

Embedded Document Formatting

Paul Manias edited this page May 28, 2026 · 12 revisions

Embedded Document Formatting, or EDF, is the source-comment format used by the Kōtuku IDL tools to generate API documentation, C/C++ declarations and run-time interface metadata. EDF sections are written next to the code they describe, so documentation can stay close to module functions, class fields, actions and methods even when an API is implemented across several source files.

To be parsed correctly, EDF source files must be referenced by a TDL file that represents a Kōtuku module. The TDL Reference Manual has more information on their construction, but the module() and class() declarations are pivotal in making the EDF—TDL connection. Consider the following TDL example:

module({ name="Vector", src={ "vector_functions.cpp", "vector_readpainter.cpp" } }, function()
   class("Vector", { src="vectors/vector.cpp" }, [[
      ...
   ]])

   ...
end)

The module() declaration uses the src option to identify source files that contain -MODULE- and -FUNCTION- headers.

The class() declaration uses the src option to identify the source files that contain -CLASS-, -FIELD-, -ACTION- and -METHOD- headers.

The first recognised header in a source file determines whether the file contributes module documentation or class documentation. It must be either -MODULE- or -CLASS-. The tools do not accept a mixture of module and class API headers in one processing session.

The parser reads recognised headers from C/C++ block comments. Each header starts with -NAME- marker, followed by sub-headers and can then either be terminated with -END- or the appearance of a new header.

API Headers

Use -MODULE- for a module API and -CLASS- for a class API. The first content line gives the public API name and a short summary. Longer introductory paragraphs can follow.

-CLASS-
Config: Manages the reading and writing of configuration files.

The Config class reads text-based key-value data from a simple structured format.

-END-

The name in a -CLASS- header must match the name supplied to the corresponding class() declaration in the TDL file. The same rule applies to -MODULE- headers and module() declarations.

Module Functions

Document each exported module function with -FUNCTION-. The function name is written without any private C++ implementation prefix, because the documented name is the public API name exposed through the IDL.

-FUNCTION-
HostToLong: Converts a 32-bit unsigned integer from host byte order to network byte order.
Category: Byte Order
Status:   Internal

Converts a host-order integer to the network byte order required by socket APIs.

-INPUT-
uint Value: Integer value in host byte order.

-RESULT-
uint: Integer value in network byte order.
-END-

Supported function header fields are:

Field Description
Category Optional category name. A preceding -CATEGORY- section can also set the current category for following functions.
Status Optional visibility state. Use Internal or Private for functions that should not appear in public documentation.
ExtPrototype Optional external prototype override for functions whose generated prototype needs explicit control.
Attribute Optional generated declaration attribute.

Use -INPUT- when the function accepts parameters. Parameter lines must appear in call order and use the format type Name: Description.

Use -RESULT- only for functions that return a non-error value. Functions that return ERR must use -ERRORS- instead:

-ERRORS-
Okay
AllocMemory: Memory could not be allocated for the result buffer.
Args: A required pointer was `NULL`.
-END-

Descriptions after error names are optional. When no description is supplied, the generator uses the standard message for that ERR value.

Class Fields

Every public field declared in a class blueprint should have a matching -FIELD- section. The field name must match the class field name declared in TDL or discovered from the compiled class metadata.

-FIELD-
Path: Location of the configuration file.
Lookup: CFG
Status: private

Stores the source path used when reading or writing configuration data.
-END-

Supported field header fields are:

Field Description
Lookup Names a lookup, flag or constant type declared in the API's TDL. The generated documentation includes the value table.
Status Use private for fields that should be hidden from public documentation. A summary beginning with Private is also treated as private.

For lookup or flag fields, keep the prose brief. The generator inserts the value breakdown from the TDL declaration.

Class Actions and Methods

Actions and methods use the same documentation shape. Methods normally include -INPUT-; actions only include it when their contract declares arguments. Both use -ERRORS- for returnable ERR values.

-METHOD-
SetAttrib: Adds, updates and removes XML attributes.

Updates the selected XML tag by changing an existing attribute, creating a new attribute or removing an attribute.

-INPUT-
int Index: Identifies the tag to update.
int(XMS) Attrib: Attribute index to update, or `NEW` to create an attribute.
cstr Name: New attribute name.  If `NULL`, the existing name is preserved.
cstr Value: New attribute value.  If `NULL`, the attribute is removed.

-ERRORS-
Okay
Args: Required arguments were invalid.
OutOfRange: `Index` or `Attrib` is outside the valid range.
ReadOnly: The XML object is read-only.
-END-

The method or action name can also be supplied with explicit fields:

-ACTION-
Name: Clear
Comment: Clears all data held by the object.

An optional long description can be written here.
-END-

Parameter Types

The following base types are recognised in -INPUT- and -RESULT- declarations.

EDF Type C/C++ Type Description
array(Type) Type * Pointer to an unsized array of Type. Use array(Type,Size) for fixed-size arrays.
arraysize int Element count for the preceding array parameter.
buf(Type) Type * Pointer to a buffer of Type. Follow with bufsize or structsize.
bufsize int Byte size of the preceding buffer.
char int8_t Signed 8-bit value.
cid CLASSID Class identifier.
cptr const void * Pointer to untyped constant data.
cstr CSTRING Pointer to an immutable C-style string.
double double 64-bit floating point value.
eid EVENTID Event identifier.
error ERR Error value.
ext OBJECTPTR Pointer to an object implementation.
fid FIELD Field identifier.
flags int 32-bit integer representing bit flags.
float float 32-bit floating point value.
func FUNCTION Callback function descriptor.
fptr(Synopsis) APTR C function pointer. The synopsis starts with the result type, followed by parameters.
hhandle HOSTHANDLE Host-specific resource handle.
int int 32-bit integer.
int(Ref) int 32-bit integer associated with a named lookup or flag type.
large int64_t 64-bit integer.
maxint MAXINT Maximum native integer size for the target.
mem MEMORYID Memory identifier.
obj OBJECTPTR Pointer to an object.
oid OBJECTID Object identifier.
ptr APTR Pointer to untyped data.
ptr(Type) Type * Pointer to typed data.
resource APTR Trackable resource reference.
short int16_t Signed 16-bit value.
str STRING Mutable C-style string.
strview std::string_view & String view parameter for C++ API calls.
struct(Name) APTR Reference to a named TDL struct.
struct(*Name) Name * Pointer to a named TDL struct.
structsize int Byte size of the preceding struct reference.
tags ... Tag-list parameter.
uchar uint8_t Unsigned 8-bit value.
uint uint32_t Unsigned 32-bit value.
ushort uint16_t Unsigned 16-bit value.
va_list va_list Variable argument list.
void void No value.
vtags ... Variable tag-list parameter.

Prefix a type with & when the parameter is a pointer that receives a result, for example &int for int *. Prefix the type with ! when the result is an allocated resource pointer that can be released with FreeResource(); this lets Tiri manage the resource safely. Prefix the type with ^ when a buffer is modified by the function.

Behaviour Tags

Use -TAGS- to record behavioural information that is useful to documentation generators, language bindings and static analysis tools, but cannot be inferred reliably from the EDF type alone. Tags are supplied as a comma-separated value list. Whitespace around commas is ignored.

-FIELD-
Path: Location of the file.

Returns the resolved path associated with the file object.

-TAGS-
null-terminated-result, object-owns-result
-END-

Tags should describe concrete API contracts, not implementation details. Do not use tags to repeat information already expressed by the EDF type, field access flags or -ERRORS- section.

Category Tag Comment
Result lifetime caller-owns-result The caller is responsible for releasing the returned value with FreeResource().
Result lifetime object-owns-result The result references storage owned by the object that supplied it, and resource lifetime is linked to the object.
Result lifetime static-result The result references static storage that remains valid for the process lifetime.
Result lifetime volatile-result The result is short-lived and must be consumed immediately.
Result lifetime api-owns-result The result lifetime is linked to the API call, becoming invalid at the next call to the same API, or the owning object is destroyed.
Result shape null-terminated-result The resulting string view is guaranteed to be NULL terminated (can be assumed for C string pointers).
Nullability non-null-result A successful call always returns a non-NULL pointer.
Nullability nullable-result A successful call may return NULL as a meaningful result.
Input lifetime copies-input The API copies the supplied input before returning and does not retain the caller's buffer.
Input lifetime retains-input The API may retain a reference to the supplied input after returning.
Ownership does-not-take-ownership The API observes the supplied pointer or handle without assuming responsibility for releasing it.
Ownership takes-ownership The API assumes responsibility for releasing the supplied pointer, handle or resource.
Mutation consumes-input The API reads from the supplied input and advances, drains or otherwise consumes it.
Mutation mutates-input The API may modify a supplied pointer, buffer, structure or object parameter.
Mutation mutates-object The called object's state can be mutated even if the result type appears query-like.
Mutation updates-seek-index The call changes the current file or stream position as a side effect.
Resource effects closes-handle The call closes or invalidates an existing host handle or framework handle.
Resource effects creates-resource The call creates a resource that must be tracked or released according to the documented contract.
Resource effects opens-handle The call opens a host handle or framework handle that remains open after returning.
Execution blocking The call may block on I/O, synchronisation, process execution or another external dependency.
Execution non-blocking The call is expected to return without waiting for external completion.
Threading main-thread-only The call must be made from the main thread.
Threading not-reentrant The call must not be re-entered for the same object or subsystem while an earlier call is active.
Threading reentrant The call can be entered again while an earlier call is active, subject to documented object ownership rules.
Threading thread-safe The call may be used concurrently from multiple threads under the documented object lifetime rules.
Callback behaviour callback-held The callback supplied to the API will be recorded and may run at any time after the initiating call returns.
Callback behaviour callback-inlines A callback supplied to the API may run before the initiating call returns.
Path behaviour case-insensitive Name or path matching performed by the API is case-insensitive.
Path behaviour case-sensitive Name or path matching performed by the API is case-sensitive.
Path behaviour path-resolved Path results are normalised to the host platform's canonical format.
Path behaviour path-preserved Path text returned or stored by the API preserves the originally supplied string.
Semantic contract idempotent Repeating the call with the same state and parameters has no additional effect after the first successful call.
Semantic contract pure-query The call reads state only and has no observable side effects.
Metadata deprecated The API or variable is deprecated.
Metadata private The API or variable is not intended for client use.

Markup

Long descriptions support a small XML-like markup set. Use these features inside EDF comments rather than Markdown.

Feature Syntax Purpose
Class reference @ClassName Links to another class document.
External class member @ClassName.Field or @ClassName.Method() Links to a field, method or action on another class.
Local field #FieldName Links to a field on the current class.
Local action or method #Activate() Links to an action or method on the current class.
Local function ~FunctionName() References a local module function (valid in -FUNCTION- documentation only).
External function ~ModuleName.Function() References a module function, e.g. ~Core.AllocMemory().
Lookup or struct reference !LOOP Links to a named lookup, flag or struct type.
Lookup or struct table !LOOP on its own line Inserts the full generated value table.
Inline code `ERR::Okay` Renders code, constants or numeric values in monospace.
Preformatted block <pre>...</pre> Preserves line breaks and spacing.
Heading <header>Technical Notes</header> Adds a heading inside generated documentation.
Ordered list <list type="ordered"> with <li> items Adds a numbered list.
Bullet list <list type="bullet"> with <li> items Adds a bullet list.

Example list:

<list type="ordered">
<li>The new owner's class receives notification through #NewChild().</li>
<li>The object's class receives notification through #NewOwner().</li>
<li>Resource tracking is updated so the child is destroyed with its owner.</li>
</list>

Processing Tools

The IDL documentation parser is implemented in tools/idl/include/doc.tiri and is loaded by tools/idl/idl-c.tiri. It is not a standalone command. Documentation is generated as part of the IDL processing step, because accurate output depends on the TDL file, the source comments and, for class documentation, compiled class metadata.

For command-line options and CMake integration, see TDL Tools. For the TDL syntax used by module(), class(), methods(), constants, flags and structs, see TDL Reference Manual.

Clone this wiki locally