theKernel 10.0
Loading...
Searching...
No Matches
MkKernel_Overload_C_API

MkKernel PACKAGE - Function overloading or method overloading is the ability to create multiple functions of the same name with different implementations.

+ Collaboration diagram for MkKernel_Overload_C_API:

MkKernel PACKAGE - Function overloading or method overloading is the ability to create multiple functions of the same name with different implementations.

MkKernel_C_API

Calls to an overloaded function will run a specific implementation of that function appropriate to the context of the call, allowing one function call to perform different tasks depending on context.

jvmkkernel provide the overload-technology to all programming languages even for languages that don't support overloading by default.

To implement the overloading in a non-overload-ready language the _XXX postfix is supported.

There are 4 basic scenarios which are support by overloading:

  1. Support the default-argument by adding more or less arguments.
  2. Support the error-handling by catch and raise the default-error.
  3. Support the callback-implementation together with the interface technology.
  4. Support the singleton-instance as internal with default-value

The implementation depend on the overload-type

default-argument
The default-argument is implemented by jvmkkernel using the __parser__default c-language extension.
error-handling
The error-handling react on the library-default-error, for jvmkkernel it is the MkErrorE.
callback-implementation
The callback-implementation is implemented by jvmkkernel using the __parser__callback_name c-language extension.
singleton-instance
A singleton-instance is an instance which only exists once per thread. A typical singleton-instance is the MkRuntimeRLS or the MkRuntimeS::error_mk. The A singleton-instance is implemented by jvmkkernel using the __parser__internal together with __parser__default or direct by the overload-postprocessor (MkRuntimeS::error_mk).

Example from MkBufferListC_def_mk.h a function with 2 default arguments and an error as return

MK_BFL const bfl,
MK_STRN const opt,
bool const defval __parser__(default=false),
bool const onlyFirst __parser__(default=true),
bool * const val_out

The MkBufferListCheckOptionBOL funtion ...

enum MkErrorE MkBufferListCheckOptionBOL(MK_BFL const, MK_STRN const, bool const, bool const, bool * const);
#define MkBufferListCheckOptionBOL(...)
MkErrorE
collection for the different error-codes …
const MK_STRB * MK_STRN
constant string pointer data-type
The CLASS used to store a list of MkBufferS items into a flat array…

has 2 default-argument overload ...

enum MkErrorE MkBufferListCheckOptionO_4(MK_BFL const, MK_STRN const, bool const, bool * const);
enum MkErrorE MkBufferListCheckOptionO_3(MK_BFL const, MK_STRN const, bool * const);
The number after the last _ is the number of arguments of the function.

and 3 error-handling overload ...

void MkBufferListCheckOptionBOL_E(MK_BFL const, MK_STRN const, bool const, bool const, bool * const);
void MkBufferListCheckOptionO_C(MK_BFL const, MK_STRN const, bool const, bool const, bool * const) { ... }
bool MkBufferListCheckOptionBOL_e(MK_BFL const, MK_STRN const, bool const, bool const);
#define MkBufferListCheckOptionBOL_e(...)
#define MkBufferListCheckOptionBOL_E(...)

Summary: The default-postfix is defined as:

_N
N is a number starting from 0 and represent the final number of arguments supported by the function.

Example from jvmkkernel : react on error, old and new approach … All functions who return an MkErrorE get a MkErrorCheck wrapper. This wrapper check for the return code MK_ERROR and do proper error-handling:

// OLD: the following line of code:
MK_BUF buf;
MkErrorCheck ( MqReadBUF (ctx, &buf) );
// NEW: can be rewritten into:
// check return from MqReadBUF and jump to 'error' label on error
// '_E' replace 'MkErrorCheck(...)'
MqReadBUF_E (ctx, &buf);
...
// put MqReadBUF into an 'if' and eval code *after* function (goto somewhere) on error
// '_C' replace 'if (MkErrorCheckI(...))'
MqReadU_C (ctx, &buf) goto somewhere;
...
// a function who return a update a single-value as pointer (buf) *AND* return an error is modified to
// return this single-value *OR* jump to label 'error' on error
// '_e' replace 'MK_EMBEDDED(...)'
MK_BUF buf = MqReadBUF_e (ctx);
somewhere:
// do something ...
error:
// do something ...
#define MkErrorCheck(err)
check return-code and goto error on error …
The ABSTRACT-CLASS used to store a native-type-data-item defined by PRIMITIVE TYPE …

Summary: The error-postfix is defined as:

_E
On MK_ERROR the function jump to a label called error: to do proper error handing. There is only one error: per context. The goal is to do all the error-handling on one place and distinguish different errors by different flags like initialization-status of a variable.
_C
React on MK_ERROR like _E but let the programmer choose how to react on error
_e
React on MK_ERROR like _E together with an reference-return-value like bool * const.
Rewrite the function to return the reference OR jump to an error: on MK_ERROR.

Example from kernel_mk.h function with MkRuntimeRLS-singleton

MK_STRN const pathName,
bool const includeExtension

The singleton-instance MK_RT will be replaced by the default-value (MkRuntimeRLS)

#define MkSysBasename_2(pathName,includeExtension) MkSysBasename(MK_RT_CALL,pathName,includeExtension)

Example from kernel_mk.h function with MkErrorS-singleton

MK_ERR const err,
MK_STRN const callfunc __parser__(default=F#FUNC),
MK_I32 const callline __parser__(default=F#LINE),
bool const force __parser__(default=B#false)
#define MkErrorReset_0M() MkErrorReset_4M(NULL,__func__,__LINE__,0);
#define MkErrorResetFORCE_1(m) MkErrorReset_4M(m,__func__,__LINE__,1);
#define MkErrorResetFORCE_0() MkErrorReset_4M(NULL,__func__,__LINE__,1);
#define MkErrorReset_4X(x,...) MkErrorReset(MkErrorFORMAT_1X(x),__VA_ARGS__)
#define MkErrorReset_1X(x) MkErrorReset_4X(x,__func__,__LINE__,0)

Any MkErrorS-instance has additional overload functions because the MkErrorS has the ability to be personalized with an object. The MkErrorS-formatter reformat the MkErrorS as error-from-object.

The MkErrorS-singleton overload functions from MkErrorReset:

#define MkErrorReset_3E(...) MkErrorReset(&MkERROR,__VA_ARGS__)
#define MkErrorReset_4M(m,...) MkErrorReset(MkErrorFORMAT_1M(m),__VA_ARGS__)
#define MkErrorReset_3(err,callfunc,callline) MkErrorReset(err,callfunc,callline,false)
#define MkErrorReset_2E(callfunc,callline) MkErrorReset_3E(callfunc,callline,false)
#define MkErrorReset_3M(err,callfunc,callline) MkErrorReset_4M(err,callfunc,callline,false)
#define MkErrorReset_2(err,callfunc) MkErrorReset(err,callfunc,__LINE__,false)
#define MkErrorReset_1E(callfunc) MkErrorReset_3E(callfunc,__LINE__,false)
#define MkErrorReset_2M(err,callfunc) MkErrorReset_4M(err,callfunc,__LINE__,false)
#define MkErrorReset_1(err) MkErrorReset(err,__func__,__LINE__,false)
#define MkErrorReset_0E() MkErrorReset_3E(__func__,__LINE__,false)
#define MkErrorReset_1M(err) MkErrorReset_4M(err,__func__,__LINE__,false)
#define MkErrorReset_E(...) MkErrorCheck(MkErrorReset(__VA_ARGS__))
#define MkErrorReset_C(...) if (MkErrorCheckI(MkErrorReset(__VA_ARGS__)))

Summary: The error-sinleton is defined as:

_NE
A function with N arguments that uses the standard error MkERROR and is resolved via runtime-cache.
_NM
A function with N arguments using standard error MkERROR personalized with first argument and resolved by run-time-cast (slow but standard for error handling)
_NX
A function with N arguments, using the standard error MkERROR, personalized with the first argument and resolved by the compile-time-cast (fast, but not preferred for error handling)