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

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

Overview
Comment:Release "2.8.35". Add null support to puts.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:e46317169af31c71df2c098613c49047d1de2c37
User & Date: pmacdona 2019-06-03 23:51:02
Context
2019-06-09
01:35
Release "2.8.36". Initial relase of "jsig.js" check-in: 6cd81c15d5 user: pmacdona tags: trunk
2019-06-03
23:51
Release "2.8.35". Add null support to puts. check-in: e46317169a user: pmacdona tags: trunk
2019-06-01
14:17
More jsiweb -> jsig changes. check-in: 8c1c2dd67c user: pmacdona tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to lib/Jsi_DebugUI/html/main.htmli.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html style="height: 100%">
  <head>
    <meta charset=utf-8 />
    <title>DebugUI</title>
    <link rel="icon" href="data:;base64,iVBORw0KGgo=">

    <script src="/jsi/web/jsig.js"></script>
    <script src="/jsi/web/bind.js"></script>
<? 
    // Load .jsi and .cssi for preprocessing inline.
    include(['debugui.jsi', 'debugui.cssi']);
?>
  </head>
  <body id="body" onload="onload()" style="display: flex; height: 97%; flex-direction: column; margin:3px">







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html style="height: 100%">
  <head>
    <meta charset=utf-8 />
    <title>DebugUI</title>
    <link rel="icon" href="data:;base64,iVBORw0KGgo=">

    <script src="/jsi/web/JSig.js"></script>
    <script src="/jsi/web/bind.js"></script>
<? 
    // Load .jsi and .cssi for preprocessing inline.
    include(['debugui.jsi', 'debugui.cssi']);
?>
  </head>
  <body id="body" onload="onload()" style="display: flex; height: 97%; flex-direction: column; margin:3px">

Changes to lib/Jsi_GenDeep.jsi.

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

    function main() {
        if (self.create) {
            File.copy('/zvfs/lib/web/markdeep/include.shtml', 'include.shtml');
            File.copy('/zvfs/lib/web/markdeep/nginx_deepdoc.conf', 'nginx_deepdoc.conf');
            File.copy('/zvfs/lib/web/markdeep/jsistyle.css', 'jsistyle.css');
            File.copy('/zvfs/lib/web/dumpdeep.js', 'dumpdeep.js');
            File.copy('/zvfs/lib/web/jsig.js', 'jsig.js');
            File.copy('/zvfs/lib/web/markdeep.min.js', 'markdeep.min.js');
            File.mkdir('md');
            File.copy('/zvfs/lib/web/markdeep/DeepDoc.md', 'md/DeepDoc.md');
            puts("DeepDoc created. View with 'jsish -W -url Deepdoc'");
            return;
        }
        var fl = [];







|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

    function main() {
        if (self.create) {
            File.copy('/zvfs/lib/web/markdeep/include.shtml', 'include.shtml');
            File.copy('/zvfs/lib/web/markdeep/nginx_deepdoc.conf', 'nginx_deepdoc.conf');
            File.copy('/zvfs/lib/web/markdeep/jsistyle.css', 'jsistyle.css');
            File.copy('/zvfs/lib/web/dumpdeep.js', 'dumpdeep.js');
            File.copy('/zvfs/lib/web/JSig.js', 'jsig.js');
            File.copy('/zvfs/lib/web/markdeep.min.js', 'markdeep.min.js');
            File.mkdir('md');
            File.copy('/zvfs/lib/web/markdeep/DeepDoc.md', 'md/DeepDoc.md');
            puts("DeepDoc created. View with 'jsish -W -url Deepdoc'");
            return;
        }
        var fl = [];

Changes to lib/Jsi_Htmlpp.jsi.

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
                        continue;
                    }
                    pre += "<script>"+begin;
                    if (!ispp) 
                        pre += File.read(fn);
                    else {
                        if (self.jsifiles.length==1 && self.noCheck) {
                            pre += File.read(self.dir+'/web/jsig.js');
                            if (self.noCheck)
                                pre += 'Jsi.conf({enable:false});\n';
                        }
                        pre += Jsi_Jspp([fn]);
                    }
                    pre += end + "</script>\n";
                    echo(pre);







|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
                        continue;
                    }
                    pre += "<script>"+begin;
                    if (!ispp) 
                        pre += File.read(fn);
                    else {
                        if (self.jsifiles.length==1 && self.noCheck) {
                            pre += File.read(self.dir+'/web/JSig.js');
                            if (self.noCheck)
                                pre += 'Jsi.conf({enable:false});\n';
                        }
                        pre += Jsi_Jspp([fn]);
                    }
                    pre += end + "</script>\n";
                    echo(pre);

Changes to lib/Jsi_Jspp.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
..
59
60
61
62
63
64
65
66


67
68
69
70
71
72
73
...
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
 * 
 *    function foo(s:string='', n:number=1):string {
 * 
 * becomes
 * 
 *    function foo(s, n) { s=Jsi.ArgCheck(...
 * 
 * Code to perform type checking/default values is provided by "web/jsig.js".
 * 
 * Limitation: Comments within function signatures are not supported.
 */

function Jsi_Jspp(files:array|string=null, conf:object=undefined):string|object
{
    var options = { // A JS preprocessor to convert "typed" functions out to web-browser compatible form
        checkRet    :false,     // Check return code by creating wrapper functions
        disable     :false,     // Preprocess to vanilla JS. WARNING: use of default values may break things.
        listFuncs   :false,     // Echo function list.
        inline      :false,     // Inline signature parse.
        noCheck     :false      // Disable argument type checking.
    };
    var self = {
        funcLst:[],         // List of functions
        funcIdx:0,          // Func idx.
        curFile:'',         // Current file being processed.
        tail:''             // Basename of file.
................................................................................
        if (str.indexOf(':')<0 && !someDflt) // Skip functions with no types or defaults
            return str;
        var res = 'function '+fnam+'(';
    
        var astr = vals[2].trim();
        var rettyp = vals[3].substr(1);
        var cres = '', ncres = '';
        if (!self.inline)


            cres += '$jsig("'+fnam+'('+astr+')'+vals[3]+'", arguments ); ';
        //res += '/* Fn('+astr+') */ ';
        var acall = [];
        if (astr !== '') {
            var alst = astr.split(',');
            var minargs = alst.length, maxargs = minargs;
            var last = alst.length-1;
................................................................................
                            minargs = i;
                    }
                    else if (minargs!==alst.length)
                        throw "non-default value follows default: "+aval+' in: '+str;
                }
                acres.push('{name:"'+afnam+'", type:'+JSON.stringify(atyp)+', def:'+defval+'}');
            }
            if (self.inline)
                cres += '  $jsig({name:"'+fnam+'",astr:"'+astr+'",args:['+acres.join(',')+'],min:'+minargs+',max:'+maxargs+',rettyp:"'+rettyp+'"}, arguments); ';
        }
        cres += ncres;
        res += ')'+vals[4]+' { ';
        if (fnam !== '' && rettyp !== '' && rettyp !== 'any' && self.checkRet) {
            typeValidate(rettyp);
            var wfn = '__Jsi_WrapRet_'+self.tail+'_'+fnam+'_'+ ++self.funcIdx;
            cres += '  var __ret = '+wfn+'('+acall.join(',')+');\n';







|










|







 







|
>
>







 







|
|







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
..
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
 * 
 *    function foo(s:string='', n:number=1):string {
 * 
 * becomes
 * 
 *    function foo(s, n) { s=Jsi.ArgCheck(...
 * 
 * Code to perform type checking/default values is provided by "web/JSig.js".
 * 
 * Limitation: Comments within function signatures are not supported.
 */

function Jsi_Jspp(files:array|string=null, conf:object=undefined):string|object
{
    var options = { // A JS preprocessor to convert "typed" functions out to web-browser compatible form
        checkRet    :false,     // Check return code by creating wrapper functions
        disable     :false,     // Preprocess to vanilla JS. WARNING: use of default values may break things.
        listFuncs   :false,     // Echo function list.
        inline      :false,      // Inline signature parse.
        noCheck     :false      // Disable argument type checking.
    };
    var self = {
        funcLst:[],         // List of functions
        funcIdx:0,          // Func idx.
        curFile:'',         // Current file being processed.
        tail:''             // Basename of file.
................................................................................
        if (str.indexOf(':')<0 && !someDflt) // Skip functions with no types or defaults
            return str;
        var res = 'function '+fnam+'(';
    
        var astr = vals[2].trim();
        var rettyp = vals[3].substr(1);
        var cres = '', ncres = '';
        if (self.inline)
            cres += 'if ($jsig("'+fnam+'('+astr+')'+vals[3]+'", arguments )) ($jsi.errorFunc())($jsi.errGet()); ';
        else
            cres += '$jsig("'+fnam+'('+astr+')'+vals[3]+'", arguments ); ';
        //res += '/* Fn('+astr+') */ ';
        var acall = [];
        if (astr !== '') {
            var alst = astr.split(',');
            var minargs = alst.length, maxargs = minargs;
            var last = alst.length-1;
................................................................................
                            minargs = i;
                    }
                    else if (minargs!==alst.length)
                        throw "non-default value follows default: "+aval+' in: '+str;
                }
                acres.push('{name:"'+afnam+'", type:'+JSON.stringify(atyp)+', def:'+defval+'}');
            }
            //if (self.inline)
            //    cres += '  $jsig({name:"'+fnam+'",astr:"'+astr+'",args:['+acres.join(',')+'],min:'+minargs+',max:'+maxargs+',rettyp:"'+rettyp+'"}, arguments); ';
        }
        cres += ncres;
        res += ')'+vals[4]+' { ';
        if (fnam !== '' && rettyp !== '' && rettyp !== 'any' && self.checkRet) {
            typeValidate(rettyp);
            var wfn = '__Jsi_WrapRet_'+self.tail+'_'+fnam+'_'+ ++self.funcIdx;
            cres += '  var __ret = '+wfn+'('+acall.join(',')+');\n';

Changes to lib/Jsi_SqliteUI/html/main.htmli.

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<head>
<title>SqliteUI</title>
<!--
<script src='sqlite.js'></script> 
<link rel="stylesheet" type="text/css" href="sqlite.css">
-->
<script src='/SqliteUI/jsi/web/jsig.js'></script> 
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<? 
// Load .jsi and .cssi for preprocessing.
include(['sqlite.jsi', 'sqlite.cssi'], true);
?>
</head>








|







3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<head>
<title>SqliteUI</title>
<!--
<script src='sqlite.js'></script> 
<link rel="stylesheet" type="text/css" href="sqlite.css">
-->
<script src='/SqliteUI/jsi/web/JSig.js'></script> 
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<? 
// Load .jsi and .cssi for preprocessing.
include(['sqlite.jsi', 'sqlite.cssi'], true);
?>
</head>

Name change from lib/web/jsig.js to lib/web/JSig.js.

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
60
61
62
..
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
100
101
102
103
104
105
106

107

108
109



110
111
112
113
114
115
116
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
...
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
224
225
...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
...
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
    typeNameStr="number string boolean array function object regexp any userobj void null undefined",
    typeNameLst= typeNameStr.split(' '),
    sigs = {},
    srcList = [],
    srcCnt = 0,
    onloadFunc = null,
    funcLst = [],

    ENDSTR = '<!--JSIG GEN-->',



    config = {

        enable:true,
        alert:false,
        debug:false,
        fatal :false,
        traceback:false,
        inline:true
    },





    isChrome = (window.chrome && window.navigator.vendor === "Google Inc.")
;

// Code to handle function parameter types and default values.
function Jsi() {
}

Jsi.prototype = {
    
    errorCmd: function(msg) {
        // Set breakpoint here to intercept function type warnings.
        console.error(msg);
        if (config.traceback)
            console.trace();
        if (config.alert) alert(msg);
        if (config.debug) debugger;
        if (config.fatal) throw(msg);
    },    
    parseError: function(msg) {
        jsi.errorCmd('PARSERR: '+msg+' ==> '+jsi.curSig);
        return [];
    },
    
    conf: function(vals) { // Configure options.
        for (var i in vals) {
            if (typeof config[i] == 'undefined')
                jsi.errorCmd("Option "+i+" not one of: "+Object.keys(config).join(', '));
            else






                config[i] = vals[i];
        }

    },



































    
    ArgCheckType: function(o, aind, val) {
        var af = o.args[aind];
        var tlst = af.typ;
        if (!tlst) return;
        var nam = af.name;
        var vtyp = typeof(val);
................................................................................
                case "regexp":  if (vtyp === 'object' && val && val.constructor === RegExp) return; break;
                case "object":  if (vtyp === 'object' && val && val.constructor !== Array) return; break;
                case "any":     return; break;
                case "userobj": if (vtyp === 'object') return; break;
                case "undefined": case "void": if (val === undefined) return; break;
                case "null": if (val === null) return; break;
                default:
                    puts("type '"+tlst[i]+'" is unknown: not one of: '+typeNameStr);
                    return;
            }
        }
        return 'type mismatch for arg '+(i+1)+' "'+nam+'" expected "'+tlst.join('|')+'" got "'+vtyp+'" '+val;
    },

    $jsig: function(sig, args) { // Check function arguments
................................................................................
        else if (len<o.min)
            msg = "missing arguments: expected "+o.min+" got "+len;
        for (var aind = 0; aind<args.length && !msg; aind++)
            msg = jsi.ArgCheckType(o, aind, args[aind]);
        if (msg) {
            msg+=': calling '+o.name+'('+o.astr+')'+o.retval;
            //msg+=': calling '+o.name+'('+Array.prototype.slice.call(args).join(',')+'), sig ==> FN('+o.astr+')'+o.retval;

            jsi.errorCmd(msg);

        }
        return msg;



    },

    typeValidate: function (typ) {
        if (typ === '') return null;
        var tlst = typ.split('|');
        var i = -1;
        for (i = 0; i<tlst.length; i++)
................................................................................
    SigParse: function(sig) { // Parse string signature and return info.
        jsi.curSig = sig;
        var reg = /^([a-zA-Z0-9_]*)\s*\(([^)]*)\)(:[\|a-z]+|)(\s*)$/;
        var vals = reg.exec(sig);
        var sargs = '';
        if (!vals)
            throw "invalid method: "+sig;
        //puts(vals);
        var fnam = vals[1];
        var someDef = sig.indexOf('=')>=0;
        if (sig.indexOf(':')<0 && !someDef) // Skip functions with no types or defaults
            return [];
        var res = {name:fnam}
    
        var astr = vals[2].trim();
................................................................................
                    maxargs = -1;
                    continue;
                }
                var rega = /^([a-zA-Z0-9_]+)(:[|a-z]+|)(=.+|)$/;
                var avals = rega.exec(aval);
                if (!avals)
                    return jsi.parseError("invalid argument: "+aval);
                //puts(avals);
                if (i)
                    sargs += ', ';
                var afnam = avals[1];
                if (afnam === '' || avals.length<3)
                    afnam = aval;
                sargs += afnam;
                var defval=undefined, atyp = '';
................................................................................
    
    SigConvert: function(code) { // Convert typed functions to work in browser, adding $jsig and default-value set.
        
        function reMethod(str) {
            var reg = /^function\s*([a-zA-Z0-9_]*)\s*\(([^)]*)\)(:[\|a-z]+|)(\s*)\{$/;
            var vals = reg.exec(str);
            if (!vals) {
                puts("invalid method: "+str);
                return str;
            }
            //puts(vals);
            var fnam = vals[1];
            if (fnam !== '' && fnam[0] !== '_')
                funcLst.push(fnam);
            var someDflt = str.indexOf('=')>=0;
            if (str.indexOf(':')<0 && !someDflt) // Skip functions with no types or defaults
                return str;
            var res = 'function '+fnam+'(';
        
            var astr = vals[2].trim();
            if (astr === '')
                res += str + ') {';
            else {
                var sobj = jsi.SigParse(fnam+'('+vals[2]+')'+vals[3]);
                puts('SOBJ',JSON.stringify(sobj));
                res += sobj.sargs+')'+sobj.retval + '{ $jsig("'+sobj.ssig+'", arguments); ';
            }

            return res;
        }
        var reg = /function\s*[a-zA-Z0-9_]*\s*\([^)]*\)(:[\|a-z]+|)\s*\{/g;
        return code.replace(reg, reMethod) + '\n'+ENDSTR;
................................................................................
                    else
                        console.log('Error: ' + xhr.status);
                }
            }
        };                
    },
    srcAdd: function(fn, asData) {
        puts('adding',fn);
        var f=document.createElement('script');
        f.setAttribute("type","text/javascript");
        if (asData)
            f.innerHTML = fn;
        else {
            f.setAttribute("src", fn);
            srcCnt++;
................................................................................
        jsi.ajax({url:fn, success:jsi.srcSuccess, error:jsi.srcError});
    },
    srcDone: function(fn) {
        srcCnt--;
    },
    srcSuccess: function(str) {
        srcCnt--;
        puts('Src Success: '+str);
        var estr = str.substr(str.length-ENDSTR.length);
        if (estr !== ENDSTR) {
            str = jsi.SigConvert(str);
            puts('Src xlate: '+str);
        }
        jsi.srcAdd(str, true);
        //eval.call({}, str);
    },
    srcError: function(str) {
        srcCnt--;
        puts('Src Error: '+str);
    },
    query: function(sel, top) {
        var rc;
        if (typeof sel === 'function') {
            document.addEventListener("DOMContentLoaded", function () {
             sel(); });
            return null;
................................................................................
        return rc;
    },
    
    query1: function(sel, top) {
        var rc = jsi.query(sel, top);
        if (rc && rc.length)
            return rc[0];
        puts('LOOKUP FAILURE: '+sel+' '+top);
        return null;
    },
    onload: function(f) {
        onloadFunc = f;
    },
    DoOnload: function(f) {
        if (srcCnt>0) {
            puts("waiting for src");
            setTimeout(jsi.DoOnload, 1000);
            return;
        }
        if (onloadFunc)
            onloadFunc();
    }

................................................................................
if (typeof win['$$'] === 'undefined')
    win['$$'] = jsi.query1;

if (typeof win['puts'] === 'undefined')
    win['puts'] = console.log.bind(console);
    

puts("Starting jsiweb...");

//eval.call({}, 'function foo() { puts("foo");}');

document.addEventListener('DOMContentLoaded', function() {
    jsi.DoOnload();
}, false);

}());







>

>
>
>

>

<
|
<
<
<

>
>
>
>
>








|
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|
>
>
>
>
>
>

|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







>
|
>


>
>
>







 







|







 







|







 







|


|













|







 







|







 







|



|






|







 







|







|







 







|








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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
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
...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
...
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
...
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
    typeNameStr="number string boolean array function object regexp any userobj void null undefined",
    typeNameLst= typeNameStr.split(' '),
    sigs = {},
    srcList = [],
    srcCnt = 0,
    onloadFunc = null,
    funcLst = [],
    inline = false,
    ENDSTR = '<!--JSIG GEN-->',
    modes = ['assert', 'error', 'warn', 'debug', 'log', 'throw', 'alert'],
    errCnt = 0,
    errCur = null,
    config = {
        mode:'error', 
        enable:true,

        debug:true



    },
    LogDebug = function() {},
    LogTrace = function() {},
    LogTest = function() {},
    LogWarn = console.warn.bind(console),
    LogError = console.error.bind(console),
    isChrome = (window.chrome && window.navigator.vendor === "Google Inc.")
;

// Code to handle function parameter types and default values.
function Jsi() {
}

Jsi.prototype = {
        














    conf: function(vals) { // Configure options.
        for (var i in vals) {
            if (typeof config[i] == 'undefined')
                jsi.errorCmd("Option "+i+" not one of: "+Object.keys(config).join(', '));
            else {
                switch (i) {
                    case 'mode':
                        if (modes.indexOf(vals[i])<0)
                            jsi.errorCmd('invalid mode '+vals[i]+': not one of: '+modes.join(','));
                        break;
                }
                config[i] = vals[i];
            }
        }
    },
    
    errorFunc: function() {
        switch (config.mode) {
            case 'assert':
                if (console.assert) return function(msg) { console.assert(false, msg); };
                debugger;
            case 'throw': return function(msg) { throw(msg); };
            case 'debug':debugger; if (console.error) return console.error;
            case 'error': if (console.error) return console.error;
            case 'warn': if (console.warn) return console.warn;
            case 'log': return console.log;
            case 'alert': return alert;
            default: console.log('unknown mode: '+config.mode);
        }
        return console.log;
    },

    errorCmd: function(msg) {
        errCnt++;
        switch (config.mode) {
            case 'assert': if (console.assert) return console.assert(false, msg);
            case 'debug': if (console.error) { console.error(msg); debugger; return; } debugger;
            case 'error': if (console.error) return console.error(msg);
            case 'warn': if (console.warn) return console.warn(msg);
            case 'log': return console.log(msg);
            case 'throw': throw(msg);
            case 'alert': return alert(msg);
            default: console.log('unknown mode: '+config.mode);
        }
        return console.log(msg);
    },    
    parseError: function(msg) {
        jsi.errorCmd('PARSERR: '+msg+' ==> '+jsi.curSig);
        return [];
    },
    
    ArgCheckType: function(o, aind, val) {
        var af = o.args[aind];
        var tlst = af.typ;
        if (!tlst) return;
        var nam = af.name;
        var vtyp = typeof(val);
................................................................................
                case "regexp":  if (vtyp === 'object' && val && val.constructor === RegExp) return; break;
                case "object":  if (vtyp === 'object' && val && val.constructor !== Array) return; break;
                case "any":     return; break;
                case "userobj": if (vtyp === 'object') return; break;
                case "undefined": case "void": if (val === undefined) return; break;
                case "null": if (val === null) return; break;
                default:
                    jsi.errorCmd("type '"+tlst[i]+'" is unknown: not one of: '+typeNameStr);
                    return;
            }
        }
        return 'type mismatch for arg '+(i+1)+' "'+nam+'" expected "'+tlst.join('|')+'" got "'+vtyp+'" '+val;
    },

    $jsig: function(sig, args) { // Check function arguments
................................................................................
        else if (len<o.min)
            msg = "missing arguments: expected "+o.min+" got "+len;
        for (var aind = 0; aind<args.length && !msg; aind++)
            msg = jsi.ArgCheckType(o, aind, args[aind]);
        if (msg) {
            msg+=': calling '+o.name+'('+o.astr+')'+o.retval;
            //msg+=': calling '+o.name+'('+Array.prototype.slice.call(args).join(',')+'), sig ==> FN('+o.astr+')'+o.retval;
            if (!inline)
                jsi.errorCmd(msg);
            errCur = msg;
        }
        return msg;
    },
    errGet: function() {
        return errCur;
    },

    typeValidate: function (typ) {
        if (typ === '') return null;
        var tlst = typ.split('|');
        var i = -1;
        for (i = 0; i<tlst.length; i++)
................................................................................
    SigParse: function(sig) { // Parse string signature and return info.
        jsi.curSig = sig;
        var reg = /^([a-zA-Z0-9_]*)\s*\(([^)]*)\)(:[\|a-z]+|)(\s*)$/;
        var vals = reg.exec(sig);
        var sargs = '';
        if (!vals)
            throw "invalid method: "+sig;
        LogTrace(vals);
        var fnam = vals[1];
        var someDef = sig.indexOf('=')>=0;
        if (sig.indexOf(':')<0 && !someDef) // Skip functions with no types or defaults
            return [];
        var res = {name:fnam}
    
        var astr = vals[2].trim();
................................................................................
                    maxargs = -1;
                    continue;
                }
                var rega = /^([a-zA-Z0-9_]+)(:[|a-z]+|)(=.+|)$/;
                var avals = rega.exec(aval);
                if (!avals)
                    return jsi.parseError("invalid argument: "+aval);
                LogTrace(avals);
                if (i)
                    sargs += ', ';
                var afnam = avals[1];
                if (afnam === '' || avals.length<3)
                    afnam = aval;
                sargs += afnam;
                var defval=undefined, atyp = '';
................................................................................
    
    SigConvert: function(code) { // Convert typed functions to work in browser, adding $jsig and default-value set.
        
        function reMethod(str) {
            var reg = /^function\s*([a-zA-Z0-9_]*)\s*\(([^)]*)\)(:[\|a-z]+|)(\s*)\{$/;
            var vals = reg.exec(str);
            if (!vals) {
                LogWarn("invalid method: "+str);
                return str;
            }
            LogTrace(vals);
            var fnam = vals[1];
            if (fnam !== '' && fnam[0] !== '_')
                funcLst.push(fnam);
            var someDflt = str.indexOf('=')>=0;
            if (str.indexOf(':')<0 && !someDflt) // Skip functions with no types or defaults
                return str;
            var res = 'function '+fnam+'(';
        
            var astr = vals[2].trim();
            if (astr === '')
                res += str + ') {';
            else {
                var sobj = jsi.SigParse(fnam+'('+vals[2]+')'+vals[3]);
                LogDebug('SOBJ',JSON.stringify(sobj));
                res += sobj.sargs+')'+sobj.retval + '{ $jsig("'+sobj.ssig+'", arguments); ';
            }

            return res;
        }
        var reg = /function\s*[a-zA-Z0-9_]*\s*\([^)]*\)(:[\|a-z]+|)\s*\{/g;
        return code.replace(reg, reMethod) + '\n'+ENDSTR;
................................................................................
                    else
                        console.log('Error: ' + xhr.status);
                }
            }
        };                
    },
    srcAdd: function(fn, asData) {
        LogDebug('adding',fn);
        var f=document.createElement('script');
        f.setAttribute("type","text/javascript");
        if (asData)
            f.innerHTML = fn;
        else {
            f.setAttribute("src", fn);
            srcCnt++;
................................................................................
        jsi.ajax({url:fn, success:jsi.srcSuccess, error:jsi.srcError});
    },
    srcDone: function(fn) {
        srcCnt--;
    },
    srcSuccess: function(str) {
        srcCnt--;
        LogDebug('Src Success: '+str);
        var estr = str.substr(str.length-ENDSTR.length);
        if (estr !== ENDSTR) {
            str = jsi.SigConvert(str);
            LogDebug('Src xlate: '+str);
        }
        jsi.srcAdd(str, true);
        //eval.call({}, str);
    },
    srcError: function(str) {
        srcCnt--;
        LogWarn('Src Error: '+str);
    },
    query: function(sel, top) {
        var rc;
        if (typeof sel === 'function') {
            document.addEventListener("DOMContentLoaded", function () {
             sel(); });
            return null;
................................................................................
        return rc;
    },
    
    query1: function(sel, top) {
        var rc = jsi.query(sel, top);
        if (rc && rc.length)
            return rc[0];
        LogWarn('LOOKUP FAILURE: '+sel+' '+top);
        return null;
    },
    onload: function(f) {
        onloadFunc = f;
    },
    DoOnload: function(f) {
        if (srcCnt>0) {
            LogDebug("waiting for src");
            setTimeout(jsi.DoOnload, 1000);
            return;
        }
        if (onloadFunc)
            onloadFunc();
    }

................................................................................
if (typeof win['$$'] === 'undefined')
    win['$$'] = jsi.query1;

if (typeof win['puts'] === 'undefined')
    win['puts'] = console.log.bind(console);
    

LogTest("Loaded jsig");

//eval.call({}, 'function foo() { puts("foo");}');

document.addEventListener('DOMContentLoaded', function() {
    jsi.DoOnload();
}, false);

}());

Deleted lib/web/jspp.js.

1
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

/* A JS preprocessor to convert "typed" functions out to web-browser compatible form, eg.
 * 
 *    function foo(s:string='', n:number=1):string {
 * 
 * becomes
 * 
 *    function foo(s, n) { s=Jsi.ArgCheck(...
 * 
 * Code to perform type checking/default values is provided by "web/jsig.js".
 * 
 * Limitation: Comments within function signatures are not supported.
 */

function Jspp(data, conf)
{
    var options = { // A JS preprocessor to convert "typed" functions out to web-browser compatible form
        checkRet    :false,     // Check return code by creating wrapper functions
        disable     :false,     // Preprocess to vanilla JS. WARNING: use of default values may break things.
        listFuncs   :false,     // Echo function list.
        noCheck     :false      // Disable argument type checking.
    };
    var self = {
        funcLst:[],         // List of functions
        funcIdx:0,          // Func idx.
        curFile:'',         // Current file being processed.
        tail:''             // Basename of file.
    };

    //parseOpts(self, options, conf);
    if (conf) {
        for (var i in options)
            self[i] = options[i];
        for (var i in conf)
            self[i] = conf[i];
    }

    self.typeNameStr = "number string boolean array function object regexp any userobj void null undefined";
    self.typeNameList = self.typeNameStr.split(' ');
    
    function typeValidate(typ) {
        var tlst = typ.split('|');
        var i = -1;
        for (i = 0; i<tlst.length; i++)
            if (self.typeNameList.indexOf(tlst[i]) < 0)
                throw "type unknown '"+tlst[i]+'" not one of: '+self.typeNameStr;
        return tlst;
    }
  
    function reMethod(str) {
        var reg = /^function\s*([a-zA-Z0-9_]*)\s*\(([^)]*)\)(:[\|a-z]+|)\s*\{$/;
        var vals = reg.exec(str);
        if (!vals)
            throw "invalid method: "+str;
        //puts(vals);
        var fnam = vals[1];
        if (fnam !== '' && fnam[0] !== '_')
            self.funcLst.push(fnam);
        if (str.indexOf(':')<0 && str.indexOf('=')<0) // Skip functions with no types or defaults
            return str;
        var res = 'function '+fnam+'(';
    
        var astr = vals[2].trim();
        var cres = '/* '+astr+' */ ';
        var acall = [];
        if (astr !== '') {
            var alst = astr.split(',');
            var minargs = alst.length, maxargs = minargs;
            var last = alst.length-1;
            for (var i = 0; i<=last; i++) {
                var aval = alst[i].trim();
                if (aval === '...') {
                    if (i != last)
                        throw "expected ... to be at end";
                    maxargs = -1;
                    continue;
                }
                var rega = /^([a-zA-Z0-9_]+)(:[|a-z]+|)(=.+|)$/;
                var avals = rega.exec(aval);
                if (!avals)
                    throw "invalid argument: "+aval;
                //puts(avals);
                if (i)
                    res += ', ';
                var afnam = avals[1];
                if (afnam === '' || avals.length<3)
                    afnam = aval;
                res += afnam;
                acall.push(afnam);
                var defval, atyp = '';
                if (avals.length>2)
                    atyp = avals[2].substr(1);
                if (atyp !== '')
                    typeValidate(atyp);
                cres += '  '+afnam+'=Jsi.ArgCheck('+(i+1)+',"'+fnam+'","'+afnam+'",'+afnam+',"'+atyp+'"';
                if (avals[3] && avals[3] !== '') { // Default value
                    if (avals[3] === '=void') {
                        defval = 'undefined';
                    } else {
                        defval = avals[3].substr(1);
                    }
                    cres += ','+ defval;
                    if (minargs===alst.length)
                        minargs = i;
                }
                else if (minargs!==alst.length)
                    throw "non-default value follows default: "+aval+' in: '+str;
                cres += ');';
            }
            cres += '  Jsi.ArgCount("'+fnam+'",'+minargs+','+maxargs+',arguments.length); ';
        }
        res += ') { ';
        var rettyp = vals[3].substr(1);
        if (fnam !== '' && rettyp !== '' && rettyp !== 'any' && self.checkRet) {
            typeValidate(rettyp);
            var wfn = '__Jsi_WrapRet_'+self.tail+'_'+fnam+'_'+ ++self.funcIdx;
            cres += '  var __ret = '+wfn+'('+acall.join(',')+');\n';
            cres += '  Jsi.RetCheck("'+fnam+'",'+' __ret,"'+rettyp+'");\n  return __ret;\n}\n';
            cres += 'function '+wfn+'('+acall.join(', ')+') {';
        }
        if (!self.disable)
            res += cres;
        return res;
    }

    function parse(data) {
        //debugger;
        var reg = /function\s*[a-zA-Z0-9_]*\s*\([^)]*\)(:[\|a-z]+|)\s*\{/g;
        var rc = data.replace(reg, reMethod);
        if (self.listFuncs) {
            rc = '';
            var n = 0;
            for (var i of self.funcLst.sort())
                rc += i + ':' + i + (++n === self.funcLst.length ? '' : ',') + '\n';
        }
        return rc;
    }
    return parse(data);
}


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































Changes to src/jsi.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
....
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
....
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
....
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
....
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
.....
17529
17530
17531
17532
17533
17534
17535
17536
17537
17538
17539
17540
17541
17542
17543
.....
21740
21741
21742
21743
21744
21745
21746
21747
21748
21749
21750
21751
21752
21753
21754
.....
23203
23204
23205
23206
23207
23208
23209
23210
23211
23212
23213
23214
23215
23216
23217
.....
27090
27091
27092
27093
27094
27095
27096
27097
27098

27099
27100
27101
27102
27103
27104
27105
27106
27107
27108
27109
27110
27111
27112
27113
27114
27115
27116
27117
27118
27119
27120
27121




27122
27123
27124
27125
27126
27127
27128
27129
.....
28385
28386
28387
28388
28389
28390
28391




28392
28393
28394
28395
28396
28397

28398
28399
28400
28401
28402
28403
28404
.....
34186
34187
34188
34189
34190
34191
34192
34193
34194
34195
34196
34197
34198
34199
34200
.....
35692
35693
35694
35695
35696
35697
35698

35699
35700
35701
35702
35703
35704
35705
.....
35788
35789
35790
35791
35792
35793
35794

35795
35796
35797
35798
35799
35800
35801
35802
35803
35804
35805
35806
.....
35812
35813
35814
35815
35816
35817
35818
35819
35820
35821
35822
35823
35824
35825
35826
.....
35827
35828
35829
35830
35831
35832
35833

35834
35835

35836
35837
35838
35839
35840
35841
35842
.....
37907
37908
37909
37910
37911
37912
37913
37914
37915
37916
37917
37918
37919
37920
37921
.....
38488
38489
38490
38491
38492
38493
38494
38495
38496
38497
38498
38499
38500
38501
38502
.....
69033
69034
69035
69036
69037
69038
69039
69040
69041
69042
69043
69044
69045
69046
69047
/* 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 34

#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

................................................................................
JSI_EXTERN int Jsi_Truncate(Jsi_Interp *interp, Jsi_Channel chan, uint len); /*STUB = 380*/
JSI_EXTERN Jsi_Wide Jsi_Rewind(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 381*/
JSI_EXTERN int Jsi_Flush(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 382*/
JSI_EXTERN int Jsi_Getc(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 383*/
JSI_EXTERN int Jsi_Printf(Jsi_Interp *interp, Jsi_Channel chan, const char *fmt, ...) /*STUB = 384*/ __attribute__((format (printf,3,4))); 
JSI_EXTERN int Jsi_Ungetc(Jsi_Interp *interp, Jsi_Channel chan, int ch); /*STUB = 385*/
JSI_EXTERN char* Jsi_Gets(Jsi_Interp *interp, Jsi_Channel chan, char *s, int size); /*STUB = 386*/
JSI_EXTERN int Jsi_Puts(Jsi_Interp *interp, Jsi_Channel chan, const char *str); /*STUB = 387*/

typedef int (Jsi_ScandirFilter)(const Jsi_Dirent *);
typedef int (Jsi_ScandirCompare)(const Jsi_Dirent **, const Jsi_Dirent**);
JSI_EXTERN int Jsi_Scandir(Jsi_Interp *interp, Jsi_Value *path, Jsi_Dirent ***namelist, Jsi_ScandirFilter *filter, Jsi_ScandirCompare *compare ); /*STUB = 388*/
JSI_EXTERN int Jsi_SetChannelOption(Jsi_Interp *interp, Jsi_Channel chan, const char *optionName, const char *newValue); /*STUB = 389*/
JSI_EXTERN char* Jsi_Realpath(Jsi_Interp *interp, Jsi_Value *path, char *newname); /*STUB = 390*/
JSI_EXTERN int Jsi_Readlink(Jsi_Interp *interp, Jsi_Value* path, char *ret, int len); /*STUB = 391*/
................................................................................
#ifndef __JSI_STUBS_H__
#define __JSI_STUBS_H__
#ifndef JSI_AMALGAMATION
#include "jsi.h"
#endif


#define JSI_STUBS_MD5 "84f582f050ca4afde696dea1f107497f"

#undef JSI_EXTENSION_INI
#define JSI_EXTENSION_INI Jsi_Stubs *jsiStubsPtr = NULL;

#ifdef JSI__MUSL
#define JSI_STUBS_BLDFLAGS 1
#else
................................................................................
    int(*_Jsi_Truncate)(Jsi_Interp *interp, Jsi_Channel chan, uint len);
    Jsi_Wide(*_Jsi_Rewind)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Flush)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Getc)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Printf)(Jsi_Interp *interp, Jsi_Channel chan, const char *fmt, ...);
    int(*_Jsi_Ungetc)(Jsi_Interp *interp, Jsi_Channel chan, int ch);
    char*(*_Jsi_Gets)(Jsi_Interp *interp, Jsi_Channel chan, char *s, int size);
    int(*_Jsi_Puts)(Jsi_Interp *interp, Jsi_Channel chan, const char *str);
    int(*_Jsi_Scandir)(Jsi_Interp *interp, Jsi_Value *path, Jsi_Dirent ***namelist, Jsi_ScandirFilter *filter, Jsi_ScandirCompare *compare );
    int(*_Jsi_SetChannelOption)(Jsi_Interp *interp, Jsi_Channel chan, const char *optionName, const char *newValue);
    char*(*_Jsi_Realpath)(Jsi_Interp *interp, Jsi_Value *path, char *newname);
    int(*_Jsi_Readlink)(Jsi_Interp *interp, Jsi_Value* path, char *ret, int len);
    Jsi_Channel(*_Jsi_GetStdChannel)(Jsi_Interp *interp, int id);
    bool(*_Jsi_FSNative)(Jsi_Interp *interp, Jsi_Value* path);
    int(*_Jsi_Link)(Jsi_Interp *interp, Jsi_Value* src, Jsi_Value *dest, int typ);
................................................................................
#define Jsi_Truncate(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Truncate(n0,n1,n2))
#define Jsi_Rewind(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Rewind(n0,n1))
#define Jsi_Flush(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Flush(n0,n1))
#define Jsi_Getc(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Getc(n0,n1))
#define Jsi_Printf(n0,n1,n2,...) JSISTUBCALL(jsiStubsPtr, _Jsi_Printf(n0,n1,n2,##__VA_ARGS__))
#define Jsi_Ungetc(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Ungetc(n0,n1,n2))
#define Jsi_Gets(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Gets(n0,n1,n2,n3))
#define Jsi_Puts(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Puts(n0,n1,n2))
#define Jsi_Scandir(n0,n1,n2,n3,n4) JSISTUBCALL(jsiStubsPtr, _Jsi_Scandir(n0,n1,n2,n3,n4))
#define Jsi_SetChannelOption(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_SetChannelOption(n0,n1,n2,n3))
#define Jsi_Realpath(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Realpath(n0,n1,n2))
#define Jsi_Readlink(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Readlink(n0,n1,n2,n3))
#define Jsi_GetStdChannel(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_GetStdChannel(n0,n1))
#define Jsi_FSNative(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_FSNative(n0,n1))
#define Jsi_Link(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Link(n0,n1,n2,n3))
................................................................................
            if (profile)
                Jsi_DSPrintf(&dStr, "PROFILE:  self=%6.6f  all=%6.6f  #calls=%-8d  self/call=%6.6f  all/call=%6.6f  %s %s%s\n",
                    (func->allTime-func->subTime), (double)(func->allTime), func->callCnt, 
                    (double)(func->allTime-func->subTime)/func->callCnt,  (double)(func->allTime)/func->callCnt, 
                    buf, interp->parent?" ::":"", (interp->parent&&interp->name?interp->name:""));
        }
        if (Jsi_DSLength(&dStr))
            Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&dStr));
        Jsi_DSFree(&dStr);
    }

    if (func->opcodes)
        jsi_FreeOpcodes(func->opcodes);
    if (func->hPtr)
        Jsi_HashEntryDelete(func->hPtr);
................................................................................
        double coverage = (int)(100.0*interp->coverHit/interp->coverAll);
        Jsi_DString dStr;
        Jsi_DSInit(&dStr);
        Jsi_DSPrintf(&dStr, "PROFILE: TOTAL: time=%.6f, func=%.6f, cmd=%.6f, #funcs=%d, #cmds=%d, cover=%2.1f%%, #values=%d, #objs=%d %s%s\n",
            endTime-interp->startTime, interp->funcSelfTime, interp->cmdSelfTime, interp->funcCallCnt, interp->cmdCallCnt,
            coverage, interp->dbPtr->valueAllocCnt,  interp->dbPtr->objAllocCnt,
            interp->parent?" ::":"", (interp->parent&&interp->name?interp->name:""));
        Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&dStr));
        Jsi_DSFree(&dStr);
    }
    if (isMainInt)
        Jsi_HashDelete(interp->lexkeyTbl);
    Jsi_HashDelete(interp->protoTbl);
    if (interp->subthread)
        jsiIntData.mainInterp->threadCnt--;
................................................................................
            }
            if (buf1[0] == 0 || (buf1[0] == '.' && buf1[1] == 0))
                goto done;
        }
        lastCnt = 1;
        Jsi_Strcpy(lastMsg, buf1);
        if (!islog)
            Jsi_Puts(interp, jsi_Stderr, buf1);
            //fputs(buf1, stderr);
        else {
            Jsi_DString jStr={}, kStr={};
            Jsi_DSPrintf(&kStr, "[%s, \"%s\", \"%s\", %d, %d ]",
                Jsi_JSONQuote(interp, buf1, -1, &jStr), mt, curFile, line, lofs);
            if (Jsi_FunctionInvokeJSON(interp->parent, interp->debugOpts.msgCallback, Jsi_DSValue(&kStr), NULL) != JSI_OK)
                code = 1;
................................................................................
    FILE *fp = (chan && chan->fp ? chan->fp : stdout);
    va_start(va,fmt);
    n = vfprintf(fp, fmt, va);
    va_end(va);
    return n;
}

int Jsi_Puts(Jsi_Interp *interp, Jsi_Channel chan, const char *str)
{

    if (chan->fsPtr==0 || !chan->fsPtr->putsProc) {
        FILE *fp = (chan && chan->fp ? chan->fp : stdout);
        fputs(str, fp);
    } else {
        if (interp && interp->debugOpts.putsCallback && interp->parent) {
            int code = 0;
            Jsi_DString jStr={}, kStr={};
            Jsi_DSPrintf(&kStr, "[%s, %d]",
                Jsi_JSONQuote(interp, str, -1, &jStr), (chan->fp == stderr?1:0));
            if (Jsi_FunctionInvokeJSON(interp->parent, interp->debugOpts.putsCallback, Jsi_DSValue(&kStr), NULL) != JSI_OK)
                code = 1;
            Jsi_DSFree(&jStr);
            Jsi_DSFree(&kStr);
            return code;
        } else if (interp && interp->stdoutStr) {
            Jsi_DString dStr = {};
            Jsi_DSAppend(&dStr, Jsi_ValueString(interp, interp->stdoutStr, NULL), NULL);
            Jsi_DSAppend(&dStr, str, NULL);
            Jsi_ValueFromDS(interp, &dStr, &interp->stdoutStr);
        } else

            return chan->fsPtr->putsProc(chan, str);
    }




    return 0;
}

static Jsi_RC FilesysConstructor(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr);
    

static Jsi_CmdSpec filesysCmds[] = {
................................................................................
    Jsi_Obj *obj = repVal->d.obj;
    p = source_str;
    for (j=0; j<(uint)bLen; j++, p++) {
        for (i=0; i<obj->arrCnt; i+=2) {
            if (!obj->arr[i]) continue;
            if (!obj->arr[i+1]) continue;
            const char *cp = Jsi_ValueToString(interp, obj->arr[i], &slen);




            int res = (nocase ? Jsi_Strncasecmp(cp, p, slen) : Jsi_Strncmp(cp, p, slen));
            if (!res) {
                replace_str = Jsi_ValueToString(interp, obj->arr[i+1], &replace_len);
                Jsi_DSAppend(&dStr, replace_str, NULL);
                p += slen;
                j += slen;

            }
        }
        if (i>=obj->arrCnt)
            Jsi_DSAppendLen(&dStr, p, 1);
    }

    Jsi_ValueFromDS(interp, &dStr, ret);
................................................................................
Jsi_RC jsi_InitJSON(Jsi_Interp *interp, int release) {
    if (release) return JSI_OK;
    Jsi_CommandCreateSpecs(interp, "JSON", jsonCmds, NULL, 0);
#ifdef TEST_JSON_INVOKE
    Jsi_Value *ret = Jsi_ValueNew1(interp);
    Jsi_CommandInvokeJSON(interp, "Info.cmds", "[\"*\", true]", ret);
    Jsi_DString dStr = {};
    Jsi_Puts(NULL, Jsi_ValueGetDString(interp, ret, &dStr, 1));
    Jsi_DSFree(&dStr);
    Jsi_DecrRefCount(interp, ret);
#endif
    return JSI_OK;
}
#endif
#ifndef JSI_LITE_ONLY
................................................................................
    }
    if (edata.trim) {
        char *cp = Jsi_DSValue(&dStr);
        int iLen = Jsi_DSLength(&dStr);
        while (iLen>0 && isspace(cp[iLen-1]))
            iLen--;
        cp[iLen] = 0;

    }
    if (edata.retAll) {
        Jsi_Obj *nobj = Jsi_ObjNew(interp);
        Jsi_ValueMakeObject(interp, ret, nobj);
        Jsi_Value *cval = Jsi_ValueNewNumber(interp, (Jsi_Number)exitCode);
        Jsi_ObjInsert(interp, nobj, "code", cval, 0);
        cval = Jsi_ValueNewNumber(interp, (Jsi_Number)(ec&0xff));
................................................................................
                || (!interp->logOpts.Info && jsi_PrefixMatch(argStr, "INFO: ")))
                goto done;
        }
 
        for (i = 0; i < argc; ++i) {
            Jsi_Value *v = Jsi_ValueArrayIndex(interp, args, i);
            if (!v) continue;

            if (cnt++)
                Jsi_DSAppendLen(&dStr, " ", 1);
            const char *cp = Jsi_ValueString(interp, v, 0);
            if (cp) {
                Jsi_DSAppend(&dStr, cp, NULL);
                continue;
            }
            Jsi_DSSetLength(&oStr, 0);
            Jsi_ValueGetDString(interp, v, &oStr, 1);
            Jsi_DSAppend(&dStr, Jsi_DSValue(&oStr), NULL);
        }
    }
................................................................................
    if (popts->func) {
        // Note: could have looked this up on the stackFrame.
        if (!interp->prevActiveFunc || !((fn=interp->prevActiveFunc->name)))
            fn = "";
        Jsi_DSPrintf(&dStr, ", %s%s", fn[0]?fn:"", fn[0]?"()":"");
    }
    Jsi_DSAppend(&dStr, "\n", NULL);
    Jsi_Puts(interp, chan, Jsi_DSValue(&dStr));
done:
    Jsi_DSFree(&dStr);
    Jsi_DSFree(&oStr);
    return JSI_OK;
}

static Jsi_RC SysPrintfCmd_(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret,
................................................................................
    Jsi_Func *funcPtr, Jsi_Channel chan)
{
    Jsi_DString dStr;
    Jsi_RC rc = Jsi_FormatString(interp, args, &dStr);
    if (rc != JSI_OK)
        return rc;
    const char *cp;

    Jsi_Puts(interp, chan, cp = Jsi_DSValue(&dStr));
    if (!Jsi_Strchr(cp, '\n'))

        Jsi_Flush(interp, chan);
    Jsi_DSFree(&dStr);
    return rc;
}

static Jsi_RC SysPrintfCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret,
    Jsi_Func *funcPtr)
................................................................................
        Jsi_GetBoolFromValue(interp, func, &bv);
        double now = jsi_GetTimestamp();
        if (bv)
            interp->timesStart = now;
        else {
            char buf[100];
            snprintf(buf, sizeof(buf), " (times = %.6f sec)\n", (now-interp->timesStart));
            Jsi_Puts(interp, jsi_Stderr, buf);
        }
        Jsi_ValueMakeNumber(interp, ret, 0);
        return JSI_OK;
    }
    Jsi_Wide diff, start, end;
    if (!Jsi_ValueIsFunction(interp, func))
        return Jsi_LogError("expected function");
................................................................................
        Jsi_DecrRefCount(interp, vargs[i]);
    Jsi_DecrRefCount(interp, vpargs);
    if (rc == JSI_OK && !Jsi_ValueIsUndef(interp, *ret) && isMain && funcPtr && funcPtr->callflags.bits.isdiscard) {
        Jsi_DSSetLength(&dStr, 0);
        cp = Jsi_ValueGetDString(interp, *ret, &dStr, 0);
        if (cp && (!(cp=Jsi_Strrchr(cp, '\n')) || cp[1]))
            Jsi_DSAppend(&dStr, "\n", NULL);
        Jsi_Puts(interp, jsi_Stdout, Jsi_DSValue(&dStr));
    }

done:
    Jsi_DSFree(&dStr);
    Jsi_DSFree(&nStr);
    return rc;
}
................................................................................
                (ret?'<':'>'), (fp?fp:""), (fp?".":""), fstatic->name, Jsi_DSValue(&aStr), Jsi_DSValue(&dStr));
        else {
            Jsi_DSPrintf(&pStr, "%*s#%d: %c %s%s%s(%s) in %s:%d%s\n", (interp->level-1)*2, "", interp->level,
                (ret?'<':'>'), (fp?fp:""), (fp?".":""), fstatic->name, Jsi_DSValue(&aStr),
            fname, ip->Line, Jsi_DSValue(&dStr));
        }
        if (Jsi_DSLength(&pStr))
            Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&pStr));
        Jsi_DSFree(&pStr);
        Jsi_DSFree(&dStr);
        Jsi_DSFree(&aStr);
    }
}

Jsi_RC jsi_FunctionSubCall(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,






|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|

>


|





|












|

>
>
>
>
|







 







>
>
>
>



|
|
|
>







 







|







 







>







 







>


|

|







 







|







 







>
|
<
>







 







|







 







|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
....
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
....
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
....
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
....
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
.....
17529
17530
17531
17532
17533
17534
17535
17536
17537
17538
17539
17540
17541
17542
17543
.....
21740
21741
21742
21743
21744
21745
21746
21747
21748
21749
21750
21751
21752
21753
21754
.....
23203
23204
23205
23206
23207
23208
23209
23210
23211
23212
23213
23214
23215
23216
23217
.....
27090
27091
27092
27093
27094
27095
27096
27097
27098
27099
27100
27101
27102
27103
27104
27105
27106
27107
27108
27109
27110
27111
27112
27113
27114
27115
27116
27117
27118
27119
27120
27121
27122
27123
27124
27125
27126
27127
27128
27129
27130
27131
27132
27133
27134
.....
28390
28391
28392
28393
28394
28395
28396
28397
28398
28399
28400
28401
28402
28403
28404
28405
28406
28407
28408
28409
28410
28411
28412
28413
28414
.....
34196
34197
34198
34199
34200
34201
34202
34203
34204
34205
34206
34207
34208
34209
34210
.....
35702
35703
35704
35705
35706
35707
35708
35709
35710
35711
35712
35713
35714
35715
35716
.....
35799
35800
35801
35802
35803
35804
35805
35806
35807
35808
35809
35810
35811
35812
35813
35814
35815
35816
35817
35818
.....
35824
35825
35826
35827
35828
35829
35830
35831
35832
35833
35834
35835
35836
35837
35838
.....
35839
35840
35841
35842
35843
35844
35845
35846
35847

35848
35849
35850
35851
35852
35853
35854
35855
.....
37920
37921
37922
37923
37924
37925
37926
37927
37928
37929
37930
37931
37932
37933
37934
.....
38501
38502
38503
38504
38505
38506
38507
38508
38509
38510
38511
38512
38513
38514
38515
.....
69046
69047
69048
69049
69050
69051
69052
69053
69054
69055
69056
69057
69058
69059
69060
/* 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 35

#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

................................................................................
JSI_EXTERN int Jsi_Truncate(Jsi_Interp *interp, Jsi_Channel chan, uint len); /*STUB = 380*/
JSI_EXTERN Jsi_Wide Jsi_Rewind(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 381*/
JSI_EXTERN int Jsi_Flush(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 382*/
JSI_EXTERN int Jsi_Getc(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 383*/
JSI_EXTERN int Jsi_Printf(Jsi_Interp *interp, Jsi_Channel chan, const char *fmt, ...) /*STUB = 384*/ __attribute__((format (printf,3,4))); 
JSI_EXTERN int Jsi_Ungetc(Jsi_Interp *interp, Jsi_Channel chan, int ch); /*STUB = 385*/
JSI_EXTERN char* Jsi_Gets(Jsi_Interp *interp, Jsi_Channel chan, char *s, int size); /*STUB = 386*/
JSI_EXTERN int Jsi_Puts(Jsi_Interp *interp, Jsi_Channel chan, const char *str, int size); /*STUB = 387*/

typedef int (Jsi_ScandirFilter)(const Jsi_Dirent *);
typedef int (Jsi_ScandirCompare)(const Jsi_Dirent **, const Jsi_Dirent**);
JSI_EXTERN int Jsi_Scandir(Jsi_Interp *interp, Jsi_Value *path, Jsi_Dirent ***namelist, Jsi_ScandirFilter *filter, Jsi_ScandirCompare *compare ); /*STUB = 388*/
JSI_EXTERN int Jsi_SetChannelOption(Jsi_Interp *interp, Jsi_Channel chan, const char *optionName, const char *newValue); /*STUB = 389*/
JSI_EXTERN char* Jsi_Realpath(Jsi_Interp *interp, Jsi_Value *path, char *newname); /*STUB = 390*/
JSI_EXTERN int Jsi_Readlink(Jsi_Interp *interp, Jsi_Value* path, char *ret, int len); /*STUB = 391*/
................................................................................
#ifndef __JSI_STUBS_H__
#define __JSI_STUBS_H__
#ifndef JSI_AMALGAMATION
#include "jsi.h"
#endif


#define JSI_STUBS_MD5 "54b3c19a995493d17414e173ea427a66"

#undef JSI_EXTENSION_INI
#define JSI_EXTENSION_INI Jsi_Stubs *jsiStubsPtr = NULL;

#ifdef JSI__MUSL
#define JSI_STUBS_BLDFLAGS 1
#else
................................................................................
    int(*_Jsi_Truncate)(Jsi_Interp *interp, Jsi_Channel chan, uint len);
    Jsi_Wide(*_Jsi_Rewind)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Flush)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Getc)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Printf)(Jsi_Interp *interp, Jsi_Channel chan, const char *fmt, ...);
    int(*_Jsi_Ungetc)(Jsi_Interp *interp, Jsi_Channel chan, int ch);
    char*(*_Jsi_Gets)(Jsi_Interp *interp, Jsi_Channel chan, char *s, int size);
    int(*_Jsi_Puts)(Jsi_Interp *interp, Jsi_Channel chan, const char *str, int size);
    int(*_Jsi_Scandir)(Jsi_Interp *interp, Jsi_Value *path, Jsi_Dirent ***namelist, Jsi_ScandirFilter *filter, Jsi_ScandirCompare *compare );
    int(*_Jsi_SetChannelOption)(Jsi_Interp *interp, Jsi_Channel chan, const char *optionName, const char *newValue);
    char*(*_Jsi_Realpath)(Jsi_Interp *interp, Jsi_Value *path, char *newname);
    int(*_Jsi_Readlink)(Jsi_Interp *interp, Jsi_Value* path, char *ret, int len);
    Jsi_Channel(*_Jsi_GetStdChannel)(Jsi_Interp *interp, int id);
    bool(*_Jsi_FSNative)(Jsi_Interp *interp, Jsi_Value* path);
    int(*_Jsi_Link)(Jsi_Interp *interp, Jsi_Value* src, Jsi_Value *dest, int typ);
................................................................................
#define Jsi_Truncate(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Truncate(n0,n1,n2))
#define Jsi_Rewind(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Rewind(n0,n1))
#define Jsi_Flush(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Flush(n0,n1))
#define Jsi_Getc(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Getc(n0,n1))
#define Jsi_Printf(n0,n1,n2,...) JSISTUBCALL(jsiStubsPtr, _Jsi_Printf(n0,n1,n2,##__VA_ARGS__))
#define Jsi_Ungetc(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Ungetc(n0,n1,n2))
#define Jsi_Gets(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Gets(n0,n1,n2,n3))
#define Jsi_Puts(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Puts(n0,n1,n2,n3))
#define Jsi_Scandir(n0,n1,n2,n3,n4) JSISTUBCALL(jsiStubsPtr, _Jsi_Scandir(n0,n1,n2,n3,n4))
#define Jsi_SetChannelOption(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_SetChannelOption(n0,n1,n2,n3))
#define Jsi_Realpath(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Realpath(n0,n1,n2))
#define Jsi_Readlink(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Readlink(n0,n1,n2,n3))
#define Jsi_GetStdChannel(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_GetStdChannel(n0,n1))
#define Jsi_FSNative(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_FSNative(n0,n1))
#define Jsi_Link(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Link(n0,n1,n2,n3))
................................................................................
            if (profile)
                Jsi_DSPrintf(&dStr, "PROFILE:  self=%6.6f  all=%6.6f  #calls=%-8d  self/call=%6.6f  all/call=%6.6f  %s %s%s\n",
                    (func->allTime-func->subTime), (double)(func->allTime), func->callCnt, 
                    (double)(func->allTime-func->subTime)/func->callCnt,  (double)(func->allTime)/func->callCnt, 
                    buf, interp->parent?" ::":"", (interp->parent&&interp->name?interp->name:""));
        }
        if (Jsi_DSLength(&dStr))
            Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&dStr), -1);
        Jsi_DSFree(&dStr);
    }

    if (func->opcodes)
        jsi_FreeOpcodes(func->opcodes);
    if (func->hPtr)
        Jsi_HashEntryDelete(func->hPtr);
................................................................................
        double coverage = (int)(100.0*interp->coverHit/interp->coverAll);
        Jsi_DString dStr;
        Jsi_DSInit(&dStr);
        Jsi_DSPrintf(&dStr, "PROFILE: TOTAL: time=%.6f, func=%.6f, cmd=%.6f, #funcs=%d, #cmds=%d, cover=%2.1f%%, #values=%d, #objs=%d %s%s\n",
            endTime-interp->startTime, interp->funcSelfTime, interp->cmdSelfTime, interp->funcCallCnt, interp->cmdCallCnt,
            coverage, interp->dbPtr->valueAllocCnt,  interp->dbPtr->objAllocCnt,
            interp->parent?" ::":"", (interp->parent&&interp->name?interp->name:""));
        Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&dStr), -1);
        Jsi_DSFree(&dStr);
    }
    if (isMainInt)
        Jsi_HashDelete(interp->lexkeyTbl);
    Jsi_HashDelete(interp->protoTbl);
    if (interp->subthread)
        jsiIntData.mainInterp->threadCnt--;
................................................................................
            }
            if (buf1[0] == 0 || (buf1[0] == '.' && buf1[1] == 0))
                goto done;
        }
        lastCnt = 1;
        Jsi_Strcpy(lastMsg, buf1);
        if (!islog)
            Jsi_Puts(interp, jsi_Stderr, buf1, -1);
            //fputs(buf1, stderr);
        else {
            Jsi_DString jStr={}, kStr={};
            Jsi_DSPrintf(&kStr, "[%s, \"%s\", \"%s\", %d, %d ]",
                Jsi_JSONQuote(interp, buf1, -1, &jStr), mt, curFile, line, lofs);
            if (Jsi_FunctionInvokeJSON(interp->parent, interp->debugOpts.msgCallback, Jsi_DSValue(&kStr), NULL) != JSI_OK)
                code = 1;
................................................................................
    FILE *fp = (chan && chan->fp ? chan->fp : stdout);
    va_start(va,fmt);
    n = vfprintf(fp, fmt, va);
    va_end(va);
    return n;
}

int Jsi_Puts(Jsi_Interp *interp, Jsi_Channel chan, const char *str, int size)
{
    int code = 0, len = Jsi_Strlen(str);
    if (chan->fsPtr==0 || !chan->fsPtr->putsProc) {
        FILE *fp = (chan && chan->fp ? chan->fp : stdout);
        code = fputs(str, fp);
    } else {
        if (interp && interp->debugOpts.putsCallback && interp->parent) {
            int code = 0;
            Jsi_DString jStr={}, kStr={};
            Jsi_DSPrintf(&kStr, "[%s, %d]",
                Jsi_JSONQuote(interp, str, size, &jStr), (chan->fp == stderr?1:0));
            if (Jsi_FunctionInvokeJSON(interp->parent, interp->debugOpts.putsCallback, Jsi_DSValue(&kStr), NULL) != JSI_OK)
                code = 1;
            Jsi_DSFree(&jStr);
            Jsi_DSFree(&kStr);
            return code;
        } else if (interp && interp->stdoutStr) {
            Jsi_DString dStr = {};
            Jsi_DSAppend(&dStr, Jsi_ValueString(interp, interp->stdoutStr, NULL), NULL);
            Jsi_DSAppend(&dStr, str, NULL);
            Jsi_ValueFromDS(interp, &dStr, &interp->stdoutStr);
        } else

            code = chan->fsPtr->putsProc(chan, str);
    }
    if (size>=0 && len < size) {
        Jsi_Puts(interp, chan, "\\0", -1);
        Jsi_Puts(interp, chan, str+len+1, size-len-1);
    }
    return code;
}

static Jsi_RC FilesysConstructor(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr);
    

static Jsi_CmdSpec filesysCmds[] = {
................................................................................
    Jsi_Obj *obj = repVal->d.obj;
    p = source_str;
    for (j=0; j<(uint)bLen; j++, p++) {
        for (i=0; i<obj->arrCnt; i+=2) {
            if (!obj->arr[i]) continue;
            if (!obj->arr[i+1]) continue;
            const char *cp = Jsi_ValueToString(interp, obj->arr[i], &slen);
            if (!cp || !slen) {
                Jsi_DSFree(&dStr);
                return Jsi_LogError("map src can not be empty");
            }
            int res = (nocase ? Jsi_Strncasecmp(cp, p, slen) : Jsi_Strncmp(cp, p, slen));
            if (!res) {
                replace_str = Jsi_ValueToString(interp, obj->arr[i+1], &replace_len);
                Jsi_DSAppendLen(&dStr, replace_str, replace_len);
                p += slen-1;
                j += slen-1;
                break;
            }
        }
        if (i>=obj->arrCnt)
            Jsi_DSAppendLen(&dStr, p, 1);
    }

    Jsi_ValueFromDS(interp, &dStr, ret);
................................................................................
Jsi_RC jsi_InitJSON(Jsi_Interp *interp, int release) {
    if (release) return JSI_OK;
    Jsi_CommandCreateSpecs(interp, "JSON", jsonCmds, NULL, 0);
#ifdef TEST_JSON_INVOKE
    Jsi_Value *ret = Jsi_ValueNew1(interp);
    Jsi_CommandInvokeJSON(interp, "Info.cmds", "[\"*\", true]", ret);
    Jsi_DString dStr = {};
    Jsi_Puts(NULL, Jsi_ValueGetDString(interp, ret, &dStr, 1), -1);
    Jsi_DSFree(&dStr);
    Jsi_DecrRefCount(interp, ret);
#endif
    return JSI_OK;
}
#endif
#ifndef JSI_LITE_ONLY
................................................................................
    }
    if (edata.trim) {
        char *cp = Jsi_DSValue(&dStr);
        int iLen = Jsi_DSLength(&dStr);
        while (iLen>0 && isspace(cp[iLen-1]))
            iLen--;
        cp[iLen] = 0;
        Jsi_DSSetLength(&dStr, iLen);
    }
    if (edata.retAll) {
        Jsi_Obj *nobj = Jsi_ObjNew(interp);
        Jsi_ValueMakeObject(interp, ret, nobj);
        Jsi_Value *cval = Jsi_ValueNewNumber(interp, (Jsi_Number)exitCode);
        Jsi_ObjInsert(interp, nobj, "code", cval, 0);
        cval = Jsi_ValueNewNumber(interp, (Jsi_Number)(ec&0xff));
................................................................................
                || (!interp->logOpts.Info && jsi_PrefixMatch(argStr, "INFO: ")))
                goto done;
        }
 
        for (i = 0; i < argc; ++i) {
            Jsi_Value *v = Jsi_ValueArrayIndex(interp, args, i);
            if (!v) continue;
            int len = 0;
            if (cnt++)
                Jsi_DSAppendLen(&dStr, " ", 1);
            const char *cp = Jsi_ValueString(interp, v, &len);
            if (cp) {
                Jsi_DSAppendLen(&dStr, cp, len);
                continue;
            }
            Jsi_DSSetLength(&oStr, 0);
            Jsi_ValueGetDString(interp, v, &oStr, 1);
            Jsi_DSAppend(&dStr, Jsi_DSValue(&oStr), NULL);
        }
    }
................................................................................
    if (popts->func) {
        // Note: could have looked this up on the stackFrame.
        if (!interp->prevActiveFunc || !((fn=interp->prevActiveFunc->name)))
            fn = "";
        Jsi_DSPrintf(&dStr, ", %s%s", fn[0]?fn:"", fn[0]?"()":"");
    }
    Jsi_DSAppend(&dStr, "\n", NULL);
    Jsi_Puts(interp, chan, Jsi_DSValue(&dStr), Jsi_DSLength(&dStr));
done:
    Jsi_DSFree(&dStr);
    Jsi_DSFree(&oStr);
    return JSI_OK;
}

static Jsi_RC SysPrintfCmd_(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret,
................................................................................
    Jsi_Func *funcPtr, Jsi_Channel chan)
{
    Jsi_DString dStr;
    Jsi_RC rc = Jsi_FormatString(interp, args, &dStr);
    if (rc != JSI_OK)
        return rc;
    const char *cp;
    int len = Jsi_DSLength(&dStr);
    Jsi_Puts(interp, chan, cp = Jsi_DSValue(&dStr), len);

    if (len>0 && cp[len-1]!='\n')
        Jsi_Flush(interp, chan);
    Jsi_DSFree(&dStr);
    return rc;
}

static Jsi_RC SysPrintfCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret,
    Jsi_Func *funcPtr)
................................................................................
        Jsi_GetBoolFromValue(interp, func, &bv);
        double now = jsi_GetTimestamp();
        if (bv)
            interp->timesStart = now;
        else {
            char buf[100];
            snprintf(buf, sizeof(buf), " (times = %.6f sec)\n", (now-interp->timesStart));
            Jsi_Puts(interp, jsi_Stderr, buf, -1);
        }
        Jsi_ValueMakeNumber(interp, ret, 0);
        return JSI_OK;
    }
    Jsi_Wide diff, start, end;
    if (!Jsi_ValueIsFunction(interp, func))
        return Jsi_LogError("expected function");
................................................................................
        Jsi_DecrRefCount(interp, vargs[i]);
    Jsi_DecrRefCount(interp, vpargs);
    if (rc == JSI_OK && !Jsi_ValueIsUndef(interp, *ret) && isMain && funcPtr && funcPtr->callflags.bits.isdiscard) {
        Jsi_DSSetLength(&dStr, 0);
        cp = Jsi_ValueGetDString(interp, *ret, &dStr, 0);
        if (cp && (!(cp=Jsi_Strrchr(cp, '\n')) || cp[1]))
            Jsi_DSAppend(&dStr, "\n", NULL);
        Jsi_Puts(interp, jsi_Stdout, Jsi_DSValue(&dStr), -1);
    }

done:
    Jsi_DSFree(&dStr);
    Jsi_DSFree(&nStr);
    return rc;
}
................................................................................
                (ret?'<':'>'), (fp?fp:""), (fp?".":""), fstatic->name, Jsi_DSValue(&aStr), Jsi_DSValue(&dStr));
        else {
            Jsi_DSPrintf(&pStr, "%*s#%d: %c %s%s%s(%s) in %s:%d%s\n", (interp->level-1)*2, "", interp->level,
                (ret?'<':'>'), (fp?fp:""), (fp?".":""), fstatic->name, Jsi_DSValue(&aStr),
            fname, ip->Line, Jsi_DSValue(&dStr));
        }
        if (Jsi_DSLength(&pStr))
            Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&pStr), -1);
        Jsi_DSFree(&pStr);
        Jsi_DSFree(&dStr);
        Jsi_DSFree(&aStr);
    }
}

Jsi_RC jsi_FunctionSubCall(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,

Changes to src/jsi.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
....
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
/* 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 34

#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

................................................................................
JSI_EXTERN int Jsi_Truncate(Jsi_Interp *interp, Jsi_Channel chan, uint len); /*STUB = 380*/
JSI_EXTERN Jsi_Wide Jsi_Rewind(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 381*/
JSI_EXTERN int Jsi_Flush(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 382*/
JSI_EXTERN int Jsi_Getc(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 383*/
JSI_EXTERN int Jsi_Printf(Jsi_Interp *interp, Jsi_Channel chan, const char *fmt, ...) /*STUB = 384*/ __attribute__((format (printf,3,4))); 
JSI_EXTERN int Jsi_Ungetc(Jsi_Interp *interp, Jsi_Channel chan, int ch); /*STUB = 385*/
JSI_EXTERN char* Jsi_Gets(Jsi_Interp *interp, Jsi_Channel chan, char *s, int size); /*STUB = 386*/
JSI_EXTERN int Jsi_Puts(Jsi_Interp *interp, Jsi_Channel chan, const char *str); /*STUB = 387*/

typedef int (Jsi_ScandirFilter)(const Jsi_Dirent *);
typedef int (Jsi_ScandirCompare)(const Jsi_Dirent **, const Jsi_Dirent**);
JSI_EXTERN int Jsi_Scandir(Jsi_Interp *interp, Jsi_Value *path, Jsi_Dirent ***namelist, Jsi_ScandirFilter *filter, Jsi_ScandirCompare *compare ); /*STUB = 388*/
JSI_EXTERN int Jsi_SetChannelOption(Jsi_Interp *interp, Jsi_Channel chan, const char *optionName, const char *newValue); /*STUB = 389*/
JSI_EXTERN char* Jsi_Realpath(Jsi_Interp *interp, Jsi_Value *path, char *newname); /*STUB = 390*/
JSI_EXTERN int Jsi_Readlink(Jsi_Interp *interp, Jsi_Value* path, char *ret, int len); /*STUB = 391*/






|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
....
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
/* 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 35

#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

................................................................................
JSI_EXTERN int Jsi_Truncate(Jsi_Interp *interp, Jsi_Channel chan, uint len); /*STUB = 380*/
JSI_EXTERN Jsi_Wide Jsi_Rewind(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 381*/
JSI_EXTERN int Jsi_Flush(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 382*/
JSI_EXTERN int Jsi_Getc(Jsi_Interp *interp, Jsi_Channel chan); /*STUB = 383*/
JSI_EXTERN int Jsi_Printf(Jsi_Interp *interp, Jsi_Channel chan, const char *fmt, ...) /*STUB = 384*/ __attribute__((format (printf,3,4))); 
JSI_EXTERN int Jsi_Ungetc(Jsi_Interp *interp, Jsi_Channel chan, int ch); /*STUB = 385*/
JSI_EXTERN char* Jsi_Gets(Jsi_Interp *interp, Jsi_Channel chan, char *s, int size); /*STUB = 386*/
JSI_EXTERN int Jsi_Puts(Jsi_Interp *interp, Jsi_Channel chan, const char *str, int size); /*STUB = 387*/

typedef int (Jsi_ScandirFilter)(const Jsi_Dirent *);
typedef int (Jsi_ScandirCompare)(const Jsi_Dirent **, const Jsi_Dirent**);
JSI_EXTERN int Jsi_Scandir(Jsi_Interp *interp, Jsi_Value *path, Jsi_Dirent ***namelist, Jsi_ScandirFilter *filter, Jsi_ScandirCompare *compare ); /*STUB = 388*/
JSI_EXTERN int Jsi_SetChannelOption(Jsi_Interp *interp, Jsi_Channel chan, const char *optionName, const char *newValue); /*STUB = 389*/
JSI_EXTERN char* Jsi_Realpath(Jsi_Interp *interp, Jsi_Value *path, char *newname); /*STUB = 390*/
JSI_EXTERN int Jsi_Readlink(Jsi_Interp *interp, Jsi_Value* path, char *ret, int len); /*STUB = 391*/

Changes to src/jsiCmds.c.

1493
1494
1495
1496
1497
1498
1499

1500
1501
1502
1503
1504
1505
1506
....
1589
1590
1591
1592
1593
1594
1595

1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
....
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
....
1628
1629
1630
1631
1632
1633
1634

1635
1636

1637
1638
1639
1640
1641
1642
1643
....
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
....
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
    }
    if (edata.trim) {
        char *cp = Jsi_DSValue(&dStr);
        int iLen = Jsi_DSLength(&dStr);
        while (iLen>0 && isspace(cp[iLen-1]))
            iLen--;
        cp[iLen] = 0;

    }
    if (edata.retAll) {
        Jsi_Obj *nobj = Jsi_ObjNew(interp);
        Jsi_ValueMakeObject(interp, ret, nobj);
        Jsi_Value *cval = Jsi_ValueNewNumber(interp, (Jsi_Number)exitCode);
        Jsi_ObjInsert(interp, nobj, "code", cval, 0);
        cval = Jsi_ValueNewNumber(interp, (Jsi_Number)(ec&0xff));
................................................................................
                || (!interp->logOpts.Info && jsi_PrefixMatch(argStr, "INFO: ")))
                goto done;
        }
 
        for (i = 0; i < argc; ++i) {
            Jsi_Value *v = Jsi_ValueArrayIndex(interp, args, i);
            if (!v) continue;

            if (cnt++)
                Jsi_DSAppendLen(&dStr, " ", 1);
            const char *cp = Jsi_ValueString(interp, v, 0);
            if (cp) {
                Jsi_DSAppend(&dStr, cp, NULL);
                continue;
            }
            Jsi_DSSetLength(&oStr, 0);
            Jsi_ValueGetDString(interp, v, &oStr, 1);
            Jsi_DSAppend(&dStr, Jsi_DSValue(&oStr), NULL);
        }
    }
................................................................................
    if (popts->func) {
        // Note: could have looked this up on the stackFrame.
        if (!interp->prevActiveFunc || !((fn=interp->prevActiveFunc->name)))
            fn = "";
        Jsi_DSPrintf(&dStr, ", %s%s", fn[0]?fn:"", fn[0]?"()":"");
    }
    Jsi_DSAppend(&dStr, "\n", NULL);
    Jsi_Puts(interp, chan, Jsi_DSValue(&dStr));
done:
    Jsi_DSFree(&dStr);
    Jsi_DSFree(&oStr);
    return JSI_OK;
}

static Jsi_RC SysPrintfCmd_(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret,
................................................................................
    Jsi_Func *funcPtr, Jsi_Channel chan)
{
    Jsi_DString dStr;
    Jsi_RC rc = Jsi_FormatString(interp, args, &dStr);
    if (rc != JSI_OK)
        return rc;
    const char *cp;

    Jsi_Puts(interp, chan, cp = Jsi_DSValue(&dStr));
    if (!Jsi_Strchr(cp, '\n'))

        Jsi_Flush(interp, chan);
    Jsi_DSFree(&dStr);
    return rc;
}

static Jsi_RC SysPrintfCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret,
    Jsi_Func *funcPtr)
................................................................................
        Jsi_GetBoolFromValue(interp, func, &bv);
        double now = jsi_GetTimestamp();
        if (bv)
            interp->timesStart = now;
        else {
            char buf[100];
            snprintf(buf, sizeof(buf), " (times = %.6f sec)\n", (now-interp->timesStart));
            Jsi_Puts(interp, jsi_Stderr, buf);
        }
        Jsi_ValueMakeNumber(interp, ret, 0);
        return JSI_OK;
    }
    Jsi_Wide diff, start, end;
    if (!Jsi_ValueIsFunction(interp, func))
        return Jsi_LogError("expected function");
................................................................................
        Jsi_DecrRefCount(interp, vargs[i]);
    Jsi_DecrRefCount(interp, vpargs);
    if (rc == JSI_OK && !Jsi_ValueIsUndef(interp, *ret) && isMain && funcPtr && funcPtr->callflags.bits.isdiscard) {
        Jsi_DSSetLength(&dStr, 0);
        cp = Jsi_ValueGetDString(interp, *ret, &dStr, 0);
        if (cp && (!(cp=Jsi_Strrchr(cp, '\n')) || cp[1]))
            Jsi_DSAppend(&dStr, "\n", NULL);
        Jsi_Puts(interp, jsi_Stdout, Jsi_DSValue(&dStr));
    }

done:
    Jsi_DSFree(&dStr);
    Jsi_DSFree(&nStr);
    return rc;
}







>







 







>


|

|







 







|







 







>
|
<
>







 







|







 







|







1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
....
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
....
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
....
1630
1631
1632
1633
1634
1635
1636
1637
1638

1639
1640
1641
1642
1643
1644
1645
1646
....
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
....
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
    }
    if (edata.trim) {
        char *cp = Jsi_DSValue(&dStr);
        int iLen = Jsi_DSLength(&dStr);
        while (iLen>0 && isspace(cp[iLen-1]))
            iLen--;
        cp[iLen] = 0;
        Jsi_DSSetLength(&dStr, iLen);
    }
    if (edata.retAll) {
        Jsi_Obj *nobj = Jsi_ObjNew(interp);
        Jsi_ValueMakeObject(interp, ret, nobj);
        Jsi_Value *cval = Jsi_ValueNewNumber(interp, (Jsi_Number)exitCode);
        Jsi_ObjInsert(interp, nobj, "code", cval, 0);
        cval = Jsi_ValueNewNumber(interp, (Jsi_Number)(ec&0xff));
................................................................................
                || (!interp->logOpts.Info && jsi_PrefixMatch(argStr, "INFO: ")))
                goto done;
        }
 
        for (i = 0; i < argc; ++i) {
            Jsi_Value *v = Jsi_ValueArrayIndex(interp, args, i);
            if (!v) continue;
            int len = 0;
            if (cnt++)
                Jsi_DSAppendLen(&dStr, " ", 1);
            const char *cp = Jsi_ValueString(interp, v, &len);
            if (cp) {
                Jsi_DSAppendLen(&dStr, cp, len);
                continue;
            }
            Jsi_DSSetLength(&oStr, 0);
            Jsi_ValueGetDString(interp, v, &oStr, 1);
            Jsi_DSAppend(&dStr, Jsi_DSValue(&oStr), NULL);
        }
    }
................................................................................
    if (popts->func) {
        // Note: could have looked this up on the stackFrame.
        if (!interp->prevActiveFunc || !((fn=interp->prevActiveFunc->name)))
            fn = "";
        Jsi_DSPrintf(&dStr, ", %s%s", fn[0]?fn:"", fn[0]?"()":"");
    }
    Jsi_DSAppend(&dStr, "\n", NULL);
    Jsi_Puts(interp, chan, Jsi_DSValue(&dStr), Jsi_DSLength(&dStr));
done:
    Jsi_DSFree(&dStr);
    Jsi_DSFree(&oStr);
    return JSI_OK;
}

static Jsi_RC SysPrintfCmd_(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret,
................................................................................
    Jsi_Func *funcPtr, Jsi_Channel chan)
{
    Jsi_DString dStr;
    Jsi_RC rc = Jsi_FormatString(interp, args, &dStr);
    if (rc != JSI_OK)
        return rc;
    const char *cp;
    int len = Jsi_DSLength(&dStr);
    Jsi_Puts(interp, chan, cp = Jsi_DSValue(&dStr), len);

    if (len>0 && cp[len-1]!='\n')
        Jsi_Flush(interp, chan);
    Jsi_DSFree(&dStr);
    return rc;
}

static Jsi_RC SysPrintfCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret,
    Jsi_Func *funcPtr)
................................................................................
        Jsi_GetBoolFromValue(interp, func, &bv);
        double now = jsi_GetTimestamp();
        if (bv)
            interp->timesStart = now;
        else {
            char buf[100];
            snprintf(buf, sizeof(buf), " (times = %.6f sec)\n", (now-interp->timesStart));
            Jsi_Puts(interp, jsi_Stderr, buf, -1);
        }
        Jsi_ValueMakeNumber(interp, ret, 0);
        return JSI_OK;
    }
    Jsi_Wide diff, start, end;
    if (!Jsi_ValueIsFunction(interp, func))
        return Jsi_LogError("expected function");
................................................................................
        Jsi_DecrRefCount(interp, vargs[i]);
    Jsi_DecrRefCount(interp, vpargs);
    if (rc == JSI_OK && !Jsi_ValueIsUndef(interp, *ret) && isMain && funcPtr && funcPtr->callflags.bits.isdiscard) {
        Jsi_DSSetLength(&dStr, 0);
        cp = Jsi_ValueGetDString(interp, *ret, &dStr, 0);
        if (cp && (!(cp=Jsi_Strrchr(cp, '\n')) || cp[1]))
            Jsi_DSAppend(&dStr, "\n", NULL);
        Jsi_Puts(interp, jsi_Stdout, Jsi_DSValue(&dStr), -1);
    }

done:
    Jsi_DSFree(&dStr);
    Jsi_DSFree(&nStr);
    return rc;
}

Changes to src/jsiEval.c.

687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
                (ret?'<':'>'), (fp?fp:""), (fp?".":""), fstatic->name, Jsi_DSValue(&aStr), Jsi_DSValue(&dStr));
        else {
            Jsi_DSPrintf(&pStr, "%*s#%d: %c %s%s%s(%s) in %s:%d%s\n", (interp->level-1)*2, "", interp->level,
                (ret?'<':'>'), (fp?fp:""), (fp?".":""), fstatic->name, Jsi_DSValue(&aStr),
            fname, ip->Line, Jsi_DSValue(&dStr));
        }
        if (Jsi_DSLength(&pStr))
            Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&pStr));
        Jsi_DSFree(&pStr);
        Jsi_DSFree(&dStr);
        Jsi_DSFree(&aStr);
    }
}

Jsi_RC jsi_FunctionSubCall(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,







|







687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
                (ret?'<':'>'), (fp?fp:""), (fp?".":""), fstatic->name, Jsi_DSValue(&aStr), Jsi_DSValue(&dStr));
        else {
            Jsi_DSPrintf(&pStr, "%*s#%d: %c %s%s%s(%s) in %s:%d%s\n", (interp->level-1)*2, "", interp->level,
                (ret?'<':'>'), (fp?fp:""), (fp?".":""), fstatic->name, Jsi_DSValue(&aStr),
            fname, ip->Line, Jsi_DSValue(&dStr));
        }
        if (Jsi_DSLength(&pStr))
            Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&pStr), -1);
        Jsi_DSFree(&pStr);
        Jsi_DSFree(&dStr);
        Jsi_DSFree(&aStr);
    }
}

Jsi_RC jsi_FunctionSubCall(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,

Changes to src/jsiFilesys.c.

999
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030




1031
1032
1033
1034
1035
1036
1037
1038
    FILE *fp = (chan && chan->fp ? chan->fp : stdout);
    va_start(va,fmt);
    n = vfprintf(fp, fmt, va);
    va_end(va);
    return n;
}

int Jsi_Puts(Jsi_Interp *interp, Jsi_Channel chan, const char *str)
{

    if (chan->fsPtr==0 || !chan->fsPtr->putsProc) {
        FILE *fp = (chan && chan->fp ? chan->fp : stdout);
        fputs(str, fp);
    } else {
        if (interp && interp->debugOpts.putsCallback && interp->parent) {
            int code = 0;
            Jsi_DString jStr={}, kStr={};
            Jsi_DSPrintf(&kStr, "[%s, %d]",
                Jsi_JSONQuote(interp, str, -1, &jStr), (chan->fp == stderr?1:0));
            if (Jsi_FunctionInvokeJSON(interp->parent, interp->debugOpts.putsCallback, Jsi_DSValue(&kStr), NULL) != JSI_OK)
                code = 1;
            Jsi_DSFree(&jStr);
            Jsi_DSFree(&kStr);
            return code;
        } else if (interp && interp->stdoutStr) {
            Jsi_DString dStr = {};
            Jsi_DSAppend(&dStr, Jsi_ValueString(interp, interp->stdoutStr, NULL), NULL);
            Jsi_DSAppend(&dStr, str, NULL);
            Jsi_ValueFromDS(interp, &dStr, &interp->stdoutStr);
        } else

            return chan->fsPtr->putsProc(chan, str);
    }




    return 0;
}

static Jsi_RC FilesysConstructor(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr);
    

static Jsi_CmdSpec filesysCmds[] = {







|

>


|





|












|

>
>
>
>
|







999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
    FILE *fp = (chan && chan->fp ? chan->fp : stdout);
    va_start(va,fmt);
    n = vfprintf(fp, fmt, va);
    va_end(va);
    return n;
}

int Jsi_Puts(Jsi_Interp *interp, Jsi_Channel chan, const char *str, int size)
{
    int code = 0, len = Jsi_Strlen(str);
    if (chan->fsPtr==0 || !chan->fsPtr->putsProc) {
        FILE *fp = (chan && chan->fp ? chan->fp : stdout);
        code = fputs(str, fp);
    } else {
        if (interp && interp->debugOpts.putsCallback && interp->parent) {
            int code = 0;
            Jsi_DString jStr={}, kStr={};
            Jsi_DSPrintf(&kStr, "[%s, %d]",
                Jsi_JSONQuote(interp, str, size, &jStr), (chan->fp == stderr?1:0));
            if (Jsi_FunctionInvokeJSON(interp->parent, interp->debugOpts.putsCallback, Jsi_DSValue(&kStr), NULL) != JSI_OK)
                code = 1;
            Jsi_DSFree(&jStr);
            Jsi_DSFree(&kStr);
            return code;
        } else if (interp && interp->stdoutStr) {
            Jsi_DString dStr = {};
            Jsi_DSAppend(&dStr, Jsi_ValueString(interp, interp->stdoutStr, NULL), NULL);
            Jsi_DSAppend(&dStr, str, NULL);
            Jsi_ValueFromDS(interp, &dStr, &interp->stdoutStr);
        } else

            code = chan->fsPtr->putsProc(chan, str);
    }
    if (size>=0 && len < size) {
        Jsi_Puts(interp, chan, "\\0", -1);
        Jsi_Puts(interp, chan, str+len+1, size-len-1);
    }
    return code;
}

static Jsi_RC FilesysConstructor(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr);
    

static Jsi_CmdSpec filesysCmds[] = {

Changes to src/jsiFunc.c.

1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
            if (profile)
                Jsi_DSPrintf(&dStr, "PROFILE:  self=%6.6f  all=%6.6f  #calls=%-8d  self/call=%6.6f  all/call=%6.6f  %s %s%s\n",
                    (func->allTime-func->subTime), (double)(func->allTime), func->callCnt, 
                    (double)(func->allTime-func->subTime)/func->callCnt,  (double)(func->allTime)/func->callCnt, 
                    buf, interp->parent?" ::":"", (interp->parent&&interp->name?interp->name:""));
        }
        if (Jsi_DSLength(&dStr))
            Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&dStr));
        Jsi_DSFree(&dStr);
    }

    if (func->opcodes)
        jsi_FreeOpcodes(func->opcodes);
    if (func->hPtr)
        Jsi_HashEntryDelete(func->hPtr);







|







1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
            if (profile)
                Jsi_DSPrintf(&dStr, "PROFILE:  self=%6.6f  all=%6.6f  #calls=%-8d  self/call=%6.6f  all/call=%6.6f  %s %s%s\n",
                    (func->allTime-func->subTime), (double)(func->allTime), func->callCnt, 
                    (double)(func->allTime-func->subTime)/func->callCnt,  (double)(func->allTime)/func->callCnt, 
                    buf, interp->parent?" ::":"", (interp->parent&&interp->name?interp->name:""));
        }
        if (Jsi_DSLength(&dStr))
            Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&dStr), -1);
        Jsi_DSFree(&dStr);
    }

    if (func->opcodes)
        jsi_FreeOpcodes(func->opcodes);
    if (func->hPtr)
        Jsi_HashEntryDelete(func->hPtr);

Changes to src/jsiInterp.c.

1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
        double coverage = (int)(100.0*interp->coverHit/interp->coverAll);
        Jsi_DString dStr;
        Jsi_DSInit(&dStr);
        Jsi_DSPrintf(&dStr, "PROFILE: TOTAL: time=%.6f, func=%.6f, cmd=%.6f, #funcs=%d, #cmds=%d, cover=%2.1f%%, #values=%d, #objs=%d %s%s\n",
            endTime-interp->startTime, interp->funcSelfTime, interp->cmdSelfTime, interp->funcCallCnt, interp->cmdCallCnt,
            coverage, interp->dbPtr->valueAllocCnt,  interp->dbPtr->objAllocCnt,
            interp->parent?" ::":"", (interp->parent&&interp->name?interp->name:""));
        Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&dStr));
        Jsi_DSFree(&dStr);
    }
    if (isMainInt)
        Jsi_HashDelete(interp->lexkeyTbl);
    Jsi_HashDelete(interp->protoTbl);
    if (interp->subthread)
        jsiIntData.mainInterp->threadCnt--;







|







1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
        double coverage = (int)(100.0*interp->coverHit/interp->coverAll);
        Jsi_DString dStr;
        Jsi_DSInit(&dStr);
        Jsi_DSPrintf(&dStr, "PROFILE: TOTAL: time=%.6f, func=%.6f, cmd=%.6f, #funcs=%d, #cmds=%d, cover=%2.1f%%, #values=%d, #objs=%d %s%s\n",
            endTime-interp->startTime, interp->funcSelfTime, interp->cmdSelfTime, interp->funcCallCnt, interp->cmdCallCnt,
            coverage, interp->dbPtr->valueAllocCnt,  interp->dbPtr->objAllocCnt,
            interp->parent?" ::":"", (interp->parent&&interp->name?interp->name:""));
        Jsi_Puts(interp, jsi_Stderr, Jsi_DSValue(&dStr), -1);
        Jsi_DSFree(&dStr);
    }
    if (isMainInt)
        Jsi_HashDelete(interp->lexkeyTbl);
    Jsi_HashDelete(interp->protoTbl);
    if (interp->subthread)
        jsiIntData.mainInterp->threadCnt--;

Changes to src/jsiJSON.c.

469
470
471
472
473
474
475
476
477
478
479
480
481
482
Jsi_RC jsi_InitJSON(Jsi_Interp *interp, int release) {
    if (release) return JSI_OK;
    Jsi_CommandCreateSpecs(interp, "JSON", jsonCmds, NULL, 0);
#ifdef TEST_JSON_INVOKE
    Jsi_Value *ret = Jsi_ValueNew1(interp);
    Jsi_CommandInvokeJSON(interp, "Info.cmds", "[\"*\", true]", ret);
    Jsi_DString dStr = {};
    Jsi_Puts(NULL, Jsi_ValueGetDString(interp, ret, &dStr, 1));
    Jsi_DSFree(&dStr);
    Jsi_DecrRefCount(interp, ret);
#endif
    return JSI_OK;
}
#endif







|






469
470
471
472
473
474
475
476
477
478
479
480
481
482
Jsi_RC jsi_InitJSON(Jsi_Interp *interp, int release) {
    if (release) return JSI_OK;
    Jsi_CommandCreateSpecs(interp, "JSON", jsonCmds, NULL, 0);
#ifdef TEST_JSON_INVOKE
    Jsi_Value *ret = Jsi_ValueNew1(interp);
    Jsi_CommandInvokeJSON(interp, "Info.cmds", "[\"*\", true]", ret);
    Jsi_DString dStr = {};
    Jsi_Puts(NULL, Jsi_ValueGetDString(interp, ret, &dStr, 1), -1);
    Jsi_DSFree(&dStr);
    Jsi_DecrRefCount(interp, ret);
#endif
    return JSI_OK;
}
#endif

Changes to src/jsiString.c.

597
598
599
600
601
602
603




604
605
606
607
608
609

610
611
612
613
614
615
616
    Jsi_Obj *obj = repVal->d.obj;
    p = source_str;
    for (j=0; j<(uint)bLen; j++, p++) {
        for (i=0; i<obj->arrCnt; i+=2) {
            if (!obj->arr[i]) continue;
            if (!obj->arr[i+1]) continue;
            const char *cp = Jsi_ValueToString(interp, obj->arr[i], &slen);




            int res = (nocase ? Jsi_Strncasecmp(cp, p, slen) : Jsi_Strncmp(cp, p, slen));
            if (!res) {
                replace_str = Jsi_ValueToString(interp, obj->arr[i+1], &replace_len);
                Jsi_DSAppend(&dStr, replace_str, NULL);
                p += slen;
                j += slen;

            }
        }
        if (i>=obj->arrCnt)
            Jsi_DSAppendLen(&dStr, p, 1);
    }

    Jsi_ValueFromDS(interp, &dStr, ret);







>
>
>
>



|
|
|
>







597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
    Jsi_Obj *obj = repVal->d.obj;
    p = source_str;
    for (j=0; j<(uint)bLen; j++, p++) {
        for (i=0; i<obj->arrCnt; i+=2) {
            if (!obj->arr[i]) continue;
            if (!obj->arr[i+1]) continue;
            const char *cp = Jsi_ValueToString(interp, obj->arr[i], &slen);
            if (!cp || !slen) {
                Jsi_DSFree(&dStr);
                return Jsi_LogError("map src can not be empty");
            }
            int res = (nocase ? Jsi_Strncasecmp(cp, p, slen) : Jsi_Strncmp(cp, p, slen));
            if (!res) {
                replace_str = Jsi_ValueToString(interp, obj->arr[i+1], &replace_len);
                Jsi_DSAppendLen(&dStr, replace_str, replace_len);
                p += slen-1;
                j += slen-1;
                break;
            }
        }
        if (i>=obj->arrCnt)
            Jsi_DSAppendLen(&dStr, p, 1);
    }

    Jsi_ValueFromDS(interp, &dStr, ret);

Changes to src/jsiStubs.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
....
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
#ifndef __JSI_STUBS_H__
#define __JSI_STUBS_H__
#ifndef JSI_AMALGAMATION
#include "jsi.h"
#endif


#define JSI_STUBS_MD5 "84f582f050ca4afde696dea1f107497f"

#undef JSI_EXTENSION_INI
#define JSI_EXTENSION_INI Jsi_Stubs *jsiStubsPtr = NULL;

#ifdef JSI__MUSL
#define JSI_STUBS_BLDFLAGS 1
#else
................................................................................
    int(*_Jsi_Truncate)(Jsi_Interp *interp, Jsi_Channel chan, uint len);
    Jsi_Wide(*_Jsi_Rewind)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Flush)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Getc)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Printf)(Jsi_Interp *interp, Jsi_Channel chan, const char *fmt, ...);
    int(*_Jsi_Ungetc)(Jsi_Interp *interp, Jsi_Channel chan, int ch);
    char*(*_Jsi_Gets)(Jsi_Interp *interp, Jsi_Channel chan, char *s, int size);
    int(*_Jsi_Puts)(Jsi_Interp *interp, Jsi_Channel chan, const char *str);
    int(*_Jsi_Scandir)(Jsi_Interp *interp, Jsi_Value *path, Jsi_Dirent ***namelist, Jsi_ScandirFilter *filter, Jsi_ScandirCompare *compare );
    int(*_Jsi_SetChannelOption)(Jsi_Interp *interp, Jsi_Channel chan, const char *optionName, const char *newValue);
    char*(*_Jsi_Realpath)(Jsi_Interp *interp, Jsi_Value *path, char *newname);
    int(*_Jsi_Readlink)(Jsi_Interp *interp, Jsi_Value* path, char *ret, int len);
    Jsi_Channel(*_Jsi_GetStdChannel)(Jsi_Interp *interp, int id);
    bool(*_Jsi_FSNative)(Jsi_Interp *interp, Jsi_Value* path);
    int(*_Jsi_Link)(Jsi_Interp *interp, Jsi_Value* src, Jsi_Value *dest, int typ);
................................................................................
#define Jsi_Truncate(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Truncate(n0,n1,n2))
#define Jsi_Rewind(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Rewind(n0,n1))
#define Jsi_Flush(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Flush(n0,n1))
#define Jsi_Getc(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Getc(n0,n1))
#define Jsi_Printf(n0,n1,n2,...) JSISTUBCALL(jsiStubsPtr, _Jsi_Printf(n0,n1,n2,##__VA_ARGS__))
#define Jsi_Ungetc(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Ungetc(n0,n1,n2))
#define Jsi_Gets(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Gets(n0,n1,n2,n3))
#define Jsi_Puts(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Puts(n0,n1,n2))
#define Jsi_Scandir(n0,n1,n2,n3,n4) JSISTUBCALL(jsiStubsPtr, _Jsi_Scandir(n0,n1,n2,n3,n4))
#define Jsi_SetChannelOption(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_SetChannelOption(n0,n1,n2,n3))
#define Jsi_Realpath(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Realpath(n0,n1,n2))
#define Jsi_Readlink(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Readlink(n0,n1,n2,n3))
#define Jsi_GetStdChannel(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_GetStdChannel(n0,n1))
#define Jsi_FSNative(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_FSNative(n0,n1))
#define Jsi_Link(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Link(n0,n1,n2,n3))







|







 







|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
....
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
#ifndef __JSI_STUBS_H__
#define __JSI_STUBS_H__
#ifndef JSI_AMALGAMATION
#include "jsi.h"
#endif


#define JSI_STUBS_MD5 "54b3c19a995493d17414e173ea427a66"

#undef JSI_EXTENSION_INI
#define JSI_EXTENSION_INI Jsi_Stubs *jsiStubsPtr = NULL;

#ifdef JSI__MUSL
#define JSI_STUBS_BLDFLAGS 1
#else
................................................................................
    int(*_Jsi_Truncate)(Jsi_Interp *interp, Jsi_Channel chan, uint len);
    Jsi_Wide(*_Jsi_Rewind)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Flush)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Getc)(Jsi_Interp *interp, Jsi_Channel chan);
    int(*_Jsi_Printf)(Jsi_Interp *interp, Jsi_Channel chan, const char *fmt, ...);
    int(*_Jsi_Ungetc)(Jsi_Interp *interp, Jsi_Channel chan, int ch);
    char*(*_Jsi_Gets)(Jsi_Interp *interp, Jsi_Channel chan, char *s, int size);
    int(*_Jsi_Puts)(Jsi_Interp *interp, Jsi_Channel chan, const char *str, int size);
    int(*_Jsi_Scandir)(Jsi_Interp *interp, Jsi_Value *path, Jsi_Dirent ***namelist, Jsi_ScandirFilter *filter, Jsi_ScandirCompare *compare );
    int(*_Jsi_SetChannelOption)(Jsi_Interp *interp, Jsi_Channel chan, const char *optionName, const char *newValue);
    char*(*_Jsi_Realpath)(Jsi_Interp *interp, Jsi_Value *path, char *newname);
    int(*_Jsi_Readlink)(Jsi_Interp *interp, Jsi_Value* path, char *ret, int len);
    Jsi_Channel(*_Jsi_GetStdChannel)(Jsi_Interp *interp, int id);
    bool(*_Jsi_FSNative)(Jsi_Interp *interp, Jsi_Value* path);
    int(*_Jsi_Link)(Jsi_Interp *interp, Jsi_Value* src, Jsi_Value *dest, int typ);
................................................................................
#define Jsi_Truncate(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Truncate(n0,n1,n2))
#define Jsi_Rewind(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Rewind(n0,n1))
#define Jsi_Flush(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Flush(n0,n1))
#define Jsi_Getc(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_Getc(n0,n1))
#define Jsi_Printf(n0,n1,n2,...) JSISTUBCALL(jsiStubsPtr, _Jsi_Printf(n0,n1,n2,##__VA_ARGS__))
#define Jsi_Ungetc(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Ungetc(n0,n1,n2))
#define Jsi_Gets(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Gets(n0,n1,n2,n3))
#define Jsi_Puts(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Puts(n0,n1,n2,n3))
#define Jsi_Scandir(n0,n1,n2,n3,n4) JSISTUBCALL(jsiStubsPtr, _Jsi_Scandir(n0,n1,n2,n3,n4))
#define Jsi_SetChannelOption(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_SetChannelOption(n0,n1,n2,n3))
#define Jsi_Realpath(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_Realpath(n0,n1,n2))
#define Jsi_Readlink(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Readlink(n0,n1,n2,n3))
#define Jsi_GetStdChannel(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_GetStdChannel(n0,n1))
#define Jsi_FSNative(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_FSNative(n0,n1))
#define Jsi_Link(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_Link(n0,n1,n2,n3))

Changes to src/jsiUtils.c.

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
            }
            if (buf1[0] == 0 || (buf1[0] == '.' && buf1[1] == 0))
                goto done;
        }
        lastCnt = 1;
        Jsi_Strcpy(lastMsg, buf1);
        if (!islog)
            Jsi_Puts(interp, jsi_Stderr, buf1);
            //fputs(buf1, stderr);
        else {
            Jsi_DString jStr={}, kStr={};
            Jsi_DSPrintf(&kStr, "[%s, \"%s\", \"%s\", %d, %d ]",
                Jsi_JSONQuote(interp, buf1, -1, &jStr), mt, curFile, line, lofs);
            if (Jsi_FunctionInvokeJSON(interp->parent, interp->debugOpts.msgCallback, Jsi_DSValue(&kStr), NULL) != JSI_OK)
                code = 1;







|







273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
            }
            if (buf1[0] == 0 || (buf1[0] == '.' && buf1[1] == 0))
                goto done;
        }
        lastCnt = 1;
        Jsi_Strcpy(lastMsg, buf1);
        if (!islog)
            Jsi_Puts(interp, jsi_Stderr, buf1, -1);
            //fputs(buf1, stderr);
        else {
            Jsi_DString jStr={}, kStr={};
            Jsi_DSPrintf(&kStr, "[%s, \"%s\", \"%s\", %d, %d ]",
                Jsi_JSONQuote(interp, buf1, -1, &jStr), mt, curFile, line, lofs);
            if (Jsi_FunctionInvokeJSON(interp->parent, interp->debugOpts.msgCallback, Jsi_DSValue(&kStr), NULL) != JSI_OK)
                code = 1;

Changes to tests/utf.jsi.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
..
52
53
54
55
56
57
58
59
60
61
;d = 'a♥c';
;d[0];
;d[1];
;d[2];
;d[3];
;d[9];


x = JSON.parse('"\\u0060\\u0000\\u0062"');
puts(x.length, x[0], x[1], x[2], x[3]);
y = 'ab\0c';
puts(y.length, y[0], y[1], y[2], y[3]);
z = 'ab\u0000c';
puts(z.length, z[0], z[1], z[2], z[3]);

/*
=!EXPECTSTART!=
b = '♥' ==> ♥
b.length ==> 1
b+'a' ==> ♥a
encodeURI(b) ==> %e2%99%a5
c = '❤' ==> ❤
................................................................................
a === y ==> true
d = 'a♥c' ==> a♥c
d[0] ==> a
d[1] ==> ♥
d[2] ==> c
d[3] ==> undefined
d[9] ==> undefined
3 `  b undefined
4 a b  c
4 a b  c







<
<
<
<
<
<
<
<







 







<
<
<
22
23
24
25
26
27
28








29
30
31
32
33
34
35
..
44
45
46
47
48
49
50



;d = 'a♥c';
;d[0];
;d[1];
;d[2];
;d[3];
;d[9];









/*
=!EXPECTSTART!=
b = '♥' ==> ♥
b.length ==> 1
b+'a' ==> ♥a
encodeURI(b) ==> %e2%99%a5
c = '❤' ==> ❤
................................................................................
a === y ==> true
d = 'a♥c' ==> a♥c
d[0] ==> a
d[1] ==> ♥
d[2] ==> c
d[3] ==> undefined
d[9] ==> undefined



Added tests/utf2.jsi.











































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/local/bin/jsish -u
var x, y, z;

x = JSON.parse('"\\u0060\\u0000\\u0062"');
puts(x.length, x[0], x[1], x[2], x[3]);
y = 'ab\0c';
puts(y.length, y[0], y[1], y[2], y[3]);
z = 'ab\u0000c';
puts(z.length, z[0], z[1], z[2], z[3]);
puts(y);
puts(z);

/*
=!EXPECTSTART!=
3 `  b undefined
4 a b  c
4 a b  c
ab\0c
ab\0c
=!EXPECTEND!=
*/

Changes to tools/protos.jsi.

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

Changes to www/web.wiki.

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147


This provides runtime type-checking of function calls.

To debug, we set a breakpoint on warnings which are output
to the console.

The Jsi support functions are included from: <b>/jsi/lib/jsig.js</b>

<hr>
<h2 id=utilities>Utilities</h2>

The following resources are available to include from <b>/jsi/lib/</b>:

  *  [../lib/web/jsig.js|jsig.js]: Support code for type-checking.
  *  [https://github.com/remy/bind.js|bind.js]: Two way binding between data and elements.
  *  [http://zeptojs.com/|zepto.js]: Lite subset of JQuery.







|






|


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147


This provides runtime type-checking of function calls.

To debug, we set a breakpoint on warnings which are output
to the console.

The Jsi support functions are included from: <b>/jsi/lib/JSig.js</b>

<hr>
<h2 id=utilities>Utilities</h2>

The following resources are available to include from <b>/jsi/lib/</b>:

  *  [../lib/web/JSig.js|JSig.js]: Support code for type-checking.
  *  [https://github.com/remy/bind.js|bind.js]: Two way binding between data and elements.
  *  [http://zeptojs.com/|zepto.js]: Lite subset of JQuery.