
[para] To get around this limitation the commands in this section
enable users of [package critcl] to extend the set of argument and
result types understood by [cmd critcl::cproc]. In other words, they
allow them to define their own, custom, types.

[list_begin definitions]

[comment {- - -- --- ----- -------- ------------- ---------------------}]
[call [cmd ::critcl::has-resulttype] [arg name]]

This command tests if the named result-type is known or not.

It returns a boolean value, [const true] if the type is known and
[const false] otherwise.

[comment {- - -- --- ----- -------- ------------- ---------------------}]
[call [cmd ::critcl::resulttype] [arg name] [arg body] [opt [arg ctype]]]

This command defines the result type [arg name], and associates it
with the C code doing the conversion ([arg body]) from C to Tcl.

The C return type of the associated function, also the C type of the
result variable, is [arg ctype]. This type defaults to [arg name] if
it is not specified.

[para] If [arg name] is declared already an error will be thrown.

[emph Attention!] The standard result type [const void] is special as
it has no accompanying result variable. This cannot be expressed
by this extension command.

[para] The [arg body]'s responsibility is the conversion of the
functions result into a Tcl result and a Tcl status. The first has to
be set into the interpreter we are in, and the second has to be
returned.

[para] The C code of [arg body] is guaranteed to be called last in the
wrapper around the actual implementation of the [cmd cproc] in
question and has access to the following environment:

[list_begin definitions]
[def [var interp]] A Tcl_Interp* typed C variable referencing the
                   interpreter the result has to be stored into.
[def [var rv]] The C variable holding the result to convert, of type
               [arg ctype].
[list_end]

As examples here are the definitions of two standard result types:

[example {
    resulttype int {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(rv));
	return TCL_OK;
    }

    resulttype ok {
	/* interp result must be set by cproc body */
	return rv;
    } int
}]

[comment {- - -- --- ----- -------- ------------- ---------------------}]
[call [cmd ::critcl::resulttype] [arg name] [method =] [arg origname]]

This form of the [cmd resulttype] command declares [arg name] as an
alias of result type [arg origname], which has to be defined
already. If this is not the case an error is thrown.


[comment {- - -- --- ----- -------- ------------- ---------------------}]
[call [cmd ::critcl::has-argtype] [arg name]]

This command tests if the named argument-type is known or not.

It returns a boolean value, [const true] if the type is known and
[const false] otherwise.

[comment {- - -- --- ----- -------- ------------- ---------------------}]
[call [cmd ::critcl::argtype] [arg name] [arg body] [opt [arg ctype]] [opt [arg ctypefun]]]

This command defines the argument type [arg name], and associates it
with the C code doing the conversion ([arg body]) from Tcl to C

The C type of the variable to hold the conversion result is
[arg ctype] and the type of the function argument itself is
[arg ctypefun].  Both types default to [arg name] if they are not
specified (or the empty string).

[para] If [arg name] is declared already an error will be thrown.

[para] The [arg body]'s responsibility is the conversion of a
command's Tcl_Obj* argument into a C value for the underlying
function and its storage in a helper variable.

[para] The C code of [arg body] is guaranteed to be called inside of a
separate C code block (thus allowing the use of local variables) which
has access to the following environment:

[list_begin definitions]
[def [var interp]] A Tcl_Interp* typed C variable referencing the
                   interpreter the code is running in.
[def [const @@]] A placeholder for the Tcl_Obj*-valued C expression
     	    	 providing the value of the argument to convert.

[def [const @A]] A placeholder for the name of the C variable to store the
     	    	 converted argument into.
[list_end]

As examples here are the definitions of two standard argument types:

[example {
    argtype int {
	if (Tcl_GetIntFromObj(interp, @@, &@A) != TCL_OK) return TCL_ERROR;
    }

    argtype float {
	double t;
	if (Tcl_GetDoubleFromObj(interp, @@, &t) != TCL_OK) return TCL_ERROR;
	@A = (float) t;
    }
}]

[comment {- - -- --- ----- -------- ------------- ---------------------}]
[call [cmd ::critcl::argtype] [arg name] [method =] [arg origname]]

This form of the [cmd argtype] command declares [arg name] as an alias
of argument type [arg origname], which has to be defined already. If
this is not the case an error is thrown.

[comment ---------------------------------------------------------------------]
[call [cmd ::critcl::argtypesupport] [arg name] [arg code] [opt [arg guard]]]

This command defines a C code fragment for the already defined
argument type [arg name] which will be inserted before all functions
using that type. Its purpose is the definition of any supporting C
types needed by the argument type.

If the type is used by many functions the system ensures that only the
first of the multiple insertions of the code fragment is active, and
the others disabled.

The guard identifier is normally derived from [arg name], but can also
be set explicitly, via [arg guard]. This latter allows different
custom types to share a common support structure without having to
perform their own guarding.

[comment ---------------------------------------------------------------------]
[call [cmd ::critcl::argtyperelease] [arg name] [arg code]]

This command defines a C code fragment for the already defined
argument type [arg name] which will be inserted whenever the worker
function of a [cmd critcl::cproc] returns to the shim. It is the
responsibility of this fragment to unconditionally release any
resources the [cmd critcl::argtype] conversion code allocated.

An example of this are the [emph variadic] types for the support of
the special, variadic [arg args] argument to [cmd critcl::cproc]'s.
They allocate a C array for the collected arguments which has to be
released when the worker returns. This command defines the C code
for doing that.

[comment {- - -- --- ----- -------- ------------- ---------------------}]
[list_end]
