/ C-API: Options


A Jsi_OptionSpec array provides details of fields in a struct. This information is used for translating values to/from and from C struct fields, both for Javascript and by the Sqlite C-API.

A Jsi_OptionSpec array specifies for a struct field the name, type, offset, help string, etc. This specification is passed, along with a pointer to the actual data, to Jsi_OptionProcess() and Jsi_OptionConf().

Example Usage

The following example is a subset of the Jsi Sqlite command:

static const char *mtxStrs[] = { "default", "none", "full", 0 };

static Jsi_OptionSpec Options[] =
    JSI_OPT(INT,    SqliteDb, debug,    .help="Set debugging level"),
    JSI_OPT(CUSTOM, SqliteDb, execOpts, .help="Default options for exec", .custom=&Jsi_OptSwitchSuboption, .data=ExecFmtOptions),

    JSI_OPT(INT,    SqliteDb, maxStmts, .help="Max cache size for compiled statements"),
    JSI_OPT(BOOL,   SqliteDb, readonly, .help="Database is readonly", .flags=JSI_OPT_INIT_ONLY ),
    JSI_OPT(VALUE,  SqliteDb, vfs,      .help="VFS to use", .flags=JSI_OPT_INIT_ONLY),
    JSI_OPT(CUSTOM, SqliteDb, mutex,    .help="Mutex type to use", .custom=&Jsi_OptSwitchEnum, .data=mtxStrs),

if (Jsi_OptionsProcess(interp, Options, optObj, &opts, 0) < 0) {
     return JSI_ERROR;
if (opts.debug)
    puts("Sqlite created");

Field Specification

Options are specified using the JSI_OPT() macro. The first 3 arguments are TYPE,STRUCT,NAME, where the NAME is a field name in STRUCT. Additional attributes can be specified using ".name=value" form.

Option Types

The option TYPE is one of:

BOOLboolBoolean (stored in a "char" variable).
INTintAn integer.
UINTuintAn unsigned integer.
LONGlongAn long integer.
ULONGulongAn long unsigned integer.
SHORTshortAn short integer.
USHORTushortAn short unsigned integer.
INT8int8_tAn 8-bit integer.
INT16int16_tA 16-bit integer.
INT32int32_tA 32-bit integer.
INT64int64_tA 64-bit integer.
UINT8uint8_tAn unsigned 8-bit integer.
UINT16uint16_tAn unsigned 16-bit integer.
UINT32uint32_tAn unsigned 32-bit integer.
UINT64uint64_tAn unsigned 64-bit integer.
SIZE_Tsize_tAn size_t integer.
INTPTR_Tintptr_tAn pointer sized integer.
UINTPTR_Tuintptr_tAn pointer sized unsigned integer.
FLOATfloagA floating point.
DOUBLEdoubleDouble floating point.
LDOUBLEldoubleLong double floating point.
DSTRINGJsi_DStringA Jsi_DString value.
STRKEYconst char*A char* string key.
STRBUFchar[]A fixed size char string buffer.
VALUEJsi_Value*A Jsi_Value.
STRINGJsi_Value*A Jsi_Value referring to a string.
VARJsi_Value*A Jsi_Value referring to a variable.
OBJJsi_Value*A Jsi_Value referring to an object.
ARRAYJsi_Value*A Jsi_Value referring to an array.
FUNCJsi_Value*A Jsi_Value referring to a function.
TIME_Ttime_tA date variable, milliseconds since 1970 stored in a time_t/long.
TIME_DdoubleA date variable, milliseconds since 1970 stored in a Jsi_Number/double.
TIME_Wint64_tA date variable, milliseconds since 1970 stored in a Jsi_Wide/64 bit integer.
CUSTOMvoid*Custom parsed value.


The following flags are predefined for individual items in an OptionSpec:

JSI_OPT_INIT_ONLYAllow set only at init, disallow update/conf
JSI_OPT_NO_DUPVALUEValues/Strings are not to be duped (dangerous)
JSI_OPT_READ_ONLYValue can never be set.
JSI_OPT_DIRTY_FIELDUsed for DB update.
JSI_OPT_IS_SPECIFIEDUser set the option.
JSI_OPT_DB_IGNOREField is not to be used for DB.
JSI_OPT_CUST_NOCASEIgnore case (eg. for ENUM and BITSET)
JSI_OPT_CUST_FLAG2Reserved for custom flags
JSI_OPT_CUST_FLAG2Reserved for custom flags
JSI_OPT_CUST_FLAG2Reserved for custom flags

Custom Types

Custom types provide parsing/formatting functions to interpret javascript data to/from a C struct-field. Again, the best example is the Jsi source itself.

The following predefined custom types come builtin:

Jsi_OptSwitchEnumEnum matchstringlist
Jsi_OptSwitchBitsetSet of zero or more enum matchstringlist
Jsi_OptSwitchValueVerifyProvide callback to verify Jsi_Value* is correct<Callback>
Jsi_OptSwitchSuboptionRecursive sub-option support<sub-Option>

Refer to the Jsi source for example usage and declarations.

OptionSpec Fields

The following fields are defined in Jsi_OptionSpec:

typeenumField type (from above)
namechar*Name of field
offsetintOffset in array
sizeconst char*Sizeof of field.
iniValunionUsed for compile-time validation
flagsintFlags (from above)
customJsi_OptionCustom*Custom parsing struct
datavoid*User data for custom options.
helpchar*Short 1 line help string.
infochar*Longer command description: re-define JSI_DETAIL macro to compile-out.
initconst char*Initial string value (used by info.cmds).
extNameconst char*External name: used by the DB interface.

The first five fields are implicitly set by the JSI_OPT() macro. The JSI_END() macro also sets extName.

All others are available for setting by the user with .FIELD=VALUE notation.

Parse Flags

The following flags are available for use with Jsi_OptionProcess/Jsi_OptionConf:

JSI_OPTS_IS_UPDATEThis is an update/conf (do not reset the specified flags)
JSI_OPTS_IGNORE_EXTRAIgnore extra members not found in spec
JSI_OPTS_FORCE_STRICTComplain about unknown options, even when noStrict is used.
JSI_OPTS_PREFIXAllow matching unique prefix of object members.
JSI_OPTS_VERBOSEDump verbose options

Compile-time Validation

Compile-time validation checks option values to ensure that stated type and the field type actually match. If they don't, the program will likely crash at runtime. The implementation uses an implicit assignment to iniVal which should generate a compiler warning if there is a type mismatch.

Here is an example:

typedef struct {
    int val;
} MyData;

Jsi_OptionSpec opts[] = {
    JSI_OPT(STRING, MyData, val),
    JSI_OPT_END(    MyData)

which should generate:

test.c:7:6: warning: initialization from incompatible pointer type [enabled by default]
test.c:7:6: warning: (near initialization for ‘opts[0].iniVal.ini_STRING’) [enabled by default]

Is Specified

When a user provides a value for an option, the flag JSI_OPT_IS_SPECIFIED is set in the option flags. Call Jsi_OptionChanged to determine if an option was specified. (Note: there are known concurrency issues with this feature).

Note: The Jsi header file jsi.h and source are best consulted for complete examples.