/ Check-in [2ea4655166]
DEMO | DOWNLOAD | DEPLOY | SEARCH
Login

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

Overview
Comment:Release "2.8.18" CData: fix config memory handling.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:2ea4655166225b7bf9c2eb9ffc3e093552f8e2bc
User & Date: pmacdona 2019-04-10 22:45:02
Context
2019-04-12
03:39
Release "2.8.19". Finish sample CData example DBI. check-in: bd26a2d361 user: pmacdona tags: trunk
2019-04-10
22:45
Release "2.8.18" CData: fix config memory handling. check-in: 2ea4655166 user: pmacdona tags: trunk
03:39
Release "2.8.17". - Add warn for duplicate "var" (means lots of scripts changed) - A new example CData example module, DBI (uses libdbi). - CData changes: - Output file is now .c instead of .h - C-code now uses #line to help with compile warnings. - Add arg -noline, to turn off #line when debugging. - Add a new "code" section for raw output. - Added options for struct-fields. - Struct-field names starting with "_" are non-visible/configurable. - Comments now stripped only at top of file. - Fix bug for no-arg commands. check-in: 688524166d user: pmacdona tags: trunk
Changes

Changes to DBI/DBI.jsc.

1
2
3
4
5
6





7
8
9
10
11
12
13
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
...
233
234
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253
254
255
256
...
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
#!/usr/local/bin/jsish -c %s
// The libDBI object.  Create with "new DBI()"

code Header = {
#include <dbi/dbi.h>
};






struct DBI_ = { // Module struct (optional), will be per-interp if no DBI_Data var.
    bool loaded;        // <RO> Module load count.
    int activeCnt;      // Count of active objects.
    int newCnt;         // Total number of new.
    int init;           // is init
    dbi_inst _dbi;      //  db instance
................................................................................
};

struct DBI_toArray = {
    double Max;
    int Cnt;
};

struct DBI_eval = {
    double Max;
    int Cnt;
};
        
struct DBI_id = {
    int id;
    Jsi_HashEntry* _hPtr;
    dbi_result _res;
    DBI* _cmdPtr;
................................................................................
    int resultCount;
    int fieldCount;
    short* _fieldTypes;
    char** _fieldNames;
};

vars DBIVars = {
    DBI_eval DBI_eval_Data;
    DBI_ DBI_Data; // ie. Module struct is not per-interp.
};

extension DBI = { // Extension to create a DBI object command.

    // Anything outside of a 'function' definition is C-code.
    #include "DBIinc.c"
................................................................................
        const char *unquoted = Jsi_ValueArrayIndexToStr(interp, args, 0, &bufLength);
        int newLength = dbi_conn_quote_binary_copy(cmdPtr->_db, (const unsigned char *)unquoted,
            bufLength, (unsigned char **)&quoted );
        Jsi_ValueMakeBlob(interp, ret, (unsigned char *)quoted, newLength);
        return JSI_OK;
    }
    
    function query(query:string, params:array=void):number { // Run query and return id
        /* C-code. */
        int qlen;
        Jsi_Value *params = Jsi_ValueArrayIndex(interp, args, 1);
        const char *qstr = Jsi_ValueArrayIndexToStr(interp, args, 0, &qlen);
        Jsi_DString dStr = {};

        if (!params || !Jsi_ValueGetLength(interp, params))
            Jsi_DSAppendLen(&dStr, qstr, qlen);
        else
            if (DBI_AddArgs(cmdPtr, &dStr, qstr, qlen, params) != JSI_OK)
                return JSI_ERROR;

        dbi_result res = dbi_conn_query( cmdPtr->_db, Jsi_DSValue(&dStr));
        Jsi_DSFree(&dStr);
        if (!res) {
            const char *msg = "N/A";
            int num = dbi_conn_error(cmdPtr->_db, &msg);
................................................................................
    }

    function idconf(id:number, options:object|string=void):any { // Function to configure query id options
        /* C code. */
        return JSI_OK;
    }

    function idseek(id:number, row:number):boolean { // Seek to a row
        /* C code. */
        DBI_id *pss = DBI_IdGet(cmdPtr, id, 0);
        if (!pss)
            return JSI_ERROR;
        bool b = pss->onrecord = dbi_result_seek_row(pss->_res, row+1);
        RETURN(b);
    }

    function idcolumn(id:number, column:number):any { // Fetch a single column value
        /* C code. */
        DBI_id *pss = DBI_IdGet(cmdPtr, id, 0);
        if (!pss)
            return JSI_ERROR;
        return DBI_IdValue(interp, pss, ret, column);
    }
    
    function idrow(id:number):any { // Fetch a row
        /* C code. */
        DBI_id *pss = DBI_IdGet(cmdPtr, id, 0);
        if (!pss)
            return JSI_ERROR;
        Jsi_Obj *res = Jsi_ObjNew(interp);
        Jsi_ValueMakeObject(interp, ret, res);
        //Jsi_IncrRefCount(interp, *ret);
................................................................................
            if (JSI_OK != DBI_IdValue(interp, pss, &v, i))
                Jsi_ValueMakeNull(interp, &v);
            Jsi_ObjInsert(interp, res, pss->_fieldNames[i], v, JSI_OM_READONLY );
        }
        return JSI_OK;
    }

    function idfree(id:number):void { // Delete query id
        /* C code. */
        DBI_id *pss = DBI_IdGet(cmdPtr, id, 0);
        if (!pss)
            return JSI_ERROR;
        Jsi_HashEntryDelete(pss->_hPtr);
        return JSI_OK;
    }


};







>
>
>
>
>







 







|
|
|







 







|







 







|

<
<
<

>

|

|







 







|








|







|







 







|











1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
..
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
...
238
239
240
241
242
243
244
245
246



247
248
249
250
251
252
253
254
255
256
257
258
259
...
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
#!/usr/local/bin/jsish -c %s
// The libDBI object.  Create with "new DBI()"

code Header = {
#include <dbi/dbi.h>
};

enum dbi_resType = {
    rows, arrays, array1d, list, column, json,
    json2, html, csv, insert, line, tabs, id, none
};

struct DBI_ = { // Module struct (optional), will be per-interp if no DBI_Data var.
    bool loaded;        // <RO> Module load count.
    int activeCnt;      // Count of active objects.
    int newCnt;         // Total number of new.
    int init;           // is init
    dbi_inst _dbi;      //  db instance
................................................................................
};

struct DBI_toArray = {
    double Max;
    int Cnt;
};

struct DBI_query = {
    dbi_resType mode;       // Output mode.
    OBJ params;             // Input parameters.
};
        
struct DBI_id = {
    int id;
    Jsi_HashEntry* _hPtr;
    dbi_result _res;
    DBI* _cmdPtr;
................................................................................
    int resultCount;
    int fieldCount;
    short* _fieldTypes;
    char** _fieldNames;
};

vars DBIVars = {
    DBI_query DBI_query_Data;
    DBI_ DBI_Data; // ie. Module struct is not per-interp.
};

extension DBI = { // Extension to create a DBI object command.

    // Anything outside of a 'function' definition is C-code.
    #include "DBIinc.c"
................................................................................
        const char *unquoted = Jsi_ValueArrayIndexToStr(interp, args, 0, &bufLength);
        int newLength = dbi_conn_quote_binary_copy(cmdPtr->_db, (const unsigned char *)unquoted,
            bufLength, (unsigned char **)&quoted );
        Jsi_ValueMakeBlob(interp, ret, (unsigned char *)quoted, newLength);
        return JSI_OK;
    }
    
    function query(query:string, options:object=void):number { // Run query and return id
        /* C-code. */



        Jsi_DString dStr = {};
        Jsi_Value *params = dPtr->params;
        if (!params || !Jsi_ValueGetLength(interp, params))
            Jsi_DSAppendLen(&dStr, query, queryLen);
        else
            if (DBI_AddArgs(cmdPtr, &dStr, query, queryLen, params) != JSI_OK)
                return JSI_ERROR;

        dbi_result res = dbi_conn_query( cmdPtr->_db, Jsi_DSValue(&dStr));
        Jsi_DSFree(&dStr);
        if (!res) {
            const char *msg = "N/A";
            int num = dbi_conn_error(cmdPtr->_db, &msg);
................................................................................
    }

    function idconf(id:number, options:object|string=void):any { // Function to configure query id options
        /* C code. */
        return JSI_OK;
    }

    function seek(id:number, row:number):boolean { // Seek to a row
        /* C code. */
        DBI_id *pss = DBI_IdGet(cmdPtr, id, 0);
        if (!pss)
            return JSI_ERROR;
        bool b = pss->onrecord = dbi_result_seek_row(pss->_res, row+1);
        RETURN(b);
    }

    function column(id:number, column:number):any { // Fetch a single column value
        /* C code. */
        DBI_id *pss = DBI_IdGet(cmdPtr, id, 0);
        if (!pss)
            return JSI_ERROR;
        return DBI_IdValue(interp, pss, ret, column);
    }
    
    function row(id:number):any { // Fetch a row
        /* C code. */
        DBI_id *pss = DBI_IdGet(cmdPtr, id, 0);
        if (!pss)
            return JSI_ERROR;
        Jsi_Obj *res = Jsi_ObjNew(interp);
        Jsi_ValueMakeObject(interp, ret, res);
        //Jsi_IncrRefCount(interp, *ret);
................................................................................
            if (JSI_OK != DBI_IdValue(interp, pss, &v, i))
                Jsi_ValueMakeNull(interp, &v);
            Jsi_ObjInsert(interp, res, pss->_fieldNames[i], v, JSI_OM_READONLY );
        }
        return JSI_OK;
    }

    function free(id:number):void { // Delete query id
        /* C code. */
        DBI_id *pss = DBI_IdGet(cmdPtr, id, 0);
        if (!pss)
            return JSI_ERROR;
        Jsi_HashEntryDelete(pss->_hPtr);
        return JSI_OK;
    }


};

Changes to DBI/Makefile.

1
2
3
4
5
6
7
8
9
10
11
12
13



CDCMD=../jsish -c
#CDCMD=../jsish ../lib/Jsi_CData.jsi
#CDOPTS= -noline true
#CC=cc -fsanitize=address 

DBI.so: DBI.c
	$(CC)  `$(CDCMD) -cflags true DBI.so` -ldbi

DBI.c: DBI.jsc DBIinc.c
	$(CDCMD) $(CDOPTS)  DBI.jsc

test:
	../jsish --U dbi_mysql.jsi





|










>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CDCMD=../jsish -c
#CDCMD=../jsish ../lib/Jsi_CData.jsi
CDOPTS= -noline true
#CC=cc -fsanitize=address 

DBI.so: DBI.c
	$(CC)  `$(CDCMD) -cflags true DBI.so` -ldbi

DBI.c: DBI.jsc DBIinc.c
	$(CDCMD) $(CDOPTS)  DBI.jsc

test:
	../jsish --U dbi_mysql.jsi

clean:
	rm -f DBI.c DBI.so DBI DBIsh

Changes to DBI/dbi_mysql.jsi.

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
52
//var opts = { driver:'sqlite', dbname:'test2.db', sqlite_dbdir:'/tmp' }; 

var id, db = new DBI(opts);
;db.open();
;db.check();
;db.conf();

;// db.conf({driver:'sqlite'});
;// db.conf({isopen:false});

;id = db.query('SELECT * FROM test1;');
;db.idconf(id);
;db.idcolumn(id,0);
;db.idrow(id);

;id = db.query('SELECT * FROM test1 WHERE last=%1;', ['Box']);
;db.ids();
;db.idconf(id);
;db.idrow(id);
;db.idseek(id,3);
;db.idrow(id);
;db.idfree(id);










delete db;

/*
=!EXPECTSTART!=
db.open() ==> true
db.check() ==> true
................................................................................
db.conf() ==> { callback:null, dbname:"jsitest", driver:"mysql", drvOpts:null, encoding:null, host:"localhost", isopen:true, password:"abc", port:3306, sqlite_dbdir:null, sqlite_timeout:0, timeout:0, username:"jsish", version:900 }
db.conf({driver:'sqlite'}) ==>
PASS!: err = Error can not update option: "driver"
db.conf({isopen:false}) ==>
PASS!: err = Error option is readonly: "isopen"
id = db.query('SELECT * FROM test1;') ==> 1
db.idconf(id) ==> { fieldCount:3, id:1, onrecord:true, resultCount:26 }
db.idcolumn(id,0) ==> 44
db.idrow(id) ==> { id:44, last:"Box", name:"Barry" }
id = db.query('SELECT * FROM test1 WHERE last=%1;', ['Box']) ==> 2
db.ids() ==> { 1:2 }
db.idconf(id) ==> { fieldCount:3, id:2, onrecord:true, resultCount:26 }
db.idrow(id) ==> { id:44, last:"Box", name:"Barry" }
db.idseek(id,3) ==> true
db.idrow(id) ==> { id:44, last:"Box", name:"Barry" }
db.idfree(id) ==> undefined
=!EXPECTEND!=
*/







<
<

|

|
|

|


|
|
|
|
>
>
>
>
>
>
>
>
>







 







|
|



|
|
|
|


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
52
53
54
55
56
57
58
59
//var opts = { driver:'sqlite', dbname:'test2.db', sqlite_dbdir:'/tmp' }; 

var id, db = new DBI(opts);
;db.open();
;db.check();
;db.conf();




;id = db.query('SELECT * FROM test1;', {mode:'id'});
;db.idconf(id);
;db.column(id,0);
;db.row(id);

;id = db.query('SELECT * FROM test1 WHERE last=%1;', {params:['Box'], mode:'id'});
;db.ids();
;db.idconf(id);
;db.row(id);
;db.seek(id,3);
;db.row(id);
;db.free(id);

;db.query('SELECT * FROM test1 WHERE last=%1;', {params:['Box'], mode:'rows'});

;' --- FAIL TESTS ---- ';
;// db.conf({driver:'sqlite'});
;// db.conf({isopen:false});
;//db.query('SELECT * FROM test1;', {params:['Box'], qag:9});
;//db.query('SELECT * FROM test1;', {bag:9});
;//db.query('SELECT * FROM test1;', {mode:'xx'});

delete db;

/*
=!EXPECTSTART!=
db.open() ==> true
db.check() ==> true
................................................................................
db.conf() ==> { callback:null, dbname:"jsitest", driver:"mysql", drvOpts:null, encoding:null, host:"localhost", isopen:true, password:"abc", port:3306, sqlite_dbdir:null, sqlite_timeout:0, timeout:0, username:"jsish", version:900 }
db.conf({driver:'sqlite'}) ==>
PASS!: err = Error can not update option: "driver"
db.conf({isopen:false}) ==>
PASS!: err = Error option is readonly: "isopen"
id = db.query('SELECT * FROM test1;') ==> 1
db.idconf(id) ==> { fieldCount:3, id:1, onrecord:true, resultCount:26 }
db.column(id,0) ==> 44
db.row(id) ==> { id:44, last:"Box", name:"Barry" }
id = db.query('SELECT * FROM test1 WHERE last=%1;', ['Box']) ==> 2
db.ids() ==> { 1:2 }
db.idconf(id) ==> { fieldCount:3, id:2, onrecord:true, resultCount:26 }
db.row(id) ==> { id:44, last:"Box", name:"Barry" }
db.seek(id,3) ==> true
db.row(id) ==> { id:44, last:"Box", name:"Barry" }
db.free(id) ==> undefined
=!EXPECTEND!=
*/

Changes to lib/Jsi_CData.jsi.

26
27
28
29
30
31
32
33

34


35
36
37
38
39
40
41
...
647
648
649
650
651
652
653


654
655
656
657
658
659



660
661
662


663
664
665
666
667
668
669
...
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
...
788
789
790
791
792
793
794
795
796

797
798
799
800
801
802
803


804
805
806
807
808
809
810
...
846
847
848
849
850
851
852



853
854
855
856
857
858
859
...
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
...
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
....
1418
1419
1420
1421
1422
1423
1424










1425
1426
1427
1428
1429
1430
1431
....
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
        pre:'', pre0:'', pre1:'', out0:'', out1:'', out:'', iout:'',
        init:[], types:'',  structs:'', enums:'', vars:'', cmds:'',
        varnames:[], mapnames:[], cmdnames:[], 
        structmap:{}, enummap:{}, enumzero:{},
        vardefs:'',  siglst:[], varinits:'', mapinits:'', enumIni:{},
        portlst:[], statlst:[], cmddefs:'', cmddef:'',
        enumvals:{}, indata:'', infile:'', outFile:null, rootname:null,
        lnstart:0, setCons:0, icode:[], outcode:''

    };


    var Ex = {asize:0, offs:1, size:2, sig:3};
    var EV = { enum:[], struct:[], vars:[] };

    parseOpts(self, options, conf);

    var defs = {structs:[], enums:[], types:[], vars:[], cmds:[]};
    //var popts = { hassig:true, hassiz:false, builtinhassig:true};
................................................................................
                self.icode[name+fname] = '{\n'+flnhash+fbody+'\n';
                continue;
            }
            if (keys.indexOf(fname)>=0)
                throw("function name can not be a keyword: "+fname);
            if (!fre[3] || fre[3] == ':')
                throw "must specify a return type for function: "+fname;


            var fcmdName = name+fname+'Cmd';
            ifpre += '\n// function '+fre[1]+'('+fre[2]+')'+fre[3];
            var ifprecc = '\nstatic Jsi_RC '+fcmdName+'(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr';
            var isObjNew = (isObj && name === fname);
            if (isObjNew) {
                ifprecc += ', '+otyp+' *cmdPtr';



            }
            ifprecc += ')';
            ifpre += ifprecc +' {\n';


            if (isObj && !fconstr) {
                if (!self.setCons)
                    self.out += '#define CDATA_CONSTRUCTOR 1\n';
                self.setCons=1;
                ifpre += '  '+otyp+' *cmdPtr = ('+otyp+' *)Jsi_UserObjGetData(interp, _this, funcPtr);\n'
                    + '  if (!cmdPtr) { Jsi_LogError("Apply in a non object"); return JSI_ERROR; }\n';
            } else if (intData) {
................................................................................
                else if (minargs!==alst.length)
                    throw "non-default value follows default: "+aval+' in function: '+fname;
                
                var voao = 'Jsi_ValueArrayIndex(interp, args, '+i+')';
                    
                if (tlen===1) {
                    iat = tvlst[0];
                    var iftn = 'Jsi_Value*';
                    iasfx = (tlen===1?'':'_'+iat);
                    switch (iat) {
                        case 'boolean': iftn = 'bool'; ttnam = 'Bool'; break;
                        case 'number': iftn = 'Jsi_Number'; ttnam = 'Number'; break;
                        case 'string': iftn = 'const char*';
                            if (tlen==1)
                                vget='if (Jsi_ValueGetLength(interp, args) > '+i+' && !('+afnam+'=Jsi_ValueString(interp, '+voao+',NULL))) '
                                + '{ Jsi_LogError("expected string"); return JSI_ERROR; }\n';
                            break;
                    }
                    ifpre += ind+iftn + ' '+afnam+iasfx+' = '+dv+';\n';
                    if (ttnam !== '' && vget === '')
                        vget='if (Jsi_ValueGetLength(interp, args) > '+i+' && Jsi_Get'+ttnam+'FromValue(interp, '+voao+', &'+afnam+') != JSI_OK) '
                        + '\n'+ind+'  { Jsi_LogError("expected '+atyp+'"); return JSI_ERROR; }\n';
                }
                if (vget !== '')
                    ifpre += ind + vget;

................................................................................
                            iodnam = '&'+name+self.varSuffix;
                    } else if (fname === 'idconf') {
                        // Cmd-local options.
                        iodnam = 'dPtr';
                        ifpre += '  '+iopnam + ' *dPtr = '+name+'_IdGet(cmdPtr, id, 0);\n';
                    } else {
                        // Cmd-local options.
                        iodnam = '&data';
                        ifpre += '  '+iopnam + ' data = {};\n';

                    }
                    if (fname === 'conf') {
                        if (i>0) throw("Conf command takes only a single argument");
                        ifpre += '  return Jsi_OptionsConf(interp, (Jsi_OptionSpec*)'+iopnamS+', '+iodnam+', '+voao+', ret, 0);\n';
                    } else if (fname === 'idconf') {
                        ifpre += '  if (!dPtr || Jsi_OptionsConf(interp, (Jsi_OptionSpec*)'+iopnamS+', '+iodnam+', '+voao+', ret, 0) < 0) return JSI_ERROR;\n';
                    } else {


                        ifpre += '  if ('+voao+' && Jsi_OptionsProcess(interp, (Jsi_OptionSpec*)'+iopnamS+', '+iodnam+', '+voao+', 0) < 0) return JSI_ERROR;\n';
                    }
                }

            }
            var fcmdNameI =  (isObj && fconstr ? name+'Constructor': fcmdName);
            ffpre += ind+'{ "'+fname+'",\t'+fcmdNameI+',\t'+minargs+','+maxargs+',"'+args+'", .help="'+fhelp
................................................................................
                    i = '        '+i;
                }
                ofbody += i + '\n';
            }
            ifpre += ofbody+'\n';
            if (fconstr)
                ifpre += format(self.objCmdStr.replace(/Demo/g, name), self.icode[name+'~'], self.icode[name+'_']);



        }
        if (hastilde && !hasconstr)
            throw('defined "function ~" without constructor');
        ffpre += ind+'{ NULL, .help="'+def.label+'" }\n  };\n';
        self.cmddef += '\n' + ifpre + ffpre;
        if (isObj)
            self.cmddefs += ''; //'\n  if (Jsi_Init'+name+'(interp, 0) != JSI_OK) return NULL;\n';
................................................................................
#endif
';

    function CDataFinalize () {
        var name = self.name;
        var scnm = self.icode[name+'_'];
        if (!scnm) scnm = '';
        self.out = '// DO NOT EDIT: file generated by Jsi_CData.jsi from: '+self.infile+'\n\n'
            + self.jscHeaderStr.replace(/Demo/g, name) + self.outcode
        /*+ "#ifndef _JSI_CDEFS_"+name+"_H_\n"
        + "#define _JSI_CDEFS_"+name+"_H_\n\n"
        + '#define _GNU_SOURCE\n#include <string.h>\n#ifdef JSI_CDATA_MAIN\n#define JSI_CDATA_IMPL\n\n'
        + '#ifdef JSI_CDATA_SHARED\n#define JSI_USE_STUBS 1\n#include "jsi.h"\n#else\n#include "jsi.c"\n#endif\n#endif\n\n' */
        + self.pre0 + '\n' + self.pre + "\n#ifdef JSI_CDATA_IMPL\n\nJSI_EXTENSION_INI\n#undef JSI_EXTENSION_INI\n#define JSI_EXTENSION_INI\n"
        + self.out0 + self.out + self.out1
................................................................................

        + "\n  return &CS_STATICS_"+name+";\n}\n\n"
        + "\n#endif\n#endif\n"
        + format(self.selfSuffix.replace(/Demo/g, name), scnm);
        if (self.outFile) {
            if (File.exists(self.outFile)) {
                var ofpre = File.read(self.outFile),
                    ofpp1 = '// DO NOT EDIT: file generated by Jsi_CData.jsi from';
                if (ofpre && ofpre.substr(0, ofpp1.length) != ofpp1)
                    throw('can not overwrite non-generated file: '+self.outFile);
            }
            File.write(self.outFile, self.out);
        } else
            return(self.out);
    }
................................................................................
    }
    
    function main() {
        var rc = mainSub();
        if ('' !== rc)
            return rc;
    }










    
    self.objCmdStr = '

// Start of template code for object commands.

static Jsi_CmdSpec DemoCmds[];

................................................................................

    var retval = main();
    if (retval === undefined)
        return '';
    return retval;
}

provide(Jsi_CData, 1);

if (isMain())
    runModule(Jsi_CData);








|
>

>
>







 







>
>
|

<
<

|
>
>
>

<
<
>
>







 







|




|

|



|







 







|
|
>







>
>







 







>
>
>







 







|







 







|







 







>
>
>
>
>
>
>
>
>
>







 







|




26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
...
650
651
652
653
654
655
656
657
658
659
660


661
662
663
664
665
666


667
668
669
670
671
672
673
674
675
...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
...
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
...
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
...
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
...
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
....
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
....
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
        pre:'', pre0:'', pre1:'', out0:'', out1:'', out:'', iout:'',
        init:[], types:'',  structs:'', enums:'', vars:'', cmds:'',
        varnames:[], mapnames:[], cmdnames:[], 
        structmap:{}, enummap:{}, enumzero:{},
        vardefs:'',  siglst:[], varinits:'', mapinits:'', enumIni:{},
        portlst:[], statlst:[], cmddefs:'', cmddef:'',
        enumvals:{}, indata:'', infile:'', outFile:null, rootname:null,
        lnstart:0, setCons:0, icode:[], outcode:'',
        preface: '// DO NOT EDIT: file generated by Jsi_CData.jsi'
    };
    self.pkg = require('Jsi_CData', 0);
    self.version = self.pkg.version;
    var Ex = {asize:0, offs:1, size:2, sig:3};
    var EV = { enum:[], struct:[], vars:[] };

    parseOpts(self, options, conf);

    var defs = {structs:[], enums:[], types:[], vars:[], cmds:[]};
    //var popts = { hassig:true, hassiz:false, builtinhassig:true};
................................................................................
                self.icode[name+fname] = '{\n'+flnhash+fbody+'\n';
                continue;
            }
            if (keys.indexOf(fname)>=0)
                throw("function name can not be a keyword: "+fname);
            if (!fre[3] || fre[3] == ':')
                throw "must specify a return type for function: "+fname;
            var ifpost = '', ifpostarg = '', ifprecc2;
            var isObjNew = (isObj && fconstr);
            var fcmdName = name+fname+'Cmd', fcmdName2 = fcmdName;
            ifpre += '\n// function '+fre[1]+'('+fre[2]+')'+fre[3];


            if (isObjNew) {
                ifprecc2 = ', '+otyp+' *cmdPtr';
            } else {
                ifprecc2 = ',  Jsi_VarRef *vrPtr';
                fcmdName2 += 'Sub';
            }


            var fcprefix = '(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr';
            ifpre += '\nstatic Jsi_RC '+fcmdName2 + fcprefix + ifprecc2 + ') {\n';
            if (isObj && !fconstr) {
                if (!self.setCons)
                    self.out += '#define CDATA_CONSTRUCTOR 1\n';
                self.setCons=1;
                ifpre += '  '+otyp+' *cmdPtr = ('+otyp+' *)Jsi_UserObjGetData(interp, _this, funcPtr);\n'
                    + '  if (!cmdPtr) { Jsi_LogError("Apply in a non object"); return JSI_ERROR; }\n';
            } else if (intData) {
................................................................................
                else if (minargs!==alst.length)
                    throw "non-default value follows default: "+aval+' in function: '+fname;
                
                var voao = 'Jsi_ValueArrayIndex(interp, args, '+i+')';
                    
                if (tlen===1) {
                    iat = tvlst[0];
                    var iftn = 'Jsi_Value*', iftnpost = '';
                    iasfx = (tlen===1?'':'_'+iat);
                    switch (iat) {
                        case 'boolean': iftn = 'bool'; ttnam = 'Bool'; break;
                        case 'number': iftn = 'Jsi_Number'; ttnam = 'Number'; break;
                        case 'string': iftn = 'const char*'; iftnpost = ' int '+afnam+'Len = 0;';
                            if (tlen==1)
                                vget='if (Jsi_ValueGetLength(interp, args) > '+i+' && !('+afnam+'=Jsi_ValueString(interp, '+voao+', &'+afnam+'Len))) '
                                + '{ Jsi_LogError("expected string"); return JSI_ERROR; }\n';
                            break;
                    }
                    ifpre += ind+iftn + ' '+afnam+iasfx+' = '+dv+';\n' + iftnpost;
                    if (ttnam !== '' && vget === '')
                        vget='if (Jsi_ValueGetLength(interp, args) > '+i+' && Jsi_Get'+ttnam+'FromValue(interp, '+voao+', &'+afnam+') != JSI_OK) '
                        + '\n'+ind+'  { Jsi_LogError("expected '+atyp+'"); return JSI_ERROR; }\n';
                }
                if (vget !== '')
                    ifpre += ind + vget;

................................................................................
                            iodnam = '&'+name+self.varSuffix;
                    } else if (fname === 'idconf') {
                        // Cmd-local options.
                        iodnam = 'dPtr';
                        ifpre += '  '+iopnam + ' *dPtr = '+name+'_IdGet(cmdPtr, id, 0);\n';
                    } else {
                        // Cmd-local options.
                        iodnam = 'dPtr';
                        ifpostarg += '  '+iopnam + ' data = {}; vr.data = (void*)&data;\n';
                        ifpre += '  '+iopnam + ' *dPtr = ('+iopnam+'*)vrPtr->data;\n';
                    }
                    if (fname === 'conf') {
                        if (i>0) throw("Conf command takes only a single argument");
                        ifpre += '  return Jsi_OptionsConf(interp, (Jsi_OptionSpec*)'+iopnamS+', '+iodnam+', '+voao+', ret, 0);\n';
                    } else if (fname === 'idconf') {
                        ifpre += '  if (!dPtr || Jsi_OptionsConf(interp, (Jsi_OptionSpec*)'+iopnamS+', '+iodnam+', '+voao+', ret, 0) < 0) return JSI_ERROR;\n';
                    } else {
                        if (!fconstr)
                            ifpre += '  if ('+voao+') { vrPtr->spec = (Jsi_OptionSpec*)'+iopnamS+'; }\n';
                        ifpre += '  if ('+voao+' && Jsi_OptionsProcess(interp, (Jsi_OptionSpec*)'+iopnamS+', '+iodnam+', '+voao+', 0) < 0) return JSI_ERROR;\n';
                    }
                }

            }
            var fcmdNameI =  (isObj && fconstr ? name+'Constructor': fcmdName);
            ffpre += ind+'{ "'+fname+'",\t'+fcmdNameI+',\t'+minargs+','+maxargs+',"'+args+'", .help="'+fhelp
................................................................................
                    i = '        '+i;
                }
                ofbody += i + '\n';
            }
            ifpre += ofbody+'\n';
            if (fconstr)
                ifpre += format(self.objCmdStr.replace(/Demo/g, name), self.icode[name+'~'], self.icode[name+'_']);
            if (!isObjNew)
                ifpost += format(self.objOptCmdStr, fcmdName, ifpostarg, fcmdName);
            ifpre += ifpost;
        }
        if (hastilde && !hasconstr)
            throw('defined "function ~" without constructor');
        ffpre += ind+'{ NULL, .help="'+def.label+'" }\n  };\n';
        self.cmddef += '\n' + ifpre + ffpre;
        if (isObj)
            self.cmddefs += ''; //'\n  if (Jsi_Init'+name+'(interp, 0) != JSI_OK) return NULL;\n';
................................................................................
#endif
';

    function CDataFinalize () {
        var name = self.name;
        var scnm = self.icode[name+'_'];
        if (!scnm) scnm = '';
        self.out = self.preface + ' ' + self.version + ' from: '+self.infile+'\n\n'
            + self.jscHeaderStr.replace(/Demo/g, name) + self.outcode
        /*+ "#ifndef _JSI_CDEFS_"+name+"_H_\n"
        + "#define _JSI_CDEFS_"+name+"_H_\n\n"
        + '#define _GNU_SOURCE\n#include <string.h>\n#ifdef JSI_CDATA_MAIN\n#define JSI_CDATA_IMPL\n\n'
        + '#ifdef JSI_CDATA_SHARED\n#define JSI_USE_STUBS 1\n#include "jsi.h"\n#else\n#include "jsi.c"\n#endif\n#endif\n\n' */
        + self.pre0 + '\n' + self.pre + "\n#ifdef JSI_CDATA_IMPL\n\nJSI_EXTENSION_INI\n#undef JSI_EXTENSION_INI\n#define JSI_EXTENSION_INI\n"
        + self.out0 + self.out + self.out1
................................................................................

        + "\n  return &CS_STATICS_"+name+";\n}\n\n"
        + "\n#endif\n#endif\n"
        + format(self.selfSuffix.replace(/Demo/g, name), scnm);
        if (self.outFile) {
            if (File.exists(self.outFile)) {
                var ofpre = File.read(self.outFile),
                    ofpp1 = self.preface;
                if (ofpre && ofpre.substr(0, ofpp1.length) != ofpp1)
                    throw('can not overwrite non-generated file: '+self.outFile);
            }
            File.write(self.outFile, self.out);
        } else
            return(self.out);
    }
................................................................................
    }
    
    function main() {
        var rc = mainSub();
        if ('' !== rc)
            return rc;
    }
    
    self.objOptCmdStr = '
static Jsi_RC %s(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr) {
    Jsi_VarRef vr = {};
    %s
    Jsi_RC rc = %sSub(interp, args, _this, ret, funcPtr, &vr);
    if (vr.data &&  vr.spec)
        Jsi_OptionsFree(interp, vr.spec, vr.data, 0);
    return rc;
}';
    
    self.objCmdStr = '

// Start of template code for object commands.

static Jsi_CmdSpec DemoCmds[];

................................................................................

    var retval = main();
    if (retval === undefined)
        return '';
    return retval;
}

provide(Jsi_CData, "2");

if (isMain())
    runModule(Jsi_CData);

Changes to src/jsi.c.

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   8
#define JSI_VERSION_RELEASE 17

#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   8
#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

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   8
#define JSI_VERSION_RELEASE 17

#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   8
#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

Changes to tools/protos.jsi.

1
2
3
4
5
6
7
8
//JSI Command Prototypes: version 2.8.17
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 {};
|







1
2
3
4
5
6
7
8
//JSI Command Prototypes: version 2.8.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 {};