jsish
Check-in [2630f8db5e]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Release "2.5.19". Fix JSON double format precision. CData changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:2630f8db5ea360bad9e89209626f42871199203d
User & Date: pmacdona 2018-10-11 00:59:19
Context
2018-10-11
02:26
Fix VFS bug check-in: ebcd5f87dd user: pmacdona tags: trunk
00:59
Release "2.5.19". Fix JSON double format precision. CData changes. check-in: 2630f8db5e user: pmacdona tags: trunk
2018-10-06
23:38
Release "2.5.18". Cleanup option parse messages. Implement CData checking of function option argument. Various cleanups. Fix bit fields. check-in: f99f541132 user: pmacdona tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to c-demos/cdata/cdatatest.jsi.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
...
397
398
399
400
401
402
403
404
405
406
407
408
"use strict";

var alpha, beta, tree, tree2, tree3, hash, hash2, hash3, pest, flower, n, bees;

;'\n====DEFINES====';

// String form brief: split on comma.
;CEnum.define('Fruit', 'apple,banana,orange,grape=9');

// String form with comments used as help field: split on newline.
CEnum.define('Vegetable', '
    corn=0, // My favorite
    peas=2, // Your favorite
    potato=-1
');

// Object form.
CEnum.define({name:'Herd'}, [
    {name:'sheep'},
    {name:'goat', value:3, help:'set a value'},
    {name:'cow'}]
);


// String form brief: split on semicolon.
;CStruct.define('Bee', 'int s:4; int r:3; int t=8; Fruit k;');

// String form with comments used as help field: split on newline.
CStruct.define('Pest', '
    int x=3;    // int field.
    Bee b;      // A sub-struct
    int y=5;
');

CStruct.define('Flower', '
    int x=3;        // int field.
    int t[3];       // Simple array
    Bee b[4];       // A struct array
    Herd herd@;     // Enum bitset. 
');

// Object form.
CStruct.define(
    {name:'Bkey', help:'Struct to use for a key'}, [
        {name:'a', type:'int', help:'first key field'},
        {name:'b', type:'int', help:'second key field'}]
);
        
alpha  = new CData('Bee');          // Struct
beta   = new CData('Bee[10]');      // Array
................................................................................
delete hash3;
delete beta;
delete alpha;
delete tree3;
delete tree;
delete tree2;
delete pest;
;CStruct.undef('Pest');

;'\nTODO';
try {
;CStruct.undef('Bee');
} catch(e) {}
try {
;CEnum.undef('Fruit');
} catch(e) {}


/*
=!EXPECTSTART!=
'
====DEFINES===='
CEnum.define('Fruit', 'apple,banana,orange,grape=9') ==> undefined
CStruct.define('Bee', 'int s:4; int r:3; int t=8; Fruit k;') ==> undefined
pest   = new CData('Pest') ==> "#CData_9"
flower = new CData('Flower') ==> "#CData_10"
bees   = new CData({structName:'Bee', arrSize:10, help:'An array of bees'}) ==> "#CData_11"
'
====Enum===='
CEnum.names() ==> [ "Fruit", "Herd", "Vegetable" ]
CEnum.names('Fruit') ==> [ "apple", "banana", "orange", "grape" ]
................................................................................
'+schema+'
);') ==> undefined
db.query('INSERT INTO Bee %s',{cdata:'beta'}) ==> 10
db.query('SELECT %s FROM Bee',{cdata:'beta'}) ==> 10
'
====Cleanup===='
Info.named('CData') ==> [ "#CData_8", "#CData_4", "#CData_9", "#CData_5", "#CData_1", "#CData_6", "#CData_2", "#CData_10", "#CData_7", "#CData_3", "#CData_11" ]
CStruct.undef('Pest') ==> undefined
'
TODO'
CStruct.undef('Bee') ==> CEnum.undef('Fruit') ==> =!EXPECTEND!=
*/







|


|






|







|


|





|







|







 







|



|


|







|
|







 







|


|

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
...
397
398
399
400
401
402
403
404
405
406
407
408
"use strict";

var alpha, beta, tree, tree2, tree3, hash, hash2, hash3, pest, flower, n, bees;

;'\n====DEFINES====';

// String form brief: split on comma.
;CEnum('Fruit', 'apple,banana,orange,grape=9');

// String form with comments used as help field: split on newline.
CEnum('Vegetable', '
    corn=0, // My favorite
    peas=2, // Your favorite
    potato=-1
');

// Object form.
CEnum({name:'Herd'}, [
    {name:'sheep'},
    {name:'goat', value:3, help:'set a value'},
    {name:'cow'}]
);


// String form brief: split on semicolon.
;CStruct('Bee', 'int s:4; int r:3; int t=8; Fruit k;');

// String form with comments used as help field: split on newline.
CStruct('Pest', '
    int x=3;    // int field.
    Bee b;      // A sub-struct
    int y=5;
');

CStruct('Flower', '
    int x=3;        // int field.
    int t[3];       // Simple array
    Bee b[4];       // A struct array
    Herd herd@;     // Enum bitset. 
');

// Object form.
CStruct(
    {name:'Bkey', help:'Struct to use for a key'}, [
        {name:'a', type:'int', help:'first key field'},
        {name:'b', type:'int', help:'second key field'}]
);
        
alpha  = new CData('Bee');          // Struct
beta   = new CData('Bee[10]');      // Array
................................................................................
delete hash3;
delete beta;
delete alpha;
delete tree3;
delete tree;
delete tree2;
delete pest;
;CStruct.remove('Pest');

;'\nTODO';
try {
;CStruct.remove('Bee');
} catch(e) {}
try {
;CEnum.remove('Fruit');
} catch(e) {}


/*
=!EXPECTSTART!=
'
====DEFINES===='
CEnum('Fruit', 'apple,banana,orange,grape=9') ==> undefined
CStruct('Bee', 'int s:4; int r:3; int t=8; Fruit k;') ==> undefined
pest   = new CData('Pest') ==> "#CData_9"
flower = new CData('Flower') ==> "#CData_10"
bees   = new CData({structName:'Bee', arrSize:10, help:'An array of bees'}) ==> "#CData_11"
'
====Enum===='
CEnum.names() ==> [ "Fruit", "Herd", "Vegetable" ]
CEnum.names('Fruit') ==> [ "apple", "banana", "orange", "grape" ]
................................................................................
'+schema+'
);') ==> undefined
db.query('INSERT INTO Bee %s',{cdata:'beta'}) ==> 10
db.query('SELECT %s FROM Bee',{cdata:'beta'}) ==> 10
'
====Cleanup===='
Info.named('CData') ==> [ "#CData_8", "#CData_4", "#CData_9", "#CData_5", "#CData_1", "#CData_6", "#CData_2", "#CData_10", "#CData_7", "#CData_3", "#CData_11" ]
CStruct.remove('Pest') ==> undefined
'
TODO'
CStruct.remove('Bee') ==> CEnum.remove('Fruit') ==> =!EXPECTEND!=
*/

Changes to src/jsi.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.....
21399
21400
21401
21402
21403
21404
21405




21406
21407
21408
21409
21410
21411
21412
.....
21434
21435
21436
21437
21438
21439
21440
21441
21442
21443
21444
21445
21446
21447
21448
.....
21474
21475
21476
21477
21478
21479
21480
21481
21482
21483
21484
21485
21486
21487
21488
21489
.....
21770
21771
21772
21773
21774
21775
21776


21777
21778
21779
21780
21781
21782
21783
.....
21807
21808
21809
21810
21811
21812
21813
21814
21815
21816
21817
21818
21819
21820
21821
.....
27019
27020
27021
27022
27023
27024
27025


27026
27027
27028
27029
27030
27031
27032
.....
35612
35613
35614
35615
35616
35617
35618

35619
35620
35621
35622
35623
35624
35625
35626
35627



35628
35629
35630
35631

35632
35633
35634
35635
35636
35637
35638
35639
.....
56194
56195
56196
56197
56198
56199
56200

56201
56202
56203
56204
56205
56206
56207
56208
56209
56210
56211
56212
56213
56214
56215
56216
.....
56490
56491
56492
56493
56494
56495
56496
56497
56498
56499
56500
56501
56502
56503
56504
.....
56716
56717
56718
56719
56720
56721
56722

56723
56724
56725
56726
56727

56728
56729
56730
56731
56732
56733
56734
56735
56736
56737
.....
57215
57216
57217
57218
57219
57220
57221
57222
57223
57224
57225
57226
57227
57228
57229
.....
57265
57266
57267
57268
57269
57270
57271
57272
57273
57274
57275

57276
57277
57278
57279
57280
57281
57282
.....
57444
57445
57446
57447
57448
57449
57450


57451
57452
57453
57454
57455
57456
57457
57458
57459
/* jsi.h : External API header file for Jsi. */
#ifndef __JSI_H__
#define __JSI_H__

#define JSI_VERSION_MAJOR   2
#define JSI_VERSION_MINOR   5
#define JSI_VERSION_RELEASE 18

#define JSI_VERSION (JSI_VERSION_MAJOR + ((Jsi_Number)JSI_VERSION_MINOR/100.0) + ((Jsi_Number)JSI_VERSION_RELEASE/10000.0))

#ifndef JSI_EXTERN
#define JSI_EXTERN extern
#endif

................................................................................
    static char lastMsg[JSI_BUFSIZ/2] = "";
    static int lastCnt = 0;
    static Jsi_Interp *LastInterp = NULL;
    Jsi_Interp *lastInterp = LastInterp;
    const char *emsg = buf, *mt;
    int islog, line = 0, lofs = 0, noDups=0;
    bool isHelp = !Jsi_Strncmp(format, "...", 3);




    if (interp==NULL)
        interp = jsiIntData.mainInterp;
    LastInterp = interp;
    if (lastInterp != interp)
        noDups = 1;
    const char *curFile = jsi_GetCurFile(interp);
    /* Filter out try/catch (TODO: and non-syntax errors??). */
................................................................................
    }
    if (code == JSI_LOG_ERROR)
        interp->logErrorCnt++;
    mt = (code <= JSI_LOG_PARSE ? jsi_LogCodes[code] : "");
    if (isHelp) mt = "help";
    assert((JSI_LOG_PARSE+2) == (sizeof(jsi_LogCodes)/sizeof(jsi_LogCodes[0])));
    if (!Jsi_Strchr(format,'\n')) term = "\n";
    char *ss = interp->lastPushStr;
    if (jsi_IsStrictMode(interp) && interp->lastParseOpt)
        ss = (char*)Jsi_ValueToString(interp, interp->lastParseOpt, NULL);
    if (code != JSI_LOG_INFO && interp && ss && ss[0]) {
        char psbuf[JSI_BUFSIZ/6];
        if (Jsi_Strchr(ss,'%')) {
            char *s = ss, *sd = psbuf;
            int plen=0, llen = sizeof(psbuf)-2;
................................................................................
            line = interp->curIp->Line;
            lofs = interp->curIp->Lofs;
            if (line<=0)
                line = interp->framePtr->line;
        }
    }
    islog = (interp->parent && interp->debugOpts.msgCallback && code != JSI_LOG_BUG);
    Jsi_OptionSpec *oep = interp->parseMsgSpec;
    const char *pps = "";
    Jsi_DString pStr;
    Jsi_DSInit(&pStr);
    if (oep) {
        if (oep->id != JSI_OPTION_CUSTOM || !oep->custom)
            pps = Jsi_DSPrintf(&pStr, "for option \"%s\": ", oep->name);
        else {
            Jsi_OptionCustom* cust = Jsi_OptionCustomBuiltin(oep->custom);
................................................................................
        Jsi_DSAppend(dStr, "\"", str, "\"", NULL);
    Jsi_DSAppend(dStr, ":", NULL);
    ow->depth++;
    Jsi_RC rc = jsiValueGetString(tree->opts.interp, v, dStr, ow);
    ow->depth--;
    return rc;
}



/* Format value into dStr.  Toplevel caller does init/free. */
static Jsi_RC jsiValueGetString(Jsi_Interp *interp, Jsi_Value* v, Jsi_DString *dStr, objwalker *owPtr)
{
    char buf[100], *str;
    Jsi_DString eStr;
    Jsi_DSInit(&eStr);
................................................................................
            } else if (Jsi_NumberIsInteger(num)) {
                Jsi_NumberItoA10((Jsi_Wide)num, buf, sizeof(buf));
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsWide(num)) {
                snprintf(buf, sizeof(buf), "%" PRId64, (Jsi_Wide)num);
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsNormal(num) || Jsi_NumberIsSubnormal(num)) {
                snprintf(buf, sizeof(buf), "%" JSI_NUMGFMT, num);
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsNaN(num)) {
                Jsi_DSAppend(dStr, "NaN", NULL);
            } else {
                int s = Jsi_NumberIsInfinity(num);
                if (s > 0) Jsi_DSAppend(dStr, "+Infinity", NULL);
                else if (s < 0) Jsi_DSAppend(dStr, "-Infinity", NULL);
................................................................................
{
    Jsi_Number r = INFINITY;
    return (Jsi_NumberIsNaN(value)==0 && value != r && r != -value);
}

void Jsi_NumberDtoA(Jsi_Number value, char* buf, int bsiz, int prec)
{


    if (Jsi_NumberIsNaN(value))
        Jsi_Strcpy(buf,"NaN");
    else
        snprintf(buf, bsiz, "%.*" JSI_NUMGFMT, prec, value);
}

bool Jsi_NumberIsEqual(Jsi_Number n1, Jsi_Number n2)
................................................................................


Jsi_Value *Jsi_CommandCreateSpecs(Jsi_Interp *interp, const char *name, Jsi_CmdSpec *cmdSpecs,
    void *privData, int flags)
{
    int i = 0;
    Jsi_Value *proto;

    if (!cmdSpecs[0].name)
        return NULL;
    if (!name)
        name = cmdSpecs[0].name;
    name = Jsi_KeyAdd(interp, name);
    if (flags & JSI_CMDSPEC_PROTO) {
        proto = (Jsi_Value*)privData;
        privData = NULL;
        i++;



    } else if (name[0] == 0)
        proto = NULL;
    else {
        if (!(flags & JSI_CMDSPEC_ISOBJ)) {

            proto = jsi_CommandCreate(interp, name, NULL, privData, 0, cmdSpecs);
        } else {
            proto = jsi_ProtoValueNew(interp, name, NULL);
        }
    }
    for (; cmdSpecs[i].name; i++)
        CommandCreateWithSpec(interp,  cmdSpecs, i, proto, privData, name);

................................................................................
    if (JSI_OK == rc)
        rc = Jsi_JSONParse(interp, Jsi_DSValue(dsPtr), ret, 0);
    Jsi_DSFree(dsPtr);
    return rc;
}

static Jsi_CmdSpec enumCmds[] = {

    {"conf",    CDataEnumConfCmd,    1, 2, "enum:string, options:object|string=void",.help="Configure options for enum", .retType=0, .flags=0, .info=0, .opts=EnumOptions},
    {"define",  CDataEnumDefineCmd,  2, 2, "options:object|string, fields:array|string", .help="Create an enum: value of items same as in fieldconf", .retType=0, .flags=0, .info=0, .opts=EnumOptions},
    {"fieldconf",CDataEnumFieldConfCmd,2, 3, "enum:string, field:string, options:object|string=void",.help="Configure options for fields", .retType=0, .flags=0, .info=0, .opts=EnumFieldOptions},
    {"find",    CDataEnumFindCmd,    2, 2, "enum:string, intValue:number", .help="Find item with given value in enum", .retType=(uint)JSI_TT_STRING},
    {"get",     CDataEnumGetCmd,     1, 1, "enum:string", .help="Return enum definition", .retType=(uint)JSI_TT_OBJECT},
    {"names",   CDataEnumNamesCmd,   0, 1, "enum:string=void", .help="Return name list of all enums, or items within one enum", .retType=(uint)JSI_TT_ARRAY},
    {"undef",   CDataEnumUndefineCmd,1, 1, "enum:string",.help="Remove an enum", .retType=0, .flags=0, .info=0, .opts=0},
    {"value",   CDataEnumValueCmd,   2, 2, "enum:string, item:string", .help="Return value for given enum item", .retType=(uint)JSI_TT_NUMBER},
    { NULL,   0,0,0,0, .help="Enum commands" }
};

/************************** STRUCT ******************************/

static Jsi_RC CDataStructGetDfn(Jsi_Interp *interp, Jsi_StructSpec * sl, Jsi_DString *dsPtr)
{
    
................................................................................
    Jsi_HashEntryDelete(entry);
    entry = Jsi_HashEntryFind(interp->CTypeHash, name);
    if (entry)
        Jsi_HashEntryDelete(entry);
    return JSI_OK;
}

/* Defines: Handles the "CData.define.create" subcommand */
static Jsi_RC CDataStructDefineCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
                                Jsi_Value **ret, Jsi_Func *funcPtr)
{
    
    Jsi_RC rc = JSI_OK;
    Jsi_OptionTypedef *st = NULL;
    jsi_csInitType(interp);
................................................................................
    if (!arg2 || !(sf = jsi_csFieldGet(interp, arg2, sl)))
        return Jsi_LogError("unknown field: %s", arg2);
    return CDataOptionsConf(interp, StructFieldOptions, args, sf, ret, 0, 2);
}

static Jsi_CmdSpec structCmds[] =
{

    {"conf",      CDataStructConfCmd,   1, 2, "struct:string, options:object|string=void", .help="Configure options for struct", .retType=0, .flags=0, .info=0, .opts=StructOptions},
    {"define",    CDataStructDefineCmd, 2, 2, "options:object|string, fields:array|string", .help="Create a struct: field values same as in fieldconf", .retType=0, .flags=0, .info=0, .opts=StructOptions},
    {"fieldconf", CDataStructFieldConfCmd,2,3,"struct:string, field:string, options:object|string=void", .help="Configure options for fields", .retType=0, .flags=0, .info=0, .opts=StructFieldOptions},
    {"get",       CDataStructGetCmd,    1, 2, "struct, options:object=void", .help="Return the struct definition", .retType=(uint)JSI_TT_OBJECT},
    {"names",     CDataStructNamesCmd,  0, 1, "struct:string=void", .help="Return name list of all structs, or fields for one struct", .retType=(uint)JSI_TT_ARRAY},

    {"schema",    CDataStructSchemaCmd, 1, 1, "", .help="Return database schema for struct", .retType=(uint)JSI_TT_STRING },
    {"undef",     CDataStructUndefineCmd,1, 1, "name:string",.help="Remove a struct", .retType=0, .flags=0, .info=0, .opts=0},
    {NULL}
};



static Jsi_RC jsi_csGetKey(Jsi_Interp *interp, CDataObj *cd, Jsi_Value *arg, void **kPtr, size_t ksize, int anum)
{
    void *kBuf = *kPtr;
................................................................................
The 2nd arg is used for function option parsing and will report errors at the callers file:line")
static Jsi_RC CDataConstructor(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr);
    
/* Defines: Handles the "Data" subcommand */
static Jsi_CmdSpec cdataCmds[] =
{
    {"CData",     CDataConstructor,1, 2, "options:string|object=void, inits:object=void",.help="Create a new struct or map/array of structs", .retType=(uint)JSI_TT_USEROBJ, .flags=JSI_CMD_IS_CONSTRUCTOR, .info=FN_cdataConstructor, .opts=CDataOptions},
    {"conf",      CDataConfCmd,    0, 1, "options:object|string=void",.help="Configure options for c-data", .retType=0, .flags=0, .info=0, .opts=CDataOptions},
    {"get"   ,    CDataGetCmd,     0, 2, "key:string|number|object=null, field:string=void", .help="Get struct/map/array value", .retType=(uint)JSI_TT_ANY},
    {"incr",      CDataIncrCmd,    3, 3, "key:string|number|object|null, field:object|string, value:number", .help="Increment a numeric field: returns the new value", .retType=(uint)JSI_TT_NUMBER},
    {"info",      CDataInfoCmd,    0, 0, "", .help="Return info for data", .retType=(uint)JSI_TT_OBJECT},
    {"names",     CDataNamesCmd,   0, 0, "", .help="Return keys for map", .retType=(uint)JSI_TT_ARRAY },
    {"set",       CDataSetCmd,     2, 3, "key:string|number|object|null, field:object|string, value:any=void", .help="Set a struct/map/array value", .retType=(uint)JSI_TT_ANY},
    {"unset",     CDataUnsetCmd,   1, 1, "key:string|number|object", .help="Remove entry from map/array", .retType=(uint)JSI_TT_ANY},
................................................................................
    int argc = Jsi_ValueGetLength(interp, args);
    return Jsi_HashKeysDump(interp, (argc?interp->CTypeHash:interp->TYPEHash), ret, 0);
}

/* Defines: Handles the "Type" subcommand */
static Jsi_CmdSpec typeCmds[] =
{
    //{"aliases",   CDataTypeAliasCmd,   0, 0, "", .help="Return type aliases", .retType=(uint)JSI_TT_ARRAY},
    {"conf",      CDataTypeConfCmd,    1, 2, "typ:string, options:object|string=void",.help="Configure options for type", .retType=0, .flags=0, .info=0, .opts=TypeOptions},
    {"names",     CDataTypeNamesCmd,   0, 1, "ctype=false", .help="Return type names", .retType=(uint)JSI_TT_ARRAY},
    {NULL}

};

static Jsi_RC jsi_csTypeFree(Jsi_Interp *interp, Jsi_HashEntry *hPtr, void *ptr) {
    if (!ptr) return JSI_OK;
    Jsi_OptionTypedef *type = jsi_csGetTypeSpec(ptr);
    if (type->extData && (type->flags&(jsi_CTYP_ENUM|jsi_CTYP_STRUCT)))
        ((Jsi_OptionSpec*)(type->extData))->value--;
................................................................................
    cd->interp = interp;
    Jsi_Value *val = Jsi_ValueArrayIndex(interp, args, 0);
    Jsi_vtype vtyp = Jsi_ValueTypeGet(val);
    int vlen, isNew = 0;
    const char *vstr = Jsi_ValueString(interp, val, &vlen);
    Jsi_DString dStr = {};
    Jsi_Value *ival = Jsi_ValueArrayIndex(interp, args, 1);


    if (ival && !Jsi_ValueIsObjType(interp, ival, JSI_OT_OBJECT))
        return Jsi_LogError("arg 2: expected object");
    if (vstr && vlen) {
        char ech = 0;
        const char *nstr = vstr, *cp = vstr;
        while (*cp && (isalnum(*cp) || *cp=='_')) cp++;
        if (*cp) {
            int slen = cp-vstr;
            Jsi_DString sStr = {};






|







 







>
>
>
>







 







<







 







<
<







 







>
>







 







|







 







>
>







 







>









>
>
>
|



>
|







 







>

<




|

|







 







|







 







>

<



>

<
|







 







|







 







<


<
>







 







>
>
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
.....
21399
21400
21401
21402
21403
21404
21405
21406
21407
21408
21409
21410
21411
21412
21413
21414
21415
21416
.....
21438
21439
21440
21441
21442
21443
21444

21445
21446
21447
21448
21449
21450
21451
.....
21477
21478
21479
21480
21481
21482
21483


21484
21485
21486
21487
21488
21489
21490
.....
21771
21772
21773
21774
21775
21776
21777
21778
21779
21780
21781
21782
21783
21784
21785
21786
.....
21810
21811
21812
21813
21814
21815
21816
21817
21818
21819
21820
21821
21822
21823
21824
.....
27022
27023
27024
27025
27026
27027
27028
27029
27030
27031
27032
27033
27034
27035
27036
27037
.....
35617
35618
35619
35620
35621
35622
35623
35624
35625
35626
35627
35628
35629
35630
35631
35632
35633
35634
35635
35636
35637
35638
35639
35640
35641
35642
35643
35644
35645
35646
35647
35648
35649
.....
56204
56205
56206
56207
56208
56209
56210
56211
56212

56213
56214
56215
56216
56217
56218
56219
56220
56221
56222
56223
56224
56225
56226
.....
56500
56501
56502
56503
56504
56505
56506
56507
56508
56509
56510
56511
56512
56513
56514
.....
56726
56727
56728
56729
56730
56731
56732
56733
56734

56735
56736
56737
56738
56739

56740
56741
56742
56743
56744
56745
56746
56747
.....
57225
57226
57227
57228
57229
57230
57231
57232
57233
57234
57235
57236
57237
57238
57239
.....
57275
57276
57277
57278
57279
57280
57281

57282
57283

57284
57285
57286
57287
57288
57289
57290
57291
.....
57453
57454
57455
57456
57457
57458
57459
57460
57461
57462
57463
57464
57465
57466
57467
57468
57469
57470
/* jsi.h : External API header file for Jsi. */
#ifndef __JSI_H__
#define __JSI_H__

#define JSI_VERSION_MAJOR   2
#define JSI_VERSION_MINOR   5
#define JSI_VERSION_RELEASE 19

#define JSI_VERSION (JSI_VERSION_MAJOR + ((Jsi_Number)JSI_VERSION_MINOR/100.0) + ((Jsi_Number)JSI_VERSION_RELEASE/10000.0))

#ifndef JSI_EXTERN
#define JSI_EXTERN extern
#endif

................................................................................
    static char lastMsg[JSI_BUFSIZ/2] = "";
    static int lastCnt = 0;
    static Jsi_Interp *LastInterp = NULL;
    Jsi_Interp *lastInterp = LastInterp;
    const char *emsg = buf, *mt;
    int islog, line = 0, lofs = 0, noDups=0;
    bool isHelp = !Jsi_Strncmp(format, "...", 3);
    Jsi_OptionSpec *oep = interp->parseMsgSpec;
    const char *pps = "";
    char *ss = interp->lastPushStr;

    if (interp==NULL)
        interp = jsiIntData.mainInterp;
    LastInterp = interp;
    if (lastInterp != interp)
        noDups = 1;
    const char *curFile = jsi_GetCurFile(interp);
    /* Filter out try/catch (TODO: and non-syntax errors??). */
................................................................................
    }
    if (code == JSI_LOG_ERROR)
        interp->logErrorCnt++;
    mt = (code <= JSI_LOG_PARSE ? jsi_LogCodes[code] : "");
    if (isHelp) mt = "help";
    assert((JSI_LOG_PARSE+2) == (sizeof(jsi_LogCodes)/sizeof(jsi_LogCodes[0])));
    if (!Jsi_Strchr(format,'\n')) term = "\n";

    if (jsi_IsStrictMode(interp) && interp->lastParseOpt)
        ss = (char*)Jsi_ValueToString(interp, interp->lastParseOpt, NULL);
    if (code != JSI_LOG_INFO && interp && ss && ss[0]) {
        char psbuf[JSI_BUFSIZ/6];
        if (Jsi_Strchr(ss,'%')) {
            char *s = ss, *sd = psbuf;
            int plen=0, llen = sizeof(psbuf)-2;
................................................................................
            line = interp->curIp->Line;
            lofs = interp->curIp->Lofs;
            if (line<=0)
                line = interp->framePtr->line;
        }
    }
    islog = (interp->parent && interp->debugOpts.msgCallback && code != JSI_LOG_BUG);


    Jsi_DString pStr;
    Jsi_DSInit(&pStr);
    if (oep) {
        if (oep->id != JSI_OPTION_CUSTOM || !oep->custom)
            pps = Jsi_DSPrintf(&pStr, "for option \"%s\": ", oep->name);
        else {
            Jsi_OptionCustom* cust = Jsi_OptionCustomBuiltin(oep->custom);
................................................................................
        Jsi_DSAppend(dStr, "\"", str, "\"", NULL);
    Jsi_DSAppend(dStr, ":", NULL);
    ow->depth++;
    Jsi_RC rc = jsiValueGetString(tree->opts.interp, v, dStr, ow);
    ow->depth--;
    return rc;
}

#include <float.h>

/* Format value into dStr.  Toplevel caller does init/free. */
static Jsi_RC jsiValueGetString(Jsi_Interp *interp, Jsi_Value* v, Jsi_DString *dStr, objwalker *owPtr)
{
    char buf[100], *str;
    Jsi_DString eStr;
    Jsi_DSInit(&eStr);
................................................................................
            } else if (Jsi_NumberIsInteger(num)) {
                Jsi_NumberItoA10((Jsi_Wide)num, buf, sizeof(buf));
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsWide(num)) {
                snprintf(buf, sizeof(buf), "%" PRId64, (Jsi_Wide)num);
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsNormal(num) || Jsi_NumberIsSubnormal(num)) {
                Jsi_NumberDtoA(num, buf, sizeof(buf), -1);
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsNaN(num)) {
                Jsi_DSAppend(dStr, "NaN", NULL);
            } else {
                int s = Jsi_NumberIsInfinity(num);
                if (s > 0) Jsi_DSAppend(dStr, "+Infinity", NULL);
                else if (s < 0) Jsi_DSAppend(dStr, "-Infinity", NULL);
................................................................................
{
    Jsi_Number r = INFINITY;
    return (Jsi_NumberIsNaN(value)==0 && value != r && r != -value);
}

void Jsi_NumberDtoA(Jsi_Number value, char* buf, int bsiz, int prec)
{
    if (prec<0)
        prec = DBL_DECIMAL_DIG;
    if (Jsi_NumberIsNaN(value))
        Jsi_Strcpy(buf,"NaN");
    else
        snprintf(buf, bsiz, "%.*" JSI_NUMGFMT, prec, value);
}

bool Jsi_NumberIsEqual(Jsi_Number n1, Jsi_Number n2)
................................................................................


Jsi_Value *Jsi_CommandCreateSpecs(Jsi_Interp *interp, const char *name, Jsi_CmdSpec *cmdSpecs,
    void *privData, int flags)
{
    int i = 0;
    Jsi_Value *proto;
    Jsi_CmdProc *cmdProc = NULL;
    if (!cmdSpecs[0].name)
        return NULL;
    if (!name)
        name = cmdSpecs[0].name;
    name = Jsi_KeyAdd(interp, name);
    if (flags & JSI_CMDSPEC_PROTO) {
        proto = (Jsi_Value*)privData;
        privData = NULL;
        i++;
    /*} else if (!Jsi_Strcmp(name, cmdSpecs[0].name)) {
        cmdProc = cmdSpecs[0].proc;
        i++;*/
    } else if (!*name)
        proto = NULL;
    else {
        if (!(flags & JSI_CMDSPEC_ISOBJ)) {
            cmdProc = cmdSpecs[0].proc;
            proto = jsi_CommandCreate(interp, name, cmdProc, privData, 0, cmdSpecs);
        } else {
            proto = jsi_ProtoValueNew(interp, name, NULL);
        }
    }
    for (; cmdSpecs[i].name; i++)
        CommandCreateWithSpec(interp,  cmdSpecs, i, proto, privData, name);

................................................................................
    if (JSI_OK == rc)
        rc = Jsi_JSONParse(interp, Jsi_DSValue(dsPtr), ret, 0);
    Jsi_DSFree(dsPtr);
    return rc;
}

static Jsi_CmdSpec enumCmds[] = {
    {"add",     CDataEnumDefineCmd,  2, 2, "options:object|string, fields:array|string", .help="Create a new enum: value of items same as in fieldconf", .retType=0, .flags=0, .info=0, .opts=EnumOptions},
    {"conf",    CDataEnumConfCmd,    1, 2, "enum:string, options:object|string=void",.help="Configure options for enum", .retType=0, .flags=0, .info=0, .opts=EnumOptions},

    {"fieldconf",CDataEnumFieldConfCmd,2, 3, "enum:string, field:string, options:object|string=void",.help="Configure options for fields", .retType=0, .flags=0, .info=0, .opts=EnumFieldOptions},
    {"find",    CDataEnumFindCmd,    2, 2, "enum:string, intValue:number", .help="Find item with given value in enum", .retType=(uint)JSI_TT_STRING},
    {"get",     CDataEnumGetCmd,     1, 1, "enum:string", .help="Return enum definition", .retType=(uint)JSI_TT_OBJECT},
    {"names",   CDataEnumNamesCmd,   0, 1, "enum:string=void", .help="Return name list of all enums, or items within one enum", .retType=(uint)JSI_TT_ARRAY},
    {"remove",  CDataEnumUndefineCmd,1, 1, "enum:string",.help="Remove an enum", .retType=0, .flags=0, .info=0, .opts=0},
    {"value",   CDataEnumValueCmd,   2, 2, "enum:string, item:string", .help="Return value for given enum item", .retType=(uint)JSI_TT_NUMBER},
    { NULL,   0,0,0,0, .help="Enum commands. Note: Enum() is a shortcut for Enum.add()" }
};

/************************** STRUCT ******************************/

static Jsi_RC CDataStructGetDfn(Jsi_Interp *interp, Jsi_StructSpec * sl, Jsi_DString *dsPtr)
{
    
................................................................................
    Jsi_HashEntryDelete(entry);
    entry = Jsi_HashEntryFind(interp->CTypeHash, name);
    if (entry)
        Jsi_HashEntryDelete(entry);
    return JSI_OK;
}

/* Defines: Handles the "CData.define" subcommand */
static Jsi_RC CDataStructDefineCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
                                Jsi_Value **ret, Jsi_Func *funcPtr)
{
    
    Jsi_RC rc = JSI_OK;
    Jsi_OptionTypedef *st = NULL;
    jsi_csInitType(interp);
................................................................................
    if (!arg2 || !(sf = jsi_csFieldGet(interp, arg2, sl)))
        return Jsi_LogError("unknown field: %s", arg2);
    return CDataOptionsConf(interp, StructFieldOptions, args, sf, ret, 0, 2);
}

static Jsi_CmdSpec structCmds[] =
{
    {"add",       CDataStructDefineCmd, 2, 2, "options:object|string, fields:array|string", .help="Create a struct: field values same as in fieldconf", .retType=0, .flags=0, .info=0, .opts=StructOptions},
    {"conf",      CDataStructConfCmd,   1, 2, "struct:string, options:object|string=void", .help="Configure options for struct", .retType=0, .flags=0, .info=0, .opts=StructOptions},

    {"fieldconf", CDataStructFieldConfCmd,2,3,"struct:string, field:string, options:object|string=void", .help="Configure options for fields", .retType=0, .flags=0, .info=0, .opts=StructFieldOptions},
    {"get",       CDataStructGetCmd,    1, 2, "struct, options:object=void", .help="Return the struct definition", .retType=(uint)JSI_TT_OBJECT},
    {"names",     CDataStructNamesCmd,  0, 1, "struct:string=void", .help="Return name list of all structs, or fields for one struct", .retType=(uint)JSI_TT_ARRAY},
    {"remove",    CDataStructUndefineCmd,1, 1, "name:string",.help="Remove a struct", .retType=0, .flags=0, .info=0, .opts=0},
    {"schema",    CDataStructSchemaCmd, 1, 1, "", .help="Return database schema for struct", .retType=(uint)JSI_TT_STRING },

    { NULL,   0,0,0,0, .help="Struct commands. Note: Struct() is a shortcut for Struct.add()" }
};



static Jsi_RC jsi_csGetKey(Jsi_Interp *interp, CDataObj *cd, Jsi_Value *arg, void **kPtr, size_t ksize, int anum)
{
    void *kBuf = *kPtr;
................................................................................
The 2nd arg is used for function option parsing and will report errors at the callers file:line")
static Jsi_RC CDataConstructor(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr);
    
/* Defines: Handles the "Data" subcommand */
static Jsi_CmdSpec cdataCmds[] =
{
    {"CData",     CDataConstructor,1, 2, "options:string|object=void, inits:object=undefined",.help="Create a new struct or map/array of structs", .retType=(uint)JSI_TT_USEROBJ, .flags=JSI_CMD_IS_CONSTRUCTOR, .info=FN_cdataConstructor, .opts=CDataOptions},
    {"conf",      CDataConfCmd,    0, 1, "options:object|string=void",.help="Configure options for c-data", .retType=0, .flags=0, .info=0, .opts=CDataOptions},
    {"get"   ,    CDataGetCmd,     0, 2, "key:string|number|object=null, field:string=void", .help="Get struct/map/array value", .retType=(uint)JSI_TT_ANY},
    {"incr",      CDataIncrCmd,    3, 3, "key:string|number|object|null, field:object|string, value:number", .help="Increment a numeric field: returns the new value", .retType=(uint)JSI_TT_NUMBER},
    {"info",      CDataInfoCmd,    0, 0, "", .help="Return info for data", .retType=(uint)JSI_TT_OBJECT},
    {"names",     CDataNamesCmd,   0, 0, "", .help="Return keys for map", .retType=(uint)JSI_TT_ARRAY },
    {"set",       CDataSetCmd,     2, 3, "key:string|number|object|null, field:object|string, value:any=void", .help="Set a struct/map/array value", .retType=(uint)JSI_TT_ANY},
    {"unset",     CDataUnsetCmd,   1, 1, "key:string|number|object", .help="Remove entry from map/array", .retType=(uint)JSI_TT_ANY},
................................................................................
    int argc = Jsi_ValueGetLength(interp, args);
    return Jsi_HashKeysDump(interp, (argc?interp->CTypeHash:interp->TYPEHash), ret, 0);
}

/* Defines: Handles the "Type" subcommand */
static Jsi_CmdSpec typeCmds[] =
{

    {"conf",      CDataTypeConfCmd,    1, 2, "typ:string, options:object|string=void",.help="Configure options for type", .retType=0, .flags=0, .info=0, .opts=TypeOptions},
    {"names",     CDataTypeNamesCmd,   0, 1, "ctype=false", .help="Return type names", .retType=(uint)JSI_TT_ARRAY},

    { NULL,   0,0,0,0, .help="Type commands. Note: Type() is a shortcut for Type.conf()" }
};

static Jsi_RC jsi_csTypeFree(Jsi_Interp *interp, Jsi_HashEntry *hPtr, void *ptr) {
    if (!ptr) return JSI_OK;
    Jsi_OptionTypedef *type = jsi_csGetTypeSpec(ptr);
    if (type->extData && (type->flags&(jsi_CTYP_ENUM|jsi_CTYP_STRUCT)))
        ((Jsi_OptionSpec*)(type->extData))->value--;
................................................................................
    cd->interp = interp;
    Jsi_Value *val = Jsi_ValueArrayIndex(interp, args, 0);
    Jsi_vtype vtyp = Jsi_ValueTypeGet(val);
    int vlen, isNew = 0;
    const char *vstr = Jsi_ValueString(interp, val, &vlen);
    Jsi_DString dStr = {};
    Jsi_Value *ival = Jsi_ValueArrayIndex(interp, args, 1);
    if (ival && Jsi_ValueIsUndef(interp, ival))
        ival = NULL;
    else if (ival && !Jsi_ValueIsObjType(interp, ival, JSI_OT_OBJECT))
        return Jsi_LogError("arg 2: expected object or undef");
    if (vstr && vlen) {
        char ech = 0;
        const char *nstr = vstr, *cp = vstr;
        while (*cp && (isalnum(*cp) || *cp=='_')) cp++;
        if (*cp) {
            int slen = cp-vstr;
            Jsi_DString sStr = {};

Changes to src/jsi.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* jsi.h : External API header file for Jsi. */
#ifndef __JSI_H__
#define __JSI_H__

#define JSI_VERSION_MAJOR   2
#define JSI_VERSION_MINOR   5
#define JSI_VERSION_RELEASE 18

#define JSI_VERSION (JSI_VERSION_MAJOR + ((Jsi_Number)JSI_VERSION_MINOR/100.0) + ((Jsi_Number)JSI_VERSION_RELEASE/10000.0))

#ifndef JSI_EXTERN
#define JSI_EXTERN extern
#endif







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* jsi.h : External API header file for Jsi. */
#ifndef __JSI_H__
#define __JSI_H__

#define JSI_VERSION_MAJOR   2
#define JSI_VERSION_MINOR   5
#define JSI_VERSION_RELEASE 19

#define JSI_VERSION (JSI_VERSION_MAJOR + ((Jsi_Number)JSI_VERSION_MINOR/100.0) + ((Jsi_Number)JSI_VERSION_RELEASE/10000.0))

#ifndef JSI_EXTERN
#define JSI_EXTERN extern
#endif

Changes to src/jsiCData.c.

804
805
806
807
808
809
810

811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
....
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
....
1326
1327
1328
1329
1330
1331
1332

1333
1334
1335
1336
1337

1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
....
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
....
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885

1886
1887
1888
1889
1890
1891
1892
....
2054
2055
2056
2057
2058
2059
2060


2061
2062
2063
2064
2065
2066
2067
2068
2069
    if (JSI_OK == rc)
        rc = Jsi_JSONParse(interp, Jsi_DSValue(dsPtr), ret, 0);
    Jsi_DSFree(dsPtr);
    return rc;
}

static Jsi_CmdSpec enumCmds[] = {

    {"conf",    CDataEnumConfCmd,    1, 2, "enum:string, options:object|string=void",.help="Configure options for enum", .retType=0, .flags=0, .info=0, .opts=EnumOptions},
    {"define",  CDataEnumDefineCmd,  2, 2, "options:object|string, fields:array|string", .help="Create an enum: value of items same as in fieldconf", .retType=0, .flags=0, .info=0, .opts=EnumOptions},
    {"fieldconf",CDataEnumFieldConfCmd,2, 3, "enum:string, field:string, options:object|string=void",.help="Configure options for fields", .retType=0, .flags=0, .info=0, .opts=EnumFieldOptions},
    {"find",    CDataEnumFindCmd,    2, 2, "enum:string, intValue:number", .help="Find item with given value in enum", .retType=(uint)JSI_TT_STRING},
    {"get",     CDataEnumGetCmd,     1, 1, "enum:string", .help="Return enum definition", .retType=(uint)JSI_TT_OBJECT},
    {"names",   CDataEnumNamesCmd,   0, 1, "enum:string=void", .help="Return name list of all enums, or items within one enum", .retType=(uint)JSI_TT_ARRAY},
    {"undef",   CDataEnumUndefineCmd,1, 1, "enum:string",.help="Remove an enum", .retType=0, .flags=0, .info=0, .opts=0},
    {"value",   CDataEnumValueCmd,   2, 2, "enum:string, item:string", .help="Return value for given enum item", .retType=(uint)JSI_TT_NUMBER},
    { NULL,   0,0,0,0, .help="Enum commands" }
};

/************************** STRUCT ******************************/

static Jsi_RC CDataStructGetDfn(Jsi_Interp *interp, Jsi_StructSpec * sl, Jsi_DString *dsPtr)
{
    
................................................................................
    Jsi_HashEntryDelete(entry);
    entry = Jsi_HashEntryFind(interp->CTypeHash, name);
    if (entry)
        Jsi_HashEntryDelete(entry);
    return JSI_OK;
}

/* Defines: Handles the "CData.define.create" subcommand */
static Jsi_RC CDataStructDefineCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
                                Jsi_Value **ret, Jsi_Func *funcPtr)
{
    
    Jsi_RC rc = JSI_OK;
    Jsi_OptionTypedef *st = NULL;
    jsi_csInitType(interp);
................................................................................
    if (!arg2 || !(sf = jsi_csFieldGet(interp, arg2, sl)))
        return Jsi_LogError("unknown field: %s", arg2);
    return CDataOptionsConf(interp, StructFieldOptions, args, sf, ret, 0, 2);
}

static Jsi_CmdSpec structCmds[] =
{

    {"conf",      CDataStructConfCmd,   1, 2, "struct:string, options:object|string=void", .help="Configure options for struct", .retType=0, .flags=0, .info=0, .opts=StructOptions},
    {"define",    CDataStructDefineCmd, 2, 2, "options:object|string, fields:array|string", .help="Create a struct: field values same as in fieldconf", .retType=0, .flags=0, .info=0, .opts=StructOptions},
    {"fieldconf", CDataStructFieldConfCmd,2,3,"struct:string, field:string, options:object|string=void", .help="Configure options for fields", .retType=0, .flags=0, .info=0, .opts=StructFieldOptions},
    {"get",       CDataStructGetCmd,    1, 2, "struct, options:object=void", .help="Return the struct definition", .retType=(uint)JSI_TT_OBJECT},
    {"names",     CDataStructNamesCmd,  0, 1, "struct:string=void", .help="Return name list of all structs, or fields for one struct", .retType=(uint)JSI_TT_ARRAY},

    {"schema",    CDataStructSchemaCmd, 1, 1, "", .help="Return database schema for struct", .retType=(uint)JSI_TT_STRING },
    {"undef",     CDataStructUndefineCmd,1, 1, "name:string",.help="Remove a struct", .retType=0, .flags=0, .info=0, .opts=0},
    {NULL}
};



static Jsi_RC jsi_csGetKey(Jsi_Interp *interp, CDataObj *cd, Jsi_Value *arg, void **kPtr, size_t ksize, int anum)
{
    void *kBuf = *kPtr;
................................................................................
The 2nd arg is used for function option parsing and will report errors at the callers file:line")
static Jsi_RC CDataConstructor(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr);
    
/* Defines: Handles the "Data" subcommand */
static Jsi_CmdSpec cdataCmds[] =
{
    {"CData",     CDataConstructor,1, 2, "options:string|object=void, inits:object=void",.help="Create a new struct or map/array of structs", .retType=(uint)JSI_TT_USEROBJ, .flags=JSI_CMD_IS_CONSTRUCTOR, .info=FN_cdataConstructor, .opts=CDataOptions},
    {"conf",      CDataConfCmd,    0, 1, "options:object|string=void",.help="Configure options for c-data", .retType=0, .flags=0, .info=0, .opts=CDataOptions},
    {"get"   ,    CDataGetCmd,     0, 2, "key:string|number|object=null, field:string=void", .help="Get struct/map/array value", .retType=(uint)JSI_TT_ANY},
    {"incr",      CDataIncrCmd,    3, 3, "key:string|number|object|null, field:object|string, value:number", .help="Increment a numeric field: returns the new value", .retType=(uint)JSI_TT_NUMBER},
    {"info",      CDataInfoCmd,    0, 0, "", .help="Return info for data", .retType=(uint)JSI_TT_OBJECT},
    {"names",     CDataNamesCmd,   0, 0, "", .help="Return keys for map", .retType=(uint)JSI_TT_ARRAY },
    {"set",       CDataSetCmd,     2, 3, "key:string|number|object|null, field:object|string, value:any=void", .help="Set a struct/map/array value", .retType=(uint)JSI_TT_ANY},
    {"unset",     CDataUnsetCmd,   1, 1, "key:string|number|object", .help="Remove entry from map/array", .retType=(uint)JSI_TT_ANY},
................................................................................
    int argc = Jsi_ValueGetLength(interp, args);
    return Jsi_HashKeysDump(interp, (argc?interp->CTypeHash:interp->TYPEHash), ret, 0);
}

/* Defines: Handles the "Type" subcommand */
static Jsi_CmdSpec typeCmds[] =
{
    //{"aliases",   CDataTypeAliasCmd,   0, 0, "", .help="Return type aliases", .retType=(uint)JSI_TT_ARRAY},
    {"conf",      CDataTypeConfCmd,    1, 2, "typ:string, options:object|string=void",.help="Configure options for type", .retType=0, .flags=0, .info=0, .opts=TypeOptions},
    {"names",     CDataTypeNamesCmd,   0, 1, "ctype=false", .help="Return type names", .retType=(uint)JSI_TT_ARRAY},
    {NULL}

};

static Jsi_RC jsi_csTypeFree(Jsi_Interp *interp, Jsi_HashEntry *hPtr, void *ptr) {
    if (!ptr) return JSI_OK;
    Jsi_OptionTypedef *type = jsi_csGetTypeSpec(ptr);
    if (type->extData && (type->flags&(jsi_CTYP_ENUM|jsi_CTYP_STRUCT)))
        ((Jsi_OptionSpec*)(type->extData))->value--;
................................................................................
    cd->interp = interp;
    Jsi_Value *val = Jsi_ValueArrayIndex(interp, args, 0);
    Jsi_vtype vtyp = Jsi_ValueTypeGet(val);
    int vlen, isNew = 0;
    const char *vstr = Jsi_ValueString(interp, val, &vlen);
    Jsi_DString dStr = {};
    Jsi_Value *ival = Jsi_ValueArrayIndex(interp, args, 1);


    if (ival && !Jsi_ValueIsObjType(interp, ival, JSI_OT_OBJECT))
        return Jsi_LogError("arg 2: expected object");
    if (vstr && vlen) {
        char ech = 0;
        const char *nstr = vstr, *cp = vstr;
        while (*cp && (isalnum(*cp) || *cp=='_')) cp++;
        if (*cp) {
            int slen = cp-vstr;
            Jsi_DString sStr = {};







>

<




|

|







 







|







 







>

<



>

<
|







 







|







 







<


<
>







 







>
>
|
|







804
805
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820
821
822
823
824
825
826
....
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
....
1326
1327
1328
1329
1330
1331
1332
1333
1334

1335
1336
1337
1338
1339

1340
1341
1342
1343
1344
1345
1346
1347
....
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
....
1875
1876
1877
1878
1879
1880
1881

1882
1883

1884
1885
1886
1887
1888
1889
1890
1891
....
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
    if (JSI_OK == rc)
        rc = Jsi_JSONParse(interp, Jsi_DSValue(dsPtr), ret, 0);
    Jsi_DSFree(dsPtr);
    return rc;
}

static Jsi_CmdSpec enumCmds[] = {
    {"add",     CDataEnumDefineCmd,  2, 2, "options:object|string, fields:array|string", .help="Create a new enum: value of items same as in fieldconf", .retType=0, .flags=0, .info=0, .opts=EnumOptions},
    {"conf",    CDataEnumConfCmd,    1, 2, "enum:string, options:object|string=void",.help="Configure options for enum", .retType=0, .flags=0, .info=0, .opts=EnumOptions},

    {"fieldconf",CDataEnumFieldConfCmd,2, 3, "enum:string, field:string, options:object|string=void",.help="Configure options for fields", .retType=0, .flags=0, .info=0, .opts=EnumFieldOptions},
    {"find",    CDataEnumFindCmd,    2, 2, "enum:string, intValue:number", .help="Find item with given value in enum", .retType=(uint)JSI_TT_STRING},
    {"get",     CDataEnumGetCmd,     1, 1, "enum:string", .help="Return enum definition", .retType=(uint)JSI_TT_OBJECT},
    {"names",   CDataEnumNamesCmd,   0, 1, "enum:string=void", .help="Return name list of all enums, or items within one enum", .retType=(uint)JSI_TT_ARRAY},
    {"remove",  CDataEnumUndefineCmd,1, 1, "enum:string",.help="Remove an enum", .retType=0, .flags=0, .info=0, .opts=0},
    {"value",   CDataEnumValueCmd,   2, 2, "enum:string, item:string", .help="Return value for given enum item", .retType=(uint)JSI_TT_NUMBER},
    { NULL,   0,0,0,0, .help="Enum commands. Note: Enum() is a shortcut for Enum.add()" }
};

/************************** STRUCT ******************************/

static Jsi_RC CDataStructGetDfn(Jsi_Interp *interp, Jsi_StructSpec * sl, Jsi_DString *dsPtr)
{
    
................................................................................
    Jsi_HashEntryDelete(entry);
    entry = Jsi_HashEntryFind(interp->CTypeHash, name);
    if (entry)
        Jsi_HashEntryDelete(entry);
    return JSI_OK;
}

/* Defines: Handles the "CData.define" subcommand */
static Jsi_RC CDataStructDefineCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
                                Jsi_Value **ret, Jsi_Func *funcPtr)
{
    
    Jsi_RC rc = JSI_OK;
    Jsi_OptionTypedef *st = NULL;
    jsi_csInitType(interp);
................................................................................
    if (!arg2 || !(sf = jsi_csFieldGet(interp, arg2, sl)))
        return Jsi_LogError("unknown field: %s", arg2);
    return CDataOptionsConf(interp, StructFieldOptions, args, sf, ret, 0, 2);
}

static Jsi_CmdSpec structCmds[] =
{
    {"add",       CDataStructDefineCmd, 2, 2, "options:object|string, fields:array|string", .help="Create a struct: field values same as in fieldconf", .retType=0, .flags=0, .info=0, .opts=StructOptions},
    {"conf",      CDataStructConfCmd,   1, 2, "struct:string, options:object|string=void", .help="Configure options for struct", .retType=0, .flags=0, .info=0, .opts=StructOptions},

    {"fieldconf", CDataStructFieldConfCmd,2,3,"struct:string, field:string, options:object|string=void", .help="Configure options for fields", .retType=0, .flags=0, .info=0, .opts=StructFieldOptions},
    {"get",       CDataStructGetCmd,    1, 2, "struct, options:object=void", .help="Return the struct definition", .retType=(uint)JSI_TT_OBJECT},
    {"names",     CDataStructNamesCmd,  0, 1, "struct:string=void", .help="Return name list of all structs, or fields for one struct", .retType=(uint)JSI_TT_ARRAY},
    {"remove",    CDataStructUndefineCmd,1, 1, "name:string",.help="Remove a struct", .retType=0, .flags=0, .info=0, .opts=0},
    {"schema",    CDataStructSchemaCmd, 1, 1, "", .help="Return database schema for struct", .retType=(uint)JSI_TT_STRING },

    { NULL,   0,0,0,0, .help="Struct commands. Note: Struct() is a shortcut for Struct.add()" }
};



static Jsi_RC jsi_csGetKey(Jsi_Interp *interp, CDataObj *cd, Jsi_Value *arg, void **kPtr, size_t ksize, int anum)
{
    void *kBuf = *kPtr;
................................................................................
The 2nd arg is used for function option parsing and will report errors at the callers file:line")
static Jsi_RC CDataConstructor(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr);
    
/* Defines: Handles the "Data" subcommand */
static Jsi_CmdSpec cdataCmds[] =
{
    {"CData",     CDataConstructor,1, 2, "options:string|object=void, inits:object=undefined",.help="Create a new struct or map/array of structs", .retType=(uint)JSI_TT_USEROBJ, .flags=JSI_CMD_IS_CONSTRUCTOR, .info=FN_cdataConstructor, .opts=CDataOptions},
    {"conf",      CDataConfCmd,    0, 1, "options:object|string=void",.help="Configure options for c-data", .retType=0, .flags=0, .info=0, .opts=CDataOptions},
    {"get"   ,    CDataGetCmd,     0, 2, "key:string|number|object=null, field:string=void", .help="Get struct/map/array value", .retType=(uint)JSI_TT_ANY},
    {"incr",      CDataIncrCmd,    3, 3, "key:string|number|object|null, field:object|string, value:number", .help="Increment a numeric field: returns the new value", .retType=(uint)JSI_TT_NUMBER},
    {"info",      CDataInfoCmd,    0, 0, "", .help="Return info for data", .retType=(uint)JSI_TT_OBJECT},
    {"names",     CDataNamesCmd,   0, 0, "", .help="Return keys for map", .retType=(uint)JSI_TT_ARRAY },
    {"set",       CDataSetCmd,     2, 3, "key:string|number|object|null, field:object|string, value:any=void", .help="Set a struct/map/array value", .retType=(uint)JSI_TT_ANY},
    {"unset",     CDataUnsetCmd,   1, 1, "key:string|number|object", .help="Remove entry from map/array", .retType=(uint)JSI_TT_ANY},
................................................................................
    int argc = Jsi_ValueGetLength(interp, args);
    return Jsi_HashKeysDump(interp, (argc?interp->CTypeHash:interp->TYPEHash), ret, 0);
}

/* Defines: Handles the "Type" subcommand */
static Jsi_CmdSpec typeCmds[] =
{

    {"conf",      CDataTypeConfCmd,    1, 2, "typ:string, options:object|string=void",.help="Configure options for type", .retType=0, .flags=0, .info=0, .opts=TypeOptions},
    {"names",     CDataTypeNamesCmd,   0, 1, "ctype=false", .help="Return type names", .retType=(uint)JSI_TT_ARRAY},

    { NULL,   0,0,0,0, .help="Type commands. Note: Type() is a shortcut for Type.conf()" }
};

static Jsi_RC jsi_csTypeFree(Jsi_Interp *interp, Jsi_HashEntry *hPtr, void *ptr) {
    if (!ptr) return JSI_OK;
    Jsi_OptionTypedef *type = jsi_csGetTypeSpec(ptr);
    if (type->extData && (type->flags&(jsi_CTYP_ENUM|jsi_CTYP_STRUCT)))
        ((Jsi_OptionSpec*)(type->extData))->value--;
................................................................................
    cd->interp = interp;
    Jsi_Value *val = Jsi_ValueArrayIndex(interp, args, 0);
    Jsi_vtype vtyp = Jsi_ValueTypeGet(val);
    int vlen, isNew = 0;
    const char *vstr = Jsi_ValueString(interp, val, &vlen);
    Jsi_DString dStr = {};
    Jsi_Value *ival = Jsi_ValueArrayIndex(interp, args, 1);
    if (ival && Jsi_ValueIsUndef(interp, ival))
        ival = NULL;
    else if (ival && !Jsi_ValueIsObjType(interp, ival, JSI_OT_OBJECT))
        return Jsi_LogError("arg 2: expected object or undef");
    if (vstr && vlen) {
        char ech = 0;
        const char *nstr = vstr, *cp = vstr;
        while (*cp && (isalnum(*cp) || *cp=='_')) cp++;
        if (*cp) {
            int slen = cp-vstr;
            Jsi_DString sStr = {};

Changes to src/jsiCmds.c.

3350
3351
3352
3353
3354
3355
3356

3357
3358
3359
3360
3361
3362
3363
3364
3365



3366
3367
3368
3369

3370
3371
3372
3373
3374
3375
3376
3377


Jsi_Value *Jsi_CommandCreateSpecs(Jsi_Interp *interp, const char *name, Jsi_CmdSpec *cmdSpecs,
    void *privData, int flags)
{
    int i = 0;
    Jsi_Value *proto;

    if (!cmdSpecs[0].name)
        return NULL;
    if (!name)
        name = cmdSpecs[0].name;
    name = Jsi_KeyAdd(interp, name);
    if (flags & JSI_CMDSPEC_PROTO) {
        proto = (Jsi_Value*)privData;
        privData = NULL;
        i++;



    } else if (name[0] == 0)
        proto = NULL;
    else {
        if (!(flags & JSI_CMDSPEC_ISOBJ)) {

            proto = jsi_CommandCreate(interp, name, NULL, privData, 0, cmdSpecs);
        } else {
            proto = jsi_ProtoValueNew(interp, name, NULL);
        }
    }
    for (; cmdSpecs[i].name; i++)
        CommandCreateWithSpec(interp,  cmdSpecs, i, proto, privData, name);








>









>
>
>
|



>
|







3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382


Jsi_Value *Jsi_CommandCreateSpecs(Jsi_Interp *interp, const char *name, Jsi_CmdSpec *cmdSpecs,
    void *privData, int flags)
{
    int i = 0;
    Jsi_Value *proto;
    Jsi_CmdProc *cmdProc = NULL;
    if (!cmdSpecs[0].name)
        return NULL;
    if (!name)
        name = cmdSpecs[0].name;
    name = Jsi_KeyAdd(interp, name);
    if (flags & JSI_CMDSPEC_PROTO) {
        proto = (Jsi_Value*)privData;
        privData = NULL;
        i++;
    /*} else if (!Jsi_Strcmp(name, cmdSpecs[0].name)) {
        cmdProc = cmdSpecs[0].proc;
        i++;*/
    } else if (!*name)
        proto = NULL;
    else {
        if (!(flags & JSI_CMDSPEC_ISOBJ)) {
            cmdProc = cmdSpecs[0].proc;
            proto = jsi_CommandCreate(interp, name, cmdProc, privData, 0, cmdSpecs);
        } else {
            proto = jsi_ProtoValueNew(interp, name, NULL);
        }
    }
    for (; cmdSpecs[i].name; i++)
        CommandCreateWithSpec(interp,  cmdSpecs, i, proto, privData, name);

Changes to src/jsiNumber.c.

59
60
61
62
63
64
65


66
67
68
69
70
71
72
{
    Jsi_Number r = INFINITY;
    return (Jsi_NumberIsNaN(value)==0 && value != r && r != -value);
}

void Jsi_NumberDtoA(Jsi_Number value, char* buf, int bsiz, int prec)
{


    if (Jsi_NumberIsNaN(value))
        Jsi_Strcpy(buf,"NaN");
    else
        snprintf(buf, bsiz, "%.*" JSI_NUMGFMT, prec, value);
}

bool Jsi_NumberIsEqual(Jsi_Number n1, Jsi_Number n2)







>
>







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
{
    Jsi_Number r = INFINITY;
    return (Jsi_NumberIsNaN(value)==0 && value != r && r != -value);
}

void Jsi_NumberDtoA(Jsi_Number value, char* buf, int bsiz, int prec)
{
    if (prec<0)
        prec = DBL_DECIMAL_DIG;
    if (Jsi_NumberIsNaN(value))
        Jsi_Strcpy(buf,"NaN");
    else
        snprintf(buf, bsiz, "%.*" JSI_NUMGFMT, prec, value);
}

bool Jsi_NumberIsEqual(Jsi_Number n1, Jsi_Number n2)

Changes to src/jsiUtils.c.

495
496
497
498
499
500
501


502
503
504
505
506
507
508
...
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
        Jsi_DSAppend(dStr, "\"", str, "\"", NULL);
    Jsi_DSAppend(dStr, ":", NULL);
    ow->depth++;
    Jsi_RC rc = jsiValueGetString(tree->opts.interp, v, dStr, ow);
    ow->depth--;
    return rc;
}



/* Format value into dStr.  Toplevel caller does init/free. */
static Jsi_RC jsiValueGetString(Jsi_Interp *interp, Jsi_Value* v, Jsi_DString *dStr, objwalker *owPtr)
{
    char buf[100], *str;
    Jsi_DString eStr;
    Jsi_DSInit(&eStr);
................................................................................
            } else if (Jsi_NumberIsInteger(num)) {
                Jsi_NumberItoA10((Jsi_Wide)num, buf, sizeof(buf));
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsWide(num)) {
                snprintf(buf, sizeof(buf), "%" PRId64, (Jsi_Wide)num);
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsNormal(num) || Jsi_NumberIsSubnormal(num)) {
                snprintf(buf, sizeof(buf), "%" JSI_NUMGFMT, num);
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsNaN(num)) {
                Jsi_DSAppend(dStr, "NaN", NULL);
            } else {
                int s = Jsi_NumberIsInfinity(num);
                if (s > 0) Jsi_DSAppend(dStr, "+Infinity", NULL);
                else if (s < 0) Jsi_DSAppend(dStr, "-Infinity", NULL);







>
>







 







|







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
...
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
        Jsi_DSAppend(dStr, "\"", str, "\"", NULL);
    Jsi_DSAppend(dStr, ":", NULL);
    ow->depth++;
    Jsi_RC rc = jsiValueGetString(tree->opts.interp, v, dStr, ow);
    ow->depth--;
    return rc;
}

#include <float.h>

/* Format value into dStr.  Toplevel caller does init/free. */
static Jsi_RC jsiValueGetString(Jsi_Interp *interp, Jsi_Value* v, Jsi_DString *dStr, objwalker *owPtr)
{
    char buf[100], *str;
    Jsi_DString eStr;
    Jsi_DSInit(&eStr);
................................................................................
            } else if (Jsi_NumberIsInteger(num)) {
                Jsi_NumberItoA10((Jsi_Wide)num, buf, sizeof(buf));
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsWide(num)) {
                snprintf(buf, sizeof(buf), "%" PRId64, (Jsi_Wide)num);
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsNormal(num) || Jsi_NumberIsSubnormal(num)) {
                Jsi_NumberDtoA(num, buf, sizeof(buf), -1);
                Jsi_DSAppend(dStr, buf, NULL);
            } else if (Jsi_NumberIsNaN(num)) {
                Jsi_DSAppend(dStr, "NaN", NULL);
            } else {
                int s = Jsi_NumberIsInfinity(num);
                if (s > 0) Jsi_DSAppend(dStr, "+Infinity", NULL);
                else if (s < 0) Jsi_DSAppend(dStr, "-Infinity", NULL);

Changes to tools/protos.jsi.

1
2
3
4
5
6
7
8
..
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46

47
48
49
50
51

52
53
54
55
56
57
58
59
60
//JSI Command Prototypes: version 2.5.18
throw("NOT EXECUTABLE: USE FILE IN GEANY EDITOR FOR CMD LINE COMPLETION + GOTO TAG");

var Array = function(cmd,args) {};
Array.prototype.concat = function(...):array {};
Array.prototype.every = function(callback:function):any {};
Array.prototype.fill = function(value:any, start:number=0, end:number=-1):array {};
Array.prototype.filter = function(callback:function, this:object=void):array {};
................................................................................
CData.prototype.get = function(key:string|number|object=null, field:string=void):any {};
CData.prototype.incr = function(key:string|number|object|null, field:object|string, value:number):number {};
CData.prototype.info = function():object {};
CData.prototype.names = function():array {};
CData.prototype.set = function(key:string|number|object|null, field:object|string, value:any=void):any {};
CData.prototype.unset = function(key:string|number|object):any {};
var CEnum = function(cmd,args) {};

CEnum.prototype.conf = function(enum:string, options:object|string=void):any {};
CEnum.prototype.define = function(options:object|string, fields:array|string):any {};
CEnum.prototype.fieldconf = function(enum:string, field:string, options:object|string=void):any {};
CEnum.prototype.find = function(enum:string, intValue:number):string {};
CEnum.prototype.get = function(enum:string):object {};
CEnum.prototype.names = function(enum:string=void):array {};
CEnum.prototype.undef = function(enum:string):any {};
CEnum.prototype.value = function(enum:string, item:string):number {};
var CStruct = function(cmd,args) {};

CStruct.prototype.conf = function(struct:string, options:object|string=void):any {};
CStruct.prototype.define = function(options:object|string, fields:array|string):any {};
CStruct.prototype.fieldconf = function(struct:string, field:string, options:object|string=void):any {};
CStruct.prototype.get = function(struct, options:object=void):object {};
CStruct.prototype.names = function(struct:string=void):array {};

CStruct.prototype.schema = function():string {};
CStruct.prototype.undef = function(name:string):any {};
var CType = function(cmd,args) {};
CType.prototype.conf = function(typ:string, options:object|string=void):any {};
CType.prototype.names = function(ctype=false):array {};
var Channel = function(cmd,args) {};
Channel.prototype.close = function():boolean {};
Channel.prototype.eof = function():boolean {};
Channel.prototype.filename = function():string {};
|







 







>

<




|


>

<



>

<







1
2
3
4
5
6
7
8
..
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48

49
50
51
52
53

54
55
56
57
58
59
60
//JSI Command Prototypes: version 2.5.19
throw("NOT EXECUTABLE: USE FILE IN GEANY EDITOR FOR CMD LINE COMPLETION + GOTO TAG");

var Array = function(cmd,args) {};
Array.prototype.concat = function(...):array {};
Array.prototype.every = function(callback:function):any {};
Array.prototype.fill = function(value:any, start:number=0, end:number=-1):array {};
Array.prototype.filter = function(callback:function, this:object=void):array {};
................................................................................
CData.prototype.get = function(key:string|number|object=null, field:string=void):any {};
CData.prototype.incr = function(key:string|number|object|null, field:object|string, value:number):number {};
CData.prototype.info = function():object {};
CData.prototype.names = function():array {};
CData.prototype.set = function(key:string|number|object|null, field:object|string, value:any=void):any {};
CData.prototype.unset = function(key:string|number|object):any {};
var CEnum = function(cmd,args) {};
CEnum.prototype.add = function(options:object|string, fields:array|string):any {};
CEnum.prototype.conf = function(enum:string, options:object|string=void):any {};

CEnum.prototype.fieldconf = function(enum:string, field:string, options:object|string=void):any {};
CEnum.prototype.find = function(enum:string, intValue:number):string {};
CEnum.prototype.get = function(enum:string):object {};
CEnum.prototype.names = function(enum:string=void):array {};
CEnum.prototype.remove = function(enum:string):any {};
CEnum.prototype.value = function(enum:string, item:string):number {};
var CStruct = function(cmd,args) {};
CStruct.prototype.add = function(options:object|string, fields:array|string):any {};
CStruct.prototype.conf = function(struct:string, options:object|string=void):any {};

CStruct.prototype.fieldconf = function(struct:string, field:string, options:object|string=void):any {};
CStruct.prototype.get = function(struct, options:object=void):object {};
CStruct.prototype.names = function(struct:string=void):array {};
CStruct.prototype.remove = function(name:string):any {};
CStruct.prototype.schema = function():string {};

var CType = function(cmd,args) {};
CType.prototype.conf = function(typ:string, options:object|string=void):any {};
CType.prototype.names = function(ctype=false):array {};
var Channel = function(cmd,args) {};
Channel.prototype.close = function():boolean {};
Channel.prototype.eof = function():boolean {};
Channel.prototype.filename = function():string {};

Changes to www/reference.wiki.

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
...
218
219
220
221
222
223
224
225


226
227
228

229
230
231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
...
293
294
295
296
297
298
299
300


301
302
303
304
305
306
307
<a name="CData"></a>

<hr>


<h1>CData</h1>

<font color=red>Synopsis:new CData(options:string|object=void, inits:object=void):userobj

</font><p>
<h2>Methods for "CData"</h2>
<table border="1"class="cmdstbl table">
<tr><th>Method</th><th>Prototype</th><th>Description</th></tr>
<tr><td>CData</td><td>new CData(<a href='#new CDataOptions'>options</a>:string|object=void, inits:object=void):userobj </td><td>Create a new struct or map/array of structs.The 2nd arg is used for function option parsing and will report errors at the callers file:line</td></tr>
<tr><td>conf</td><td>conf(<a href='#CData.confOptions'>options</a>:object|string=void) </td><td>Configure options for c-data.</td></tr>
<tr><td>get</td><td>get(key:string|number|object=null, field:string=void) </td><td>Get struct/map/array value.</td></tr>
<tr><td>incr</td><td>incr(key:string|number|object|null, field:object|string, value:number):number </td><td>Increment a numeric field: returns the new value.</td></tr>
<tr><td>info</td><td>info():object </td><td>Return info for data.</td></tr>
<tr><td>names</td><td>names():array </td><td>Return keys for map.</td></tr>
<tr><td>set</td><td>set(key:string|number|object|null, field:object|string, value:any=void) </td><td>Set a struct/map/array value.</td></tr>
<tr><td>unset</td><td>unset(key:string|number|object) </td><td>Remove entry from map/array.</td></tr>
................................................................................
<hr>


<h1>CEnum</h1>

<font color=red>Synopsis:CEnum.method(...)

</font><p>Enum commands.


<h2>Methods for "CEnum"</h2>
<table border="1"class="cmdstbl table">
<tr><th>Method</th><th>Prototype</th><th>Description</th></tr>

<tr><td>conf</td><td>conf(enum:string, <a href='#CEnum.confOptions'>options</a>:object|string=void) </td><td>Configure options for enum.</td></tr>
<tr><td>define</td><td>define(<a href='#CEnum.defineOptions'>options</a>:object|string, fields:array|string) </td><td>Create an enum: value of items same as in fieldconf.</td></tr>
<tr><td>fieldconf</td><td>fieldconf(enum:string, field:string, <a href='#CEnum.fieldconfOptions'>options</a>:object|string=void) </td><td>Configure options for fields.</td></tr>
<tr><td>find</td><td>find(enum:string, intValue:number):string </td><td>Find item with given value in enum.</td></tr>
<tr><td>get</td><td>get(enum:string):object </td><td>Return enum definition.</td></tr>
<tr><td>names</td><td>names(enum:string=void):array </td><td>Return name list of all enums, or items within one enum.</td></tr>
<tr><td>undef</td><td>undef(enum:string) </td><td>Remove an enum.</td></tr>
<tr><td>value</td><td>value(enum:string, item:string):number </td><td>Return value for given enum item.</td></tr>
</table>


<a name="CEnum.confOptions"></a>
<a name="CEnum.confOptions"></a>
<h2>Options for "CEnum.conf"</h2>
<table border="1" class="optstbl table">
<tr><th>Option</th> <th>Type</th> <th>Description</th><th>Flags</th></tr>
<tr><td>flags</td><td><i>INT64</i></td><td>Flags for enum.</td><td><i>initOnly</i></td></tr>
<tr><td>help</td><td><i>STRKEY</i></td><td>Description of enum.</td><td><i>initOnly</i></td></tr>
<tr><td>name</td><td><i>STRKEY</i></td><td>Name of enum.</td><td><i>initOnly</i></td></tr>
<tr><td>idx</td><td><i>UINT</i></td><td>Number of items in enum.</td><td><i>readOnly</i></td></tr>
</table>


<a name="CEnum.defineOptions"></a>
<a name="CEnum.confOptions"></a>
<h2>Options for "CEnum.define"</h2>
<table border="1" class="optstbl table">
<tr><th>Option</th> <th>Type</th> <th>Description</th><th>Flags</th></tr>
<tr><td>flags</td><td><i>INT64</i></td><td>Flags for enum.</td><td><i>initOnly</i></td></tr>
<tr><td>help</td><td><i>STRKEY</i></td><td>Description of enum.</td><td><i>initOnly</i></td></tr>
<tr><td>name</td><td><i>STRKEY</i></td><td>Name of enum.</td><td><i>initOnly</i></td></tr>
<tr><td>idx</td><td><i>UINT</i></td><td>Number of items in enum.</td><td><i>readOnly</i></td></tr>
</table>
................................................................................
<hr>


<h1>CStruct</h1>

<font color=red>Synopsis:CStruct.method(...)

</font><p>


<h2>Methods for "CStruct"</h2>
<table border="1"class="cmdstbl table">
<tr><th>Method</th><th>Prototype</th><th>Description</th></tr>

<tr><td>conf</td><td>conf(struct:string, <a href='#CStruct.confOptions'>options</a>:object|string=void) </td><td>Configure options for struct.</td></tr>
<tr><td>define</td><td>define(<a href='#CStruct.defineOptions'>options</a>:object|string, fields:array|string) </td><td>Create a struct: field values same as in fieldconf.</td></tr>
<tr><td>fieldconf</td><td>fieldconf(struct:string, field:string, <a href='#CStruct.fieldconfOptions'>options</a>:object|string=void) </td><td>Configure options for fields.</td></tr>
<tr><td>get</td><td>get(struct, options:object=void):object </td><td>Return the struct definition.</td></tr>
<tr><td>names</td><td>names(struct:string=void):array </td><td>Return name list of all structs, or fields for one struct.</td></tr>

<tr><td>schema</td><td>schema():string </td><td>Return database schema for struct.</td></tr>
<tr><td>undef</td><td>undef(name:string) </td><td>Remove a struct.</td></tr>
</table>


<a name="CStruct.confOptions"></a>
<a name="CStruct.confOptions"></a>
<h2>Options for "CStruct.conf"</h2>
<table border="1" class="optstbl table">
<tr><th>Option</th> <th>Type</th> <th>Description</th><th>Flags</th></tr>
<tr><td>crc</td><td><i>UINT32</i></td><td>Crc for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>flags</td><td><i>INT64</i></td><td>Flags for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>help</td><td><i>STRKEY</i></td><td>Struct description.</td><td><i>initOnly</i></td></tr>
<tr><td>idx</td><td><i>UINT32</i></td><td>Number of fields in struct.</td><td><i>readOnly</i></td></tr>
<tr><td>name</td><td><i>STRKEY</i></td><td>Name of struct.</td><td><i>initOnly|required</i></td></tr>
<tr><td>size</td><td><i>UINT</i></td><td>Size of struct in bytes.</td><td><i>readOnly</i></td></tr>
<tr><td>ssig</td><td><i>UINT32</i></td><td>Signature for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>value</td><td><i>INT64</i></td><td>Reference count.</td><td><i>readOnly</i></td></tr>
</table>


<a name="CStruct.defineOptions"></a>
<a name="CStruct.confOptions"></a>
<h2>Options for "CStruct.define"</h2>
<table border="1" class="optstbl table">
<tr><th>Option</th> <th>Type</th> <th>Description</th><th>Flags</th></tr>
<tr><td>crc</td><td><i>UINT32</i></td><td>Crc for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>flags</td><td><i>INT64</i></td><td>Flags for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>help</td><td><i>STRKEY</i></td><td>Struct description.</td><td><i>initOnly</i></td></tr>
<tr><td>idx</td><td><i>UINT32</i></td><td>Number of fields in struct.</td><td><i>readOnly</i></td></tr>
<tr><td>name</td><td><i>STRKEY</i></td><td>Name of struct.</td><td><i>initOnly|required</i></td></tr>
................................................................................
<hr>


<h1>CType</h1>

<font color=red>Synopsis:CType.method(...)

</font><p>


<h2>Methods for "CType"</h2>
<table border="1"class="cmdstbl table">
<tr><th>Method</th><th>Prototype</th><th>Description</th></tr>
<tr><td>conf</td><td>conf(typ:string, <a href='#CType.confOptions'>options</a>:object|string=void) </td><td>Configure options for type.</td></tr>
<tr><td>names</td><td>names(ctype=false):array </td><td>Return type names.</td></tr>
</table>








|





|







 







|





>

<




|




|

|









|

|







 







|
>
>



>

<



>

<



|

|













|

|







 







|
>
>







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
<a name="CData"></a>

<hr>


<h1>CData</h1>

<font color=red>Synopsis:new CData(options:string|object=void, inits:object=undefined):userobj

</font><p>
<h2>Methods for "CData"</h2>
<table border="1"class="cmdstbl table">
<tr><th>Method</th><th>Prototype</th><th>Description</th></tr>
<tr><td>CData</td><td>new CData(<a href='#new CDataOptions'>options</a>:string|object=void, inits:object=undefined):userobj </td><td>Create a new struct or map/array of structs.The 2nd arg is used for function option parsing and will report errors at the callers file:line</td></tr>
<tr><td>conf</td><td>conf(<a href='#CData.confOptions'>options</a>:object|string=void) </td><td>Configure options for c-data.</td></tr>
<tr><td>get</td><td>get(key:string|number|object=null, field:string=void) </td><td>Get struct/map/array value.</td></tr>
<tr><td>incr</td><td>incr(key:string|number|object|null, field:object|string, value:number):number </td><td>Increment a numeric field: returns the new value.</td></tr>
<tr><td>info</td><td>info():object </td><td>Return info for data.</td></tr>
<tr><td>names</td><td>names():array </td><td>Return keys for map.</td></tr>
<tr><td>set</td><td>set(key:string|number|object|null, field:object|string, value:any=void) </td><td>Set a struct/map/array value.</td></tr>
<tr><td>unset</td><td>unset(key:string|number|object) </td><td>Remove entry from map/array.</td></tr>
................................................................................
<hr>


<h1>CEnum</h1>

<font color=red>Synopsis:CEnum.method(...)

</font><p>Enum commands. Note: Enum() is a shortcut for Enum.add().


<h2>Methods for "CEnum"</h2>
<table border="1"class="cmdstbl table">
<tr><th>Method</th><th>Prototype</th><th>Description</th></tr>
<tr><td>add</td><td>add(<a href='#CEnum.addOptions'>options</a>:object|string, fields:array|string) </td><td>Create a new enum: value of items same as in fieldconf.</td></tr>
<tr><td>conf</td><td>conf(enum:string, <a href='#CEnum.confOptions'>options</a>:object|string=void) </td><td>Configure options for enum.</td></tr>

<tr><td>fieldconf</td><td>fieldconf(enum:string, field:string, <a href='#CEnum.fieldconfOptions'>options</a>:object|string=void) </td><td>Configure options for fields.</td></tr>
<tr><td>find</td><td>find(enum:string, intValue:number):string </td><td>Find item with given value in enum.</td></tr>
<tr><td>get</td><td>get(enum:string):object </td><td>Return enum definition.</td></tr>
<tr><td>names</td><td>names(enum:string=void):array </td><td>Return name list of all enums, or items within one enum.</td></tr>
<tr><td>remove</td><td>remove(enum:string) </td><td>Remove an enum.</td></tr>
<tr><td>value</td><td>value(enum:string, item:string):number </td><td>Return value for given enum item.</td></tr>
</table>


<a name="CEnum.addOptions"></a>
<a name="CEnum.confOptions"></a>
<h2>Options for "CEnum.add"</h2>
<table border="1" class="optstbl table">
<tr><th>Option</th> <th>Type</th> <th>Description</th><th>Flags</th></tr>
<tr><td>flags</td><td><i>INT64</i></td><td>Flags for enum.</td><td><i>initOnly</i></td></tr>
<tr><td>help</td><td><i>STRKEY</i></td><td>Description of enum.</td><td><i>initOnly</i></td></tr>
<tr><td>name</td><td><i>STRKEY</i></td><td>Name of enum.</td><td><i>initOnly</i></td></tr>
<tr><td>idx</td><td><i>UINT</i></td><td>Number of items in enum.</td><td><i>readOnly</i></td></tr>
</table>


<a name="CEnum.confOptions"></a>
<a name="CEnum.confOptions"></a>
<h2>Options for "CEnum.conf"</h2>
<table border="1" class="optstbl table">
<tr><th>Option</th> <th>Type</th> <th>Description</th><th>Flags</th></tr>
<tr><td>flags</td><td><i>INT64</i></td><td>Flags for enum.</td><td><i>initOnly</i></td></tr>
<tr><td>help</td><td><i>STRKEY</i></td><td>Description of enum.</td><td><i>initOnly</i></td></tr>
<tr><td>name</td><td><i>STRKEY</i></td><td>Name of enum.</td><td><i>initOnly</i></td></tr>
<tr><td>idx</td><td><i>UINT</i></td><td>Number of items in enum.</td><td><i>readOnly</i></td></tr>
</table>
................................................................................
<hr>


<h1>CStruct</h1>

<font color=red>Synopsis:CStruct.method(...)

</font><p>Struct commands. Note: Struct() is a shortcut for Struct.add().


<h2>Methods for "CStruct"</h2>
<table border="1"class="cmdstbl table">
<tr><th>Method</th><th>Prototype</th><th>Description</th></tr>
<tr><td>add</td><td>add(<a href='#CStruct.addOptions'>options</a>:object|string, fields:array|string) </td><td>Create a struct: field values same as in fieldconf.</td></tr>
<tr><td>conf</td><td>conf(struct:string, <a href='#CStruct.confOptions'>options</a>:object|string=void) </td><td>Configure options for struct.</td></tr>

<tr><td>fieldconf</td><td>fieldconf(struct:string, field:string, <a href='#CStruct.fieldconfOptions'>options</a>:object|string=void) </td><td>Configure options for fields.</td></tr>
<tr><td>get</td><td>get(struct, options:object=void):object </td><td>Return the struct definition.</td></tr>
<tr><td>names</td><td>names(struct:string=void):array </td><td>Return name list of all structs, or fields for one struct.</td></tr>
<tr><td>remove</td><td>remove(name:string) </td><td>Remove a struct.</td></tr>
<tr><td>schema</td><td>schema():string </td><td>Return database schema for struct.</td></tr>

</table>


<a name="CStruct.addOptions"></a>
<a name="CStruct.confOptions"></a>
<h2>Options for "CStruct.add"</h2>
<table border="1" class="optstbl table">
<tr><th>Option</th> <th>Type</th> <th>Description</th><th>Flags</th></tr>
<tr><td>crc</td><td><i>UINT32</i></td><td>Crc for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>flags</td><td><i>INT64</i></td><td>Flags for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>help</td><td><i>STRKEY</i></td><td>Struct description.</td><td><i>initOnly</i></td></tr>
<tr><td>idx</td><td><i>UINT32</i></td><td>Number of fields in struct.</td><td><i>readOnly</i></td></tr>
<tr><td>name</td><td><i>STRKEY</i></td><td>Name of struct.</td><td><i>initOnly|required</i></td></tr>
<tr><td>size</td><td><i>UINT</i></td><td>Size of struct in bytes.</td><td><i>readOnly</i></td></tr>
<tr><td>ssig</td><td><i>UINT32</i></td><td>Signature for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>value</td><td><i>INT64</i></td><td>Reference count.</td><td><i>readOnly</i></td></tr>
</table>


<a name="CStruct.confOptions"></a>
<a name="CStruct.confOptions"></a>
<h2>Options for "CStruct.conf"</h2>
<table border="1" class="optstbl table">
<tr><th>Option</th> <th>Type</th> <th>Description</th><th>Flags</th></tr>
<tr><td>crc</td><td><i>UINT32</i></td><td>Crc for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>flags</td><td><i>INT64</i></td><td>Flags for struct.</td><td><i>initOnly</i></td></tr>
<tr><td>help</td><td><i>STRKEY</i></td><td>Struct description.</td><td><i>initOnly</i></td></tr>
<tr><td>idx</td><td><i>UINT32</i></td><td>Number of fields in struct.</td><td><i>readOnly</i></td></tr>
<tr><td>name</td><td><i>STRKEY</i></td><td>Name of struct.</td><td><i>initOnly|required</i></td></tr>
................................................................................
<hr>


<h1>CType</h1>

<font color=red>Synopsis:CType.method(...)

</font><p>Type commands. Note: Type() is a shortcut for Type.conf().


<h2>Methods for "CType"</h2>
<table border="1"class="cmdstbl table">
<tr><th>Method</th><th>Prototype</th><th>Description</th></tr>
<tr><td>conf</td><td>conf(typ:string, <a href='#CType.confOptions'>options</a>:object|string=void) </td><td>Configure options for type.</td></tr>
<tr><td>names</td><td>names(ctype=false):array </td><td>Return type names.</td></tr>
</table>