The Croc Programming Language
Documentation helpers

Data Structures

struct  CrocDoc
 

Macros

#define croc_ex_doc_pop(d, idx)   (croc_ex_doc_popNamed((d), (idx), "children"))
 
#define CROC_DOC_MODULE(name)   CROC_DOC_HEADER("module", name) "\n"
 
#define CROC_DOC_FUNC(name)   CROC_DOC_HEADER("function", name) "\n"
 
#define CROC_DOC_CLASS(name)   CROC_DOC_HEADER("class", name) "\n"
 
#define CROC_DOC_NS(name)   CROC_DOC_HEADER("namespace", name) "\n"
 
#define CROC_DOC_FIELD(name)   CROC_DOC_HEADER("field", name) "\n"
 
#define CROC_DOC_FIELDV(name, val)   CROC_DOC_HEADER("field", name) "=" val "\n"
 
#define CROC_DOC_VAR(name)   CROC_DOC_HEADER("global", name) "\n"
 
#define CROC_DOC_VARV(name, val)   CROC_DOC_HEADER("global", name) "=" val "\n"
 
#define CROC_DOC_BASE(name)   "!base " name "\n"
 
#define CROC_DOC_PARAMANY(name)   "!param " name ":any\n"
 
#define CROC_DOC_PARAMANYD(name, def)   "!param " name ":any=" def "\n"
 
#define CROC_DOC_PARAM(name, type)   "!param " name ":" type "\n"
 
#define CROC_DOC_PARAMD(name, type, def)   "!param " name ":" type "=" def "\n"
 
#define CROC_DOC_VARARG   CROC_DOC_PARAM("vararg", "vararg")
 

Functions

void croc_ex_doc_init (CrocThread *t, CrocDoc *d, const char *file)
 
void croc_ex_doc_finish (CrocDoc *d)
 
void croc_ex_doc_push (CrocDoc *d, const char *docString)
 
void croc_ex_doc_popNamed (CrocDoc *d, word_t idx, const char *parentField)
 
void croc_ex_doc_mergeModuleDocs (CrocDoc *d)
 
void croc_ex_docGlobal (CrocDoc *d, const char *docString)
 
void croc_ex_docField (CrocDoc *d, const char *docString)
 
void croc_ex_docGlobals (CrocDoc *d, const char **docStrings)
 
void croc_ex_docFields (CrocDoc *d, const char **docStrings)
 

Detailed Description

These make it easier to write Croc documentation for native libraries.

You are encouraged to define aliases to the CROC_DOC_XXX macros to make your code shorter, as they can be very verbose otherwise.


Data Structure Documentation

struct CrocDoc

A structure used to keep track of doctables that are currently being built up.

Although the members are defined so you can allocate this structure on the stack, treat it as if it were an opaque type! Only pass it to the doc functions.

Macro Definition Documentation

#define croc_ex_doc_pop (   d,
  idx 
)    (croc_ex_doc_popNamed((d), (idx), "children"))

Like croc_ex_doc_popNamed, but passes "children" as the name of the parent field.

#define CROC_DOC_MODULE (   name)    CROC_DOC_HEADER("module", name) "\n"

Makes a module docstring header.

#define CROC_DOC_FUNC (   name)    CROC_DOC_HEADER("function", name) "\n"

Makes a function docstring header.

After this, you can use the parameter macros to list params.

#define CROC_DOC_CLASS (   name)    CROC_DOC_HEADER("class", name) "\n"

Makes a class docstring header.

Can be followed by zero or more base directives (CROC_DOC_BASE).

#define CROC_DOC_NS (   name)    CROC_DOC_HEADER("namespace", name) "\n"

Makes a namespace docstring header.

Can be followed by zero or one base directives (CROC_DOC_BASE).

#define CROC_DOC_FIELD (   name)    CROC_DOC_HEADER("field", name) "\n"

Makes a field docstring header.

#define CROC_DOC_FIELDV (   name,
  val 
)    CROC_DOC_HEADER("field", name) "=" val "\n"

Makes a field docstring header with an initializer value.

#define CROC_DOC_VAR (   name)    CROC_DOC_HEADER("global", name) "\n"

Makes a global variable docstring header.

#define CROC_DOC_VARV (   name,
  val 
)    CROC_DOC_HEADER("global", name) "=" val "\n"

Makes a global variable docstring header with an initializer value.

#define CROC_DOC_BASE (   name)    "!base " name "\n"

Used for listing the base class(es) and base namespace in class and namespace docstrings.

#define CROC_DOC_PARAMANY (   name)    "!param " name ":any\n"

Defines a parameter which can accept any type.

#define CROC_DOC_PARAMANYD (   name,
  def 
)    "!param " name ":any=" def "\n"

Defines a parameter which can accept any type and has a default value.

#define CROC_DOC_PARAM (   name,
  type 
)    "!param " name ":" type "\n"

Defines a parameter which accepts values of type type.

#define CROC_DOC_PARAMD (   name,
  type,
  def 
)    "!param " name ":" type "=" def "\n"

Defines a parameter which accepts values of type type and has a default value.

#define CROC_DOC_VARARG   CROC_DOC_PARAM("vararg", "vararg")

Should come as the last parameter, and indicates the function is variadic.

Function Documentation

void croc_ex_doc_init ( CrocThread t,
CrocDoc d,
const char *  file 
)

Initialize a CrocDoc structure.

Let's talk about how this doc system works. There is a stack of "in-progress" doctables, and this structure keeps track of that stack. The doctable stack is not on the thread's stack, it's kept elsewhere, so you don't have to worry about pushing and popping values on the thread's stack at all.

When you begin a doctable by using croc_ex_doc_push, it is pushed onto this doc stack. Then you can document any sub-members (like inside a module or class). Then, when you pop the doctable with croc_ex_doc_pop, it is attached to a program object that you provide, and added to its parent (unless there is none).

When you're done with the CrocDoc, call croc_ex_doc_finish on it.

Parameters
fileis the filename that will be added as the "file" member of every doctable created with this CrocDoc. You can use the FILE preprocessor macro for this if you like.
void croc_ex_doc_finish ( CrocDoc d)

Finishes the use of a CrocDoc by checking that the doctable stack is at the same height that it was when croc_ex_doc_init was called.

void croc_ex_doc_push ( CrocDoc d,
const char *  docString 
)

Pushes a new doctable onto the given CrocDoc's doctable stack.

This doc system uses a mini-language to describe the line, kind, name, and other attributes of documented items. Every doc string that you pass to this function must have a header, which means the first line of the docs must be a string of the following form:

!<line> <kind> <name>

It starts with an exclamation point, then the line number, a space, the kind of doctable it is (one of "module", "function", "class", "namespace", "global", and "field"), another space, and then everything to the end of the line is treated as the name.

Some kinds of doctables can have further lines that start with an exclamation to give more info, and others have more info on the header line itself. Regardless, the first line of the docstring that doesn't start with an exclamation point is treated as the beginning of the document text itself, and it can contain all the stuff a Croc doc comment can.

Trying to write these headers out manually can be a pain (especially since the parser for them is very strict and doesn't allow things like extra whitespace), so there are some macros which will make it easier to write them. Using the macros will also insulate you against future changes in the syntax of the docstrings.

Some examples:

const char* ModuleDocs =
CROC_DOC_MODULE("mymodule")
"These are docs for my module! It has some things in it.";
const char* MyClassDocs =
CROC_DOC_CLASS("MyClass") CROC_DOC_BASE("SomeOtherClass")
"This class derives from SomeOtherClass!";
const char* myFuncDocs =
CROC_DOC_FUNC("myFunc") CROC_DOC_PARAM("x", "int")
"This is my function. It takes one parameter.\n\
\\param[x] is the parameter.\n\
\\returns something. I'm sorry you have to double up the backslashes, and that\n\
you have to put the silly line endings on, and inserting a literal backslash takes\n\
four \\\\ backslashes, buuuut hopefully you'll just be using the C binding from\n\
another language and not from C itself. Hopefully.";

Also, the docs after the header can just be the word "ditto", which will work exactly the same as in Croc (error checking included).

Parameters
docStringis a docstring of the form described above.
void croc_ex_doc_popNamed ( CrocDoc d,
word_t  idx,
const char *  parentField 
)

Pops a doctable off the doctable stack.

Then, if the value on d's thread's stack at idx is a function, class, or namespace, calls the Croc doc decorator function on it with the doctable as its parameter.

Then, if there is still a doctable on the stack, appends the popped doctable to the end of the array in the previous doctable's parentField field (creating that array if necessary).

void croc_ex_doc_mergeModuleDocs ( CrocDoc d)

Expects a module doctable on top of d's thread's stack (called the "submodule"), and a doctable on top of d's doctable stack (called the main module).

This appends the contents of the submodule doctable's children field to the main module doctable's children field.

This is useful in fairly limited scenarios. The standard library docs use this to merge the documentation in modules that are written partly in native code and partly in script code. Maybe you'll find it useful for that too!

void croc_ex_docGlobal ( CrocDoc d,
const char *  docString 
)

Given a docstring, pushes a doctable with it, then looks up the global with the name given in the docstring, calls croc_ex_doc_pop on it, and pops it from the stack.

This has the effect of documenting one global in the current namespace.

void croc_ex_docField ( CrocDoc d,
const char *  docString 
)

Similar to croc_ex_docGlobal, but instead of looking up a global, gets a field out of the object on top of d's thread and docs that.

void croc_ex_docGlobals ( CrocDoc d,
const char **  docStrings 
)

Takes a NULL-terminated array of docstrings and calls croc_ex_docGlobal on all of them in order.

void croc_ex_docFields ( CrocDoc d,
const char **  docStrings 
)

Takes a NULL-terminated array of docstrings and calls croc_ex_docField on all of them in order.