This documents how the C interface functions are generated.

## Rationale

We used to manually maintain individual source file for each mpi-level
function. For example, src/mpi/pt2pt/send.c for MPI_Send. Starting with
PR #4846, we are generating all these code with a python script and a set
of config files.

The interface is generated by `python maint/gen_binding_c.py`, executed
inside the autogen.sh. It loads master config file, then loads per category
custom config files and generate one file for each configured function in
the src/binding/c folder, as well as necessary src/binding/c/Makefile.mk,
src/binding/c/errnames.txt, and src/include/mpir_impl.h.

## Master API config file

The master config file -- maint/mpi_standards_api.txt is a direct
transcription from mpi-standard repository. It contains entries as following:

---- quote ----
MPI_Send:
    buf: BUFFER, constant=True, [initial address of send buffer]
    count: POLYXFER_NUM_ELEM_NNI, [number of elements in send buffer]
    datatype: DATATYPE, [datatype of each send buffer element]
    dest: RANK, [rank of destination]
    tag: TAG, [message tag]
    comm: COMMUNICATOR
---- end quote ----

Essentially for each function followed with a list a parameters. Each parameter
starts with the variable name, followed by a "kind", then a set of optional 
attributes, finally a description inside the square brackets.

## Language specific kind mapping

The mapping from parameter "kind" to language specific type is listed in
maint/api_mapping.txt with a simple format as:

---- quote ----
LIS_KIND_MAP:
    ACCESS_MODE: integer
    ...
BASE_C_KIND_MAP:
    ACCESS_MODE: int
    ...
SMALL_C_KIND_MAP:
    .base: BASE_C_KIND_MAP
    POLYDISPLACEMENT: int
    ...
BIG_C_KIND_MAP:
    .base: BASE_C_KIND_MAP
    POLYDISPLACEMENT: MPI_Aint
...
---- end quote ----

I.e. a map type heading followed with a set of kind: type listings. `BASE_C_KIND_MAP`
is only used to avoid duplication between SMALL and BIG versions.

Typically we should use the exact mapping from mpi standard, i.e. maint/api_mapping.txt
should be kept in-sync with upstream. But sometime, e.g. MPIX functions, we may need to
define our own kind mappings. We do that in `src/binding/custom_mapping.txt.


## Custom API config files

For any function to be generated, it has to be listed in one of the custom config
files in the src/binding/c folder, e.g. src/binding/c/pt2pt_api.txt. The filename
has to fit the `dir_api.txt` format. The root name designates the subfolder where
the code files will be generated in. For example, all functions listed in 
src/binding/c/pt2pt_api.txt will get generated in src/binding/c/pt2pt/ folder.

The custom config file follows the same format as master config files plust a few
additions. General format as following:

---- example ----
MPI_Example:
    .desc: a short description
/*
    Notes:
    Here we can supply custom man page notes explaining the semantics of the
    function.
*/
/*
    Multiple such "comment" blocks are allowed. The first block adds notes to the
    top of the man page (after the generated parameter info). The rest of the blocks
    are concatenated a follows the generated notes.

    Typical functions will all include .ThreadSafe and .Fortran notes, unless
    one or both of them are excluded by .skip directives.

    .N ExampleNote
    Any text is allowed. Refer to the sowing package manual.
*/
{ -- error_check -- list_of, parameters, that, are, checked
    /* custom error checking code when automatically generated validation is
     * insufficient */
    if (list_of < 0) {
        mpi_errno = ...;
        goto fn_fail;
    }
}
{ -- early_return --
    if (!param1) {
        goto fn_exit;
    }
}
{
    /* without the -- mark, this is the "body of routine" */
    mpi_errno = my_custom_code(...);
    if (mpi_errno) {
        goto fn_fail;
    }
}
---- end of example ----

The above example customizes the function, MPI_Example, with a short description,
extra man page notes, custom error checking code, early_return code, and custom
body of routine.

The customizations are place holders to allow flexibility dealing with arbitrary
complex code that it is too complex to deal with within the python script.
However, for most functions, most of the custom parts can be omitted. For example,
the following:

---- quote ----
MPI_Sendrecv:
    .desc: Sends and receives a message
---- end quote ----

is sufficient to generate src/binding/c/pt2pt/sendrecv.c with default man page,
default validations, and default body of routines, which simply calls
MPIR_Sendrecv_impl. When in doubt, double check the generated output and add
customizations when necessary.

For MPIX function, we'll need supply our own parameter information since they
will be missing from the standard master config file. Simply list the parameters
in the custom files. The parameters all start with 
    param_name: ...
while the directives all start with a '.', as
    .desc: ...

Supported directives include:
    .desc -- short description
    .skip -- a list of items that should skip auto generations, such as
             ThreadSafe, Fortran: these are standard notes
             validate-INDEX: the INDEX kind should be skipped
             validate-ANY: skip all validations
             initcheck: the function should skip MPIR_ERRTEST_INITIALIZED_ORDIE
             global_cs: the function should skip MPID_THREAD_CS_ENTER/EXIT

    .extra -- a list extra items that should be generated, such as
              SignalSafe, NotThreadSafe, collops: extra notes 
    .error -- a list extra error code that should listed in the document.
              The error codes associated with generated validation code are
              always documented automatically.

It is easy to extend with extra special directives. Simply specify it in the config
files with a `.name`, then implement it in `maint/local_python/binding_c.py`. The
difficult part is to keep it documented.
