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](./TDL-Reference-Manual.md) 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. ```text -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. ```text -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: ```text -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. ```text -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. ```text -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: ```text -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. ```text -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 | `
...
` | Preserves line breaks and spacing. | | Heading | `
Technical Notes
` | Adds a heading inside generated documentation. | | Ordered list | `` with `
  • ` items | Adds a numbered list. | | Bullet list | `` with `
  • ` items | Adds a bullet list. | Example list: ```text
  • The new owner's class receives notification through #NewChild().
  • The object's class receives notification through #NewOwner().
  • Resource tracking is updated so the child is destroyed with its owner.
  • ``` ## 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](./TDL-Tools.md). For the TDL syntax used by `module()`, `class()`, `methods()`, constants, flags and structs, see [TDL Reference Manual](./TDL-Reference-Manual.md).