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

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

Overview
Comment:Release "2.8.28". Fix String.match() to not force /g always on.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:2c45c8227408d39d86418be2879b0298e14af5d8
User & Date: pmacdona 2019-05-15 01:38:09
Context
2019-05-15
04:01
String.match, further fix. check-in: d9d4c2b3bc user: pmacdona tags: trunk
01:38
Release "2.8.28". Fix String.match() to not force /g always on. check-in: 2c45c82274 user: pmacdona tags: trunk
2019-05-13
14:15
Release "2.8.27". require: change default version back to 0, and add back lastReq field. check-in: fea7a7d0f4 user: pmacdona tags: trunk
Changes

Changes to lib/Jsi_Jspp.jsi.

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
..
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
        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;
................................................................................
                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';







>
|




|





>
>







 







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







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
..
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
        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);
        var someDef = str.indexOf('=')>=0;
        if (str.indexOf(':')<0 && !someDef) // Skip functions with no types or defaults
            return str;
        var res = 'function '+fnam+'(';
    
        var astr = vals[2].trim();
        var cres = '/* Fn('+astr+') */ ';
        var acall = [];
        if (astr !== '') {
            var alst = astr.split(',');
            var minargs = alst.length, maxargs = minargs;
            var last = alst.length-1;
            if (!someDef)
                cres += 'Jsi.CheckFunc("'+fnam+'",'+minargs+','+maxargs+', arguments.length';
            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;
................................................................................
                res += afnam;
                acall.push(afnam);
                var defval, atyp = '';
                if (avals.length>2)
                    atyp = avals[2].substr(1);
                if (atyp !== '')
                    typeValidate(atyp);
                if (!someDef) {
                    cres += ', "'+afnam+'",'+afnam+',"'+atyp+'"';
                } else {
    
                    var hasDef = (avals[3] && avals[3] !== '');
                    if (hasDef)
                        cres += '  '+afnam+'=';
                    cres += 'Jsi.ArgCheck('+(i+1)+',"'+fnam+'","'+afnam+'",'+afnam+',"'+atyp+'"';
                    if (hasDef) { // 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 += ');';
                }
            }
            if (someDef)
                cres += '  Jsi.ArgCount("'+fnam+'",'+minargs+','+maxargs+',arguments.length); ';
            else
                cres += ');';
        }
        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';

Changes to lib/web/jsiweb.js.

116
117
118
119
120
121
122










123
124
125
126
127
128
129
                default:
                    this.errorCmd(pre+" type unknown '"+tlst[i]+'" not one of: '+this.typeNameStr);
                    return 0;
            }
        }
        this.errorCmd(pre+' type mismatch "'+nam+'" is not of type "'+typ+'": '+vtyp);
    },










    
    ValueType: function(val) { // Return type of value.
        var vt = typeof val;
        switch (vt) {
            case "undefined": return "void";
            case "number":
            case "string":







>
>
>
>
>
>
>
>
>
>







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
                default:
                    this.errorCmd(pre+" type unknown '"+tlst[i]+'" not one of: '+this.typeNameStr);
                    return 0;
            }
        }
        this.errorCmd(pre+' type mismatch "'+nam+'" is not of type "'+typ+'": '+vtyp);
    },
    
    CheckFunc: function(nam, min, max, cnt) { // Check when no default values.
        var a = arguments;
        this.ArgCount(nam, min, max, cnt);
        var aind = 4, anum = 1;
        for (anum = 1; aind<a.length; anum++, aind += 3) {
            var anam = a[aind], val = a[aind+1], typ = a[aind+2];
            this.ArgCheck(anum, nam, anam, val, typ);
        }
    },
    
    ValueType: function(val) { // Return type of value.
        var vt = typeof val;
        switch (vt) {
            case "undefined": return "void";
            case "number":
            case "string":

Changes to src/jsi.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
....
8964
8965
8966
8967
8968
8969
8970

8971
8972
8973
8974
8975
8976
8977
.....
19458
19459
19460
19461
19462
19463
19464
19465
19466
19467
19468
19469
19470
19471
19472
.....
19473
19474
19475
19476
19477
19478
19479

19480
19481
19482
19483
19484
19485
19486
.....
19513
19514
19515
19516
19517
19518
19519


19520
19521
19522
19523
19524
19525
19526
19527
19528
19529
19530
19531
19532
19533
19534
19535
19536
19537
19538
19539
19540
19541
.....
19559
19560
19561
19562
19563
19564
19565
19566
19567
19568
19569
19570
19571
19572
19573
.....
27975
27976
27977
27978
27979
27980
27981
27982
27983
27984
27985
27986
27987
27988
27989
.....
28343
28344
28345
28346
28347
28348
28349
28350
28351
28352
28353
28354
28355
28356
28357
.....
28395
28396
28397
28398
28399
28400
28401
28402
28403
28404
28405
28406
28407
28408
28409
.....
28528
28529
28530
28531
28532
28533
28534
28535
28536
28537
28538
28539
28540
28541
28542
/* 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 27

#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

................................................................................
extern int jsi_GetDefaultType(const char *cp);
extern Jsi_RC jsi_ParseTypeCheckStr(Jsi_Interp *interp, const char *str);
extern Jsi_Interp *jsi_DoExit(Jsi_Interp *interp, int rc);
extern Jsi_RC jsi_CDataDataSetCmdSub(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr, int flags);
extern Jsi_RC jsi_AliasInvoke(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr);
extern Jsi_Number jsi_VersionNormalize(Jsi_Number ver, char *obuf, size_t osiz);
extern const char* jsi_FuncGetCode(Jsi_Interp *interp, Jsi_Func *func, int *lenPtr);


extern Jsi_RC Jsi_CleanValue(Jsi_Interp *interp, Jsi_Interp *tointerp, Jsi_Value *val, Jsi_Value **ret); //TODO: EXPORT

extern char jsi_toHexChar(char code);
extern char jsi_fromHexChar(char ch);
extern bool jsi_IsAlnumStr(const char *cp);
extern char *jsi_TrimStr(char *str);
................................................................................
    }
    
    return JSI_OK;
}



static Jsi_RC jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret, int *ofs)
{
    Jsi_Regex *re;
    int regexec_flags = 0;
    Jsi_Value *seq = pattern;

    if (seq == NULL || seq->vt != JSI_VT_OBJECT || seq->d.obj->ot != JSI_OT_REGEXP) {
        Jsi_ValueMakeNull(interp, &ret);
................................................................................
        return JSI_OK;
    }
    re = seq->d.obj->d.robj;
    regex_t *reg = &re->reg;
    
    regmatch_t pos[MAX_SUBREGEX] = {};
    int num_matches = 0, r, n = Jsi_Strlen(str);

    Jsi_Obj *obj;
    
    do {
        r = regexec(reg, str, MAX_SUBREGEX, pos, regexec_flags);

        if (r >= REG_BADPAT) {
            char buf[JSI_BUFSIZ];
................................................................................
            Jsi_Value *val = Jsi_ValueMakeString(interp, NULL, 
                jsi_SubstrDup(str, pos[i].rm_so, pos[i].rm_eo - pos[i].rm_so));
            if (ofs)
                *ofs = pos[i].rm_eo;
            Jsi_ValueInsertArray(interp, ret, num_matches, val, 0);
            num_matches++;
        }


        if (num_matches == 1 && (ofs || (!(re->eflags&JSI_REG_GLOB))))
            break;
        
        str += pos[0].rm_eo;
        n -= pos[0].rm_eo;

        regexec_flags |= REG_NOTBOL;
    } while (n && pos[0].rm_eo>0);
    
    return JSI_OK;
}

Jsi_RC Jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret)
{
    return jsi_RegExpMatches(interp, pattern, str, ret, NULL);
}


#define FN_regexec JSI_INFO("\
Perform regexp match checking.  Returns the array of matches.\
With the global flag g, sets lastIndex and returns next match.")
static Jsi_RC RegexpExecCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
................................................................................
        l = Jsi_ValueObjLookup(interp, v, "lastIndex", 0);
        if (l && Jsi_ValueGetNumber(interp, l, &lv) != JSI_OK) 
            return Jsi_LogError("lastIndex not a number");
        if (l)
            re->lastIndex = (int)lv;
    }
    int ofs = 0;
    Jsi_RC rc = jsi_RegExpMatches(interp, v, re->lastIndex<slen?str+re->lastIndex:"", *ret, isglob?&ofs:NULL);
    if (isglob) {
        if (rc != JSI_OK)
            return rc;
        re->lastIndex += ofs;
        if (Jsi_ValueIsNull(interp, *ret))
            re->lastIndex = 0;
        lv = (Jsi_Number)re->lastIndex;
................................................................................
    if (Jsi_ValueIsString(interp, seq)) {
        char *cp = Jsi_ValueString(interp, seq, NULL);

        if (jsi_RegExpValueNew(interp, cp, seq) != JSI_OK)
            return JSI_ERROR;
    }
    /* TODO: differentiate from re.exec() */
    return Jsi_RegExpMatches(interp, seq, v, *ret);
}

static Jsi_RC StringFromCharCodeCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr)
{
    if (!(_this->vt == JSI_VT_OBJECT && _this->d.obj->ot == JSI_OT_FUNCTION &&
       _this->d.obj->__proto__ == interp->String_prototype->d.obj->__proto__ ))
................................................................................
    Jsi_Value *seq, *strVal;
    Jsi_DString dStr = {};
    regex_t *regex;
    Jsi_Regex *re;
    const char *p;
    int maxArgs = 1;

    int offset = 0, n, j, opt_all = 0, num_matches = 0;
    /* Is a generic  String.replace if _this->d.obj is a function */
    ChkString(_this, funcPtr, source_str, &source_len, &bLen);
    source_len = bLen;
    if (!skip)
        strVal = _this;
    else
        strVal = Jsi_ValueArrayIndex(interp, args, 0);
................................................................................
    if (seq == NULL || seq->vt != JSI_VT_OBJECT || seq->d.obj->ot != JSI_OT_REGEXP) {
        Jsi_ValueMakeNull(interp, ret);
        return JSI_OK;
    }

    re = seq->d.obj->d.robj;
    regex = &re->reg;
    opt_all = (re->eflags & JSI_REG_GLOB);
    
    regmatch_t pmatch[MAX_SUBREGEX] = {};
    /* If an offset has been specified, adjust for that now.
     * If it points past the end of the string, point to the terminating null
     */
    int eoffset=0;
    if (offset) {
................................................................................
            }
            Jsi_DecrRefCount(interp, inStr);
        }
        eoffset += pmatch[0].rm_eo;
        p += pmatch[0].rm_eo;
        n -= pmatch[0].rm_eo;
        /* If -all is not specified, or there is no source left, we are done */
        if (!opt_all || n == 0 || pmatch[0].rm_eo == 0) {
            break;
        }
        /* An anchored pattern without -line must be done */
        if ((re->eflags & JSI_REG_NEWLINE) == 0 && re->pattern[0] == '^') {
            break;
        }
        






|







 







>







 







|







 







>







 







>
>
|













|







 







|







 







|







 







|







 







|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
....
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
.....
19459
19460
19461
19462
19463
19464
19465
19466
19467
19468
19469
19470
19471
19472
19473
.....
19474
19475
19476
19477
19478
19479
19480
19481
19482
19483
19484
19485
19486
19487
19488
.....
19515
19516
19517
19518
19519
19520
19521
19522
19523
19524
19525
19526
19527
19528
19529
19530
19531
19532
19533
19534
19535
19536
19537
19538
19539
19540
19541
19542
19543
19544
19545
.....
19563
19564
19565
19566
19567
19568
19569
19570
19571
19572
19573
19574
19575
19576
19577
.....
27979
27980
27981
27982
27983
27984
27985
27986
27987
27988
27989
27990
27991
27992
27993
.....
28347
28348
28349
28350
28351
28352
28353
28354
28355
28356
28357
28358
28359
28360
28361
.....
28399
28400
28401
28402
28403
28404
28405
28406
28407
28408
28409
28410
28411
28412
28413
.....
28532
28533
28534
28535
28536
28537
28538
28539
28540
28541
28542
28543
28544
28545
28546
/* 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 28

#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

................................................................................
extern int jsi_GetDefaultType(const char *cp);
extern Jsi_RC jsi_ParseTypeCheckStr(Jsi_Interp *interp, const char *str);
extern Jsi_Interp *jsi_DoExit(Jsi_Interp *interp, int rc);
extern Jsi_RC jsi_CDataDataSetCmdSub(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr, int flags);
extern Jsi_RC jsi_AliasInvoke(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr);
extern Jsi_Number jsi_VersionNormalize(Jsi_Number ver, char *obuf, size_t osiz);
extern const char* jsi_FuncGetCode(Jsi_Interp *interp, Jsi_Func *func, int *lenPtr);
extern Jsi_RC jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret, int *ofs, bool match);

extern Jsi_RC Jsi_CleanValue(Jsi_Interp *interp, Jsi_Interp *tointerp, Jsi_Value *val, Jsi_Value **ret); //TODO: EXPORT

extern char jsi_toHexChar(char code);
extern char jsi_fromHexChar(char ch);
extern bool jsi_IsAlnumStr(const char *cp);
extern char *jsi_TrimStr(char *str);
................................................................................
    }
    
    return JSI_OK;
}



Jsi_RC jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret, int *ofs, bool match)
{
    Jsi_Regex *re;
    int regexec_flags = 0;
    Jsi_Value *seq = pattern;

    if (seq == NULL || seq->vt != JSI_VT_OBJECT || seq->d.obj->ot != JSI_OT_REGEXP) {
        Jsi_ValueMakeNull(interp, &ret);
................................................................................
        return JSI_OK;
    }
    re = seq->d.obj->d.robj;
    regex_t *reg = &re->reg;
    
    regmatch_t pos[MAX_SUBREGEX] = {};
    int num_matches = 0, r, n = Jsi_Strlen(str);
    int isglob = (re->eflags&JSI_REG_GLOB);
    Jsi_Obj *obj;
    
    do {
        r = regexec(reg, str, MAX_SUBREGEX, pos, regexec_flags);

        if (r >= REG_BADPAT) {
            char buf[JSI_BUFSIZ];
................................................................................
            Jsi_Value *val = Jsi_ValueMakeString(interp, NULL, 
                jsi_SubstrDup(str, pos[i].rm_so, pos[i].rm_eo - pos[i].rm_so));
            if (ofs)
                *ofs = pos[i].rm_eo;
            Jsi_ValueInsertArray(interp, ret, num_matches, val, 0);
            num_matches++;
        }
        if (num_matches && match && !isglob)
            return JSI_OK;
        if (num_matches == 1 && (ofs || !isglob))
            break;
        
        str += pos[0].rm_eo;
        n -= pos[0].rm_eo;

        regexec_flags |= REG_NOTBOL;
    } while (n && pos[0].rm_eo>0);
    
    return JSI_OK;
}

Jsi_RC Jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret)
{
    return jsi_RegExpMatches(interp, pattern, str, ret, NULL, 0);
}


#define FN_regexec JSI_INFO("\
Perform regexp match checking.  Returns the array of matches.\
With the global flag g, sets lastIndex and returns next match.")
static Jsi_RC RegexpExecCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
................................................................................
        l = Jsi_ValueObjLookup(interp, v, "lastIndex", 0);
        if (l && Jsi_ValueGetNumber(interp, l, &lv) != JSI_OK) 
            return Jsi_LogError("lastIndex not a number");
        if (l)
            re->lastIndex = (int)lv;
    }
    int ofs = 0;
    Jsi_RC rc = jsi_RegExpMatches(interp, v, re->lastIndex<slen?str+re->lastIndex:"", *ret, isglob?&ofs:NULL, 0);
    if (isglob) {
        if (rc != JSI_OK)
            return rc;
        re->lastIndex += ofs;
        if (Jsi_ValueIsNull(interp, *ret))
            re->lastIndex = 0;
        lv = (Jsi_Number)re->lastIndex;
................................................................................
    if (Jsi_ValueIsString(interp, seq)) {
        char *cp = Jsi_ValueString(interp, seq, NULL);

        if (jsi_RegExpValueNew(interp, cp, seq) != JSI_OK)
            return JSI_ERROR;
    }
    /* TODO: differentiate from re.exec() */
    return jsi_RegExpMatches(interp, seq, v, *ret, NULL, 1);
}

static Jsi_RC StringFromCharCodeCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr)
{
    if (!(_this->vt == JSI_VT_OBJECT && _this->d.obj->ot == JSI_OT_FUNCTION &&
       _this->d.obj->__proto__ == interp->String_prototype->d.obj->__proto__ ))
................................................................................
    Jsi_Value *seq, *strVal;
    Jsi_DString dStr = {};
    regex_t *regex;
    Jsi_Regex *re;
    const char *p;
    int maxArgs = 1;

    int offset = 0, n, j, isglob = 0, num_matches = 0;
    /* Is a generic  String.replace if _this->d.obj is a function */
    ChkString(_this, funcPtr, source_str, &source_len, &bLen);
    source_len = bLen;
    if (!skip)
        strVal = _this;
    else
        strVal = Jsi_ValueArrayIndex(interp, args, 0);
................................................................................
    if (seq == NULL || seq->vt != JSI_VT_OBJECT || seq->d.obj->ot != JSI_OT_REGEXP) {
        Jsi_ValueMakeNull(interp, ret);
        return JSI_OK;
    }

    re = seq->d.obj->d.robj;
    regex = &re->reg;
    isglob = (re->eflags & JSI_REG_GLOB);
    
    regmatch_t pmatch[MAX_SUBREGEX] = {};
    /* If an offset has been specified, adjust for that now.
     * If it points past the end of the string, point to the terminating null
     */
    int eoffset=0;
    if (offset) {
................................................................................
            }
            Jsi_DecrRefCount(interp, inStr);
        }
        eoffset += pmatch[0].rm_eo;
        p += pmatch[0].rm_eo;
        n -= pmatch[0].rm_eo;
        /* If -all is not specified, or there is no source left, we are done */
        if (!isglob || n == 0 || pmatch[0].rm_eo == 0) {
            break;
        }
        /* An anchored pattern without -line must be done */
        if ((re->eflags & JSI_REG_NEWLINE) == 0 && re->pattern[0] == '^') {
            break;
        }
        

Changes to src/jsi.h.

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

#define JSI_VERSION_MAJOR   2
#define JSI_VERSION_MINOR   8
#define JSI_VERSION_RELEASE 27

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

#ifndef JSI_EXTERN
#define JSI_EXTERN extern
#endif







|







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

#define JSI_VERSION_MAJOR   2
#define JSI_VERSION_MINOR   8
#define JSI_VERSION_RELEASE 28

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

#ifndef JSI_EXTERN
#define JSI_EXTERN extern
#endif

Changes to src/jsiInt.h.

1534
1535
1536
1537
1538
1539
1540

1541
1542
1543
1544
1545
1546
1547
extern int jsi_GetDefaultType(const char *cp);
extern Jsi_RC jsi_ParseTypeCheckStr(Jsi_Interp *interp, const char *str);
extern Jsi_Interp *jsi_DoExit(Jsi_Interp *interp, int rc);
extern Jsi_RC jsi_CDataDataSetCmdSub(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr, int flags);
extern Jsi_RC jsi_AliasInvoke(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr);
extern Jsi_Number jsi_VersionNormalize(Jsi_Number ver, char *obuf, size_t osiz);
extern const char* jsi_FuncGetCode(Jsi_Interp *interp, Jsi_Func *func, int *lenPtr);


extern Jsi_RC Jsi_CleanValue(Jsi_Interp *interp, Jsi_Interp *tointerp, Jsi_Value *val, Jsi_Value **ret); //TODO: EXPORT

extern char jsi_toHexChar(char code);
extern char jsi_fromHexChar(char ch);
extern bool jsi_IsAlnumStr(const char *cp);
extern char *jsi_TrimStr(char *str);







>







1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
extern int jsi_GetDefaultType(const char *cp);
extern Jsi_RC jsi_ParseTypeCheckStr(Jsi_Interp *interp, const char *str);
extern Jsi_Interp *jsi_DoExit(Jsi_Interp *interp, int rc);
extern Jsi_RC jsi_CDataDataSetCmdSub(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr, int flags);
extern Jsi_RC jsi_AliasInvoke(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr);
extern Jsi_Number jsi_VersionNormalize(Jsi_Number ver, char *obuf, size_t osiz);
extern const char* jsi_FuncGetCode(Jsi_Interp *interp, Jsi_Func *func, int *lenPtr);
extern Jsi_RC jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret, int *ofs, bool match);

extern Jsi_RC Jsi_CleanValue(Jsi_Interp *interp, Jsi_Interp *tointerp, Jsi_Value *val, Jsi_Value **ret); //TODO: EXPORT

extern char jsi_toHexChar(char code);
extern char jsi_fromHexChar(char ch);
extern bool jsi_IsAlnumStr(const char *cp);
extern char *jsi_TrimStr(char *str);

Changes to src/jsiRegexp.c.

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
189
190
191
192
193
194
195

196
197
198
199
200
201
202
...
229
230
231
232
233
234
235


236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
...
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    }
    
    return JSI_OK;
}



static Jsi_RC jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret, int *ofs)
{
    Jsi_Regex *re;
    int regexec_flags = 0;
    Jsi_Value *seq = pattern;

    if (seq == NULL || seq->vt != JSI_VT_OBJECT || seq->d.obj->ot != JSI_OT_REGEXP) {
        Jsi_ValueMakeNull(interp, &ret);
................................................................................
        return JSI_OK;
    }
    re = seq->d.obj->d.robj;
    regex_t *reg = &re->reg;
    
    regmatch_t pos[MAX_SUBREGEX] = {};
    int num_matches = 0, r, n = Jsi_Strlen(str);

    Jsi_Obj *obj;
    
    do {
        r = regexec(reg, str, MAX_SUBREGEX, pos, regexec_flags);

        if (r >= REG_BADPAT) {
            char buf[JSI_BUFSIZ];
................................................................................
            Jsi_Value *val = Jsi_ValueMakeString(interp, NULL, 
                jsi_SubstrDup(str, pos[i].rm_so, pos[i].rm_eo - pos[i].rm_so));
            if (ofs)
                *ofs = pos[i].rm_eo;
            Jsi_ValueInsertArray(interp, ret, num_matches, val, 0);
            num_matches++;
        }


        if (num_matches == 1 && (ofs || (!(re->eflags&JSI_REG_GLOB))))
            break;
        
        str += pos[0].rm_eo;
        n -= pos[0].rm_eo;

        regexec_flags |= REG_NOTBOL;
    } while (n && pos[0].rm_eo>0);
    
    return JSI_OK;
}

Jsi_RC Jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret)
{
    return jsi_RegExpMatches(interp, pattern, str, ret, NULL);
}


#define FN_regexec JSI_INFO("\
Perform regexp match checking.  Returns the array of matches.\
With the global flag g, sets lastIndex and returns next match.")
static Jsi_RC RegexpExecCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
................................................................................
        l = Jsi_ValueObjLookup(interp, v, "lastIndex", 0);
        if (l && Jsi_ValueGetNumber(interp, l, &lv) != JSI_OK) 
            return Jsi_LogError("lastIndex not a number");
        if (l)
            re->lastIndex = (int)lv;
    }
    int ofs = 0;
    Jsi_RC rc = jsi_RegExpMatches(interp, v, re->lastIndex<slen?str+re->lastIndex:"", *ret, isglob?&ofs:NULL);
    if (isglob) {
        if (rc != JSI_OK)
            return rc;
        re->lastIndex += ofs;
        if (Jsi_ValueIsNull(interp, *ret))
            re->lastIndex = 0;
        lv = (Jsi_Number)re->lastIndex;







|







 







>







 







>
>
|













|







 







|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
    }
    
    return JSI_OK;
}



Jsi_RC jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret, int *ofs, bool match)
{
    Jsi_Regex *re;
    int regexec_flags = 0;
    Jsi_Value *seq = pattern;

    if (seq == NULL || seq->vt != JSI_VT_OBJECT || seq->d.obj->ot != JSI_OT_REGEXP) {
        Jsi_ValueMakeNull(interp, &ret);
................................................................................
        return JSI_OK;
    }
    re = seq->d.obj->d.robj;
    regex_t *reg = &re->reg;
    
    regmatch_t pos[MAX_SUBREGEX] = {};
    int num_matches = 0, r, n = Jsi_Strlen(str);
    int isglob = (re->eflags&JSI_REG_GLOB);
    Jsi_Obj *obj;
    
    do {
        r = regexec(reg, str, MAX_SUBREGEX, pos, regexec_flags);

        if (r >= REG_BADPAT) {
            char buf[JSI_BUFSIZ];
................................................................................
            Jsi_Value *val = Jsi_ValueMakeString(interp, NULL, 
                jsi_SubstrDup(str, pos[i].rm_so, pos[i].rm_eo - pos[i].rm_so));
            if (ofs)
                *ofs = pos[i].rm_eo;
            Jsi_ValueInsertArray(interp, ret, num_matches, val, 0);
            num_matches++;
        }
        if (num_matches && match && !isglob)
            return JSI_OK;
        if (num_matches == 1 && (ofs || !isglob))
            break;
        
        str += pos[0].rm_eo;
        n -= pos[0].rm_eo;

        regexec_flags |= REG_NOTBOL;
    } while (n && pos[0].rm_eo>0);
    
    return JSI_OK;
}

Jsi_RC Jsi_RegExpMatches(Jsi_Interp *interp, Jsi_Value *pattern, const char *str, Jsi_Value *ret)
{
    return jsi_RegExpMatches(interp, pattern, str, ret, NULL, 0);
}


#define FN_regexec JSI_INFO("\
Perform regexp match checking.  Returns the array of matches.\
With the global flag g, sets lastIndex and returns next match.")
static Jsi_RC RegexpExecCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
................................................................................
        l = Jsi_ValueObjLookup(interp, v, "lastIndex", 0);
        if (l && Jsi_ValueGetNumber(interp, l, &lv) != JSI_OK) 
            return Jsi_LogError("lastIndex not a number");
        if (l)
            re->lastIndex = (int)lv;
    }
    int ofs = 0;
    Jsi_RC rc = jsi_RegExpMatches(interp, v, re->lastIndex<slen?str+re->lastIndex:"", *ret, isglob?&ofs:NULL, 0);
    if (isglob) {
        if (rc != JSI_OK)
            return rc;
        re->lastIndex += ofs;
        if (Jsi_ValueIsNull(interp, *ret))
            re->lastIndex = 0;
        lv = (Jsi_Number)re->lastIndex;

Changes to src/jsiString.c.

259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
...
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
...
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
    if (Jsi_ValueIsString(interp, seq)) {
        char *cp = Jsi_ValueString(interp, seq, NULL);

        if (jsi_RegExpValueNew(interp, cp, seq) != JSI_OK)
            return JSI_ERROR;
    }
    /* TODO: differentiate from re.exec() */
    return Jsi_RegExpMatches(interp, seq, v, *ret);
}

static Jsi_RC StringFromCharCodeCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr)
{
    if (!(_this->vt == JSI_VT_OBJECT && _this->d.obj->ot == JSI_OT_FUNCTION &&
       _this->d.obj->__proto__ == interp->String_prototype->d.obj->__proto__ ))
................................................................................
    Jsi_Value *seq, *strVal;
    Jsi_DString dStr = {};
    regex_t *regex;
    Jsi_Regex *re;
    const char *p;
    int maxArgs = 1;

    int offset = 0, n, j, opt_all = 0, num_matches = 0;
    /* Is a generic  String.replace if _this->d.obj is a function */
    ChkString(_this, funcPtr, source_str, &source_len, &bLen);
    source_len = bLen;
    if (!skip)
        strVal = _this;
    else
        strVal = Jsi_ValueArrayIndex(interp, args, 0);
................................................................................
    if (seq == NULL || seq->vt != JSI_VT_OBJECT || seq->d.obj->ot != JSI_OT_REGEXP) {
        Jsi_ValueMakeNull(interp, ret);
        return JSI_OK;
    }

    re = seq->d.obj->d.robj;
    regex = &re->reg;
    opt_all = (re->eflags & JSI_REG_GLOB);
    
    regmatch_t pmatch[MAX_SUBREGEX] = {};
    /* If an offset has been specified, adjust for that now.
     * If it points past the end of the string, point to the terminating null
     */
    int eoffset=0;
    if (offset) {
................................................................................
            }
            Jsi_DecrRefCount(interp, inStr);
        }
        eoffset += pmatch[0].rm_eo;
        p += pmatch[0].rm_eo;
        n -= pmatch[0].rm_eo;
        /* If -all is not specified, or there is no source left, we are done */
        if (!opt_all || n == 0 || pmatch[0].rm_eo == 0) {
            break;
        }
        /* An anchored pattern without -line must be done */
        if ((re->eflags & JSI_REG_NEWLINE) == 0 && re->pattern[0] == '^') {
            break;
        }
        







|







 







|







 







|







 







|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
...
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
...
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
    if (Jsi_ValueIsString(interp, seq)) {
        char *cp = Jsi_ValueString(interp, seq, NULL);

        if (jsi_RegExpValueNew(interp, cp, seq) != JSI_OK)
            return JSI_ERROR;
    }
    /* TODO: differentiate from re.exec() */
    return jsi_RegExpMatches(interp, seq, v, *ret, NULL, 1);
}

static Jsi_RC StringFromCharCodeCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr)
{
    if (!(_this->vt == JSI_VT_OBJECT && _this->d.obj->ot == JSI_OT_FUNCTION &&
       _this->d.obj->__proto__ == interp->String_prototype->d.obj->__proto__ ))
................................................................................
    Jsi_Value *seq, *strVal;
    Jsi_DString dStr = {};
    regex_t *regex;
    Jsi_Regex *re;
    const char *p;
    int maxArgs = 1;

    int offset = 0, n, j, isglob = 0, num_matches = 0;
    /* Is a generic  String.replace if _this->d.obj is a function */
    ChkString(_this, funcPtr, source_str, &source_len, &bLen);
    source_len = bLen;
    if (!skip)
        strVal = _this;
    else
        strVal = Jsi_ValueArrayIndex(interp, args, 0);
................................................................................
    if (seq == NULL || seq->vt != JSI_VT_OBJECT || seq->d.obj->ot != JSI_OT_REGEXP) {
        Jsi_ValueMakeNull(interp, ret);
        return JSI_OK;
    }

    re = seq->d.obj->d.robj;
    regex = &re->reg;
    isglob = (re->eflags & JSI_REG_GLOB);
    
    regmatch_t pmatch[MAX_SUBREGEX] = {};
    /* If an offset has been specified, adjust for that now.
     * If it points past the end of the string, point to the terminating null
     */
    int eoffset=0;
    if (offset) {
................................................................................
            }
            Jsi_DecrRefCount(interp, inStr);
        }
        eoffset += pmatch[0].rm_eo;
        p += pmatch[0].rm_eo;
        n -= pmatch[0].rm_eo;
        /* If -all is not specified, or there is no source left, we are done */
        if (!isglob || n == 0 || pmatch[0].rm_eo == 0) {
            break;
        }
        /* An anchored pattern without -line must be done */
        if ((re->eflags & JSI_REG_NEWLINE) == 0 && re->pattern[0] == '^') {
            break;
        }
        

Changes to tools/protos.jsi.

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