-
-
Notifications
You must be signed in to change notification settings - Fork 2
Embedded Document Formatting
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.
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.
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.
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.
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-
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.
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. |
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>
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.