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

Overview
Comment:More type massage and fixes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wip
Files: files | file ages | folders
SHA3-256: 85bc8c68e6b9e14f590a84b2c81d79eaf2b167cd5e15eeaa6374a4c7825669da
User & Date: user 2024-07-08 00:41:32
Context
2024-07-08
00:53
Again more type massage and fixes. check-in: 48173f10ad user: rolf tags: wip
00:41
More type massage and fixes. check-in: 85bc8c68e6 user: user tags: wip
2024-07-07
21:31
Do not use the included allocator even on windows. check-in: f5a1497f67 user: user tags: wip
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/datatypes.c.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
|
|   written by Rolf Ade
|   2022
|
\---------------------------------------------------------------------------*/

#include <tdom.h>
#include <stdint.h>
#include <domjson.h>
#include <schema.h>

#ifndef TDOM_NO_SCHEMA

#define CHECK_TI                                                        \







|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
|
|   written by Rolf Ade
|   2022
|
\---------------------------------------------------------------------------*/

#include <dom.h>
#include <stdint.h>
#include <domjson.h>
#include <schema.h>

#ifndef TDOM_NO_SCHEMA

#define CHECK_TI                                                        \

Changes to generic/dom.c.

2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
    info->nextFeedbackPosition = info->feedbackAfter;
    
    Tcl_ResetResult (info->interp);
    result = 1;
    if (chan == NULL) {
        do {
            done = (len < PARSE_CHUNK_SIZE);
            status = XML_Parse (extparser, xmlstring, done ? len : PARSE_CHUNK_SIZE,
                                done);
            if (!done) {
                xmlstring += PARSE_CHUNK_SIZE;
                len -= PARSE_CHUNK_SIZE;
            }
        }  while (!done && status == XML_STATUS_OK);
        switch (status) {
        case XML_STATUS_ERROR:







|
|







2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
    info->nextFeedbackPosition = info->feedbackAfter;
    
    Tcl_ResetResult (info->interp);
    result = 1;
    if (chan == NULL) {
        do {
            done = (len < PARSE_CHUNK_SIZE);
            status = XML_Parse (extparser, xmlstring,
                                (int)(done ? len : PARSE_CHUNK_SIZE), done);
            if (!done) {
                xmlstring += PARSE_CHUNK_SIZE;
                len -= PARSE_CHUNK_SIZE;
            }
        }  while (!done && status == XML_STATUS_OK);
        switch (status) {
        case XML_STATUS_ERROR:
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
        default:
            break;
        }
    } else {
        do {
            len = Tcl_Read (chan, buf, sizeof(buf));
            done = len < sizeof(buf);
            status = XML_Parse (extparser, buf, len, done);
            switch (status) {
            case XML_STATUS_ERROR:
                interpResult = Tcl_GetStringResult(info->interp);
                sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));
                if (interpResult[0] == '\0') {
                    Tcl_ResetResult (info->interp);
                    Tcl_AppendResult(info->interp, "error \"",







|







2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
        default:
            break;
        }
    } else {
        do {
            len = Tcl_Read (chan, buf, sizeof(buf));
            done = len < sizeof(buf);
            status = XML_Parse (extparser, buf, (int)len, done);
            switch (status) {
            case XML_STATUS_ERROR:
                interpResult = Tcl_GetStringResult(info->interp);
                sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));
                if (interpResult[0] == '\0') {
                    Tcl_ResetResult (info->interp);
                    Tcl_AppendResult(info->interp, "error \"",
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
#endif
    Tcl_Interp *interp,
    domParseForestErrorData *forestError,
    int        *resultcode
)
{
    int             done;
    domLength       tclLen;
    enum XML_Status status;
    size_t          len;
    domReadInfo     info;
    char            buf[8192];
    Tcl_Obj        *bufObj;
    Tcl_DString     dStr;
    int             useBinary = 0;
    char           *str;
    domDocument    *doc = domCreateDoc(baseurl, storeLineColumn);







|

<







2272
2273
2274
2275
2276
2277
2278
2279
2280

2281
2282
2283
2284
2285
2286
2287
#endif
    Tcl_Interp *interp,
    domParseForestErrorData *forestError,
    int        *resultcode
)
{
    int             done;
    domLength       tclLen, len;
    enum XML_Status status;

    domReadInfo     info;
    char            buf[8192];
    Tcl_Obj        *bufObj;
    Tcl_DString     dStr;
    int             useBinary = 0;
    char           *str;
    domDocument    *doc = domCreateDoc(baseurl, storeLineColumn);
2353
2354
2355
2356
2357
2358
2359
2360

2361
2362
2363
2364
2365
2366
2367
        info.parser = parser;
        info.currentNode = doc->rootNode;
    }
    
    if (channel == NULL) {
        do {
            done = (length < PARSE_CHUNK_SIZE);
            status = XML_Parse (parser, xml, done ? length : PARSE_CHUNK_SIZE, done);

            if (!done) {
                xml += PARSE_CHUNK_SIZE;
                length -= PARSE_CHUNK_SIZE;
            }
        }  while (!done && status == XML_STATUS_OK);
    } else {
        Tcl_DStringInit (&dStr);







|
>







2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
        info.parser = parser;
        info.currentNode = doc->rootNode;
    }
    
    if (channel == NULL) {
        do {
            done = (length < PARSE_CHUNK_SIZE);
            status = XML_Parse (parser, xml,
                                (int)(done ? length : PARSE_CHUNK_SIZE), done);
            if (!done) {
                xml += PARSE_CHUNK_SIZE;
                length -= PARSE_CHUNK_SIZE;
            }
        }  while (!done && status == XML_STATUS_OK);
    } else {
        Tcl_DStringInit (&dStr);
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
                done = len < sizeof(buf);
            } else {
                len = Tcl_ReadChars (channel, bufObj, 1024, 0);
                done = (len < 1024);
                str = Tcl_GetStringFromObj (bufObj, &tclLen);
            }
            if (useBinary) {
                status = XML_Parse (parser, buf, len, done);
            } else {
                status = XML_Parse (parser, str, tclLen, done);
            }
        } while (!done && status == XML_STATUS_OK);
    }
    switch (status) {
    case XML_STATUS_SUSPENDED:
        DBG(fprintf(stderr, "XML_STATUS_SUSPENDED\n");)
            if (info.status == TCL_BREAK) {







|

|







2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
                done = len < sizeof(buf);
            } else {
                len = Tcl_ReadChars (channel, bufObj, 1024, 0);
                done = (len < 1024);
                str = Tcl_GetStringFromObj (bufObj, &tclLen);
            }
            if (useBinary) {
                status = XML_Parse (parser, buf, (int)len, done);
            } else {
                status = XML_Parse (parser, str, (int)tclLen, done);
            }
        } while (!done && status == XML_STATUS_OK);
    }
    switch (status) {
    case XML_STATUS_SUSPENDED:
        DBG(fprintf(stderr, "XML_STATUS_SUSPENDED\n");)
            if (info.status == TCL_BREAK) {

Changes to generic/domxpath.c.

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
    "FQVARIABLE", "WCARDNAME", "COMMENT", "TEXT", "PI", "NODE", "AXISNAME",
    "EOS"
};


typedef struct {

    Token  token;
    char  *strvalue;
    long   intvalue;
    double realvalue;
    long   pos;

} XPathToken;

typedef XPathToken *XPathTokens;


/*----------------------------------------------------------------------------







|
|
|
|
|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
    "FQVARIABLE", "WCARDNAME", "COMMENT", "TEXT", "PI", "NODE", "AXISNAME",
    "EOS"
};


typedef struct {

    Token      token;
    char      *strvalue;
    domLength  intvalue;
    double     realvalue;
    domLength  pos;

} XPathToken;

typedef XPathToken *XPathTokens;


/*----------------------------------------------------------------------------
305
306
307
308
309
310
311
312

313
314
315
316

317
318
319
320
321
322
323
    char tmp[80];
    switch (rs->type) {
        case EmptyResult:
             fprintf(stderr, "empty result \n");
             break;

        case BoolResult:
             fprintf(stderr, "boolean result: %ld \n", rs->intvalue);

             break;

        case IntResult:
             fprintf(stderr, "int result: %ld \n", rs->intvalue);

             break;

        case RealResult:
             fprintf(stderr, "real result: %f \n", rs->realvalue);
             break;

        case StringResult:







|
>



|
>







305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
    char tmp[80];
    switch (rs->type) {
        case EmptyResult:
             fprintf(stderr, "empty result \n");
             break;

        case BoolResult:
             fprintf(stderr, "boolean result: %" TCL_SIZE_MODIFIER "d \n",
                     rs->intvalue);
             break;

        case IntResult:
             fprintf(stderr, "int result: %" TCL_SIZE_MODIFIER "d \n",
                     rs->intvalue);
             break;

        case RealResult:
             fprintf(stderr, "real result: %f \n", rs->realvalue);
             break;

        case StringResult:
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
}
void rsSetInf ( xpathResultSet *rs ) {
    rs->type = InfResult;
}
void rsSetNInf ( xpathResultSet *rs ) {
    rs->type = NInfResult;
}
void rsSetLong ( xpathResultSet *rs, long i) {
    rs->type = IntResult;
    rs->intvalue = i;
}
void rsSetBool ( xpathResultSet *rs, long i) {
    rs->type = BoolResult;
    rs->intvalue = (i ? 1 : 0);
}
void rsSetString ( xpathResultSet *rs, const char *s) {
    rs->type = StringResult;
    if (s) {
        rs->string     = tdomstrdup(s);







|



|







397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
}
void rsSetInf ( xpathResultSet *rs ) {
    rs->type = InfResult;
}
void rsSetNInf ( xpathResultSet *rs ) {
    rs->type = NInfResult;
}
void rsSetLong ( xpathResultSet *rs, domLength i) {
    rs->type = IntResult;
    rs->intvalue = i;
}
void rsSetBool ( xpathResultSet *rs, domLength i) {
    rs->type = BoolResult;
    rs->intvalue = (i ? 1 : 0);
}
void rsSetString ( xpathResultSet *rs, const char *s) {
    rs->type = StringResult;
    if (s) {
        rs->string     = tdomstrdup(s);
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
        t->child->next = New1(EvalSteps, b);
    } else {
        t->child->next = b;
    }
    return t;
}

static ast NewInt( long i ) {
    ast t = NEWCONS;

    t->type      = Int;
    t->strvalue  = NULL;
    t->intvalue  = i;
    t->realvalue = 0.0;








|







573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
        t->child->next = New1(EvalSteps, b);
    } else {
        t->child->next = b;
    }
    return t;
}

static ast NewInt( domLength i ) {
    ast t = NEWCONS;

    t->type      = Int;
    t->strvalue  = NULL;
    t->intvalue  = i;
    t->realvalue = 0.0;

663
664
665
666
667
668
669
670

671
672
673
674
675
676
677
    int i;

    while (t) {
        for (i=0; i<depth; i++) fprintf(stderr, "   ");
        fprintf(stderr, "%s ", astType2str[t->type]);
        switch (t->type) {

            case Int :        fprintf(stderr, "%ld", t->intvalue);   break;

            case Real:        fprintf(stderr, "%f", t->realvalue);  break;
            case IsElement:
            case IsFQElement:
            case IsNSAttr:
            case IsAttr:
            case ExecFunction:
            case Literal:







|
>







665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
    int i;

    while (t) {
        for (i=0; i<depth; i++) fprintf(stderr, "   ");
        fprintf(stderr, "%s ", astType2str[t->type]);
        switch (t->type) {

            case Int :
                fprintf(stderr, "%" TCL_SIZE_MODIFIER "d", t->intvalue);   break;
            case Real:        fprintf(stderr, "%f", t->realvalue);  break;
            case IsElement:
            case IsFQElement:
            case IsNSAttr:
            case IsAttr:
            case ExecFunction:
            case Literal:
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
EndProduction


/*-----------------------------------------------------------------
|   Step  production
|
\----------------------------------------------------------------*/
static long IsStepPredOptimizable (ast a) {
    ast b;
    long left;
    
    /* Must be called with a != NULL */
    DBG (
        fprintf (stderr, "IsStepPredOptimizable:\n");
        printAst (0,a);
    )
    switch (a->type) {







|

|







1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
EndProduction


/*-----------------------------------------------------------------
|   Step  production
|
\----------------------------------------------------------------*/
static domLength IsStepPredOptimizable (ast a) {
    ast b;
    domLength left;
    
    /* Must be called with a != NULL */
    DBG (
        fprintf (stderr, "IsStepPredOptimizable:\n");
        printAst (0,a);
    )
    switch (a->type) {
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
        }
        a = a->next;
    }
    return 0;
}

/* Must be called with a != NULL */
static int checkStepPatternPredOptimizability ( ast a , long *max) {
    ast b;

    switch (a->type) {
        case Literal:
        case AxisAncestor:
        case AxisAncestorOrSelf:
        case AxisChild:







|







1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
        }
        a = a->next;
    }
    return 0;
}

/* Must be called with a != NULL */
static int checkStepPatternPredOptimizability ( ast a , domLength *max) {
    ast b;

    switch (a->type) {
        case Literal:
        case AxisAncestor:
        case AxisAncestorOrSelf:
        case AxisChild:
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
        default: 
            return 0;
    }
    return 1;
}

/* Must be called with a != NULL */
static long IsStepPatternPredOptimizable ( ast a, long *max ) {
    long f;

    *max = 0;
    f = checkStepPatternPredOptimizability(a, max);
    DBG(
        if (f) {
            fprintf(stderr, "\nStepPattern Pred is optimizable:\n");







|







1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
        default: 
            return 0;
    }
    return 1;
}

/* Must be called with a != NULL */
static long IsStepPatternPredOptimizable ( ast a, domLength *max ) {
    long f;

    *max = 0;
    f = checkStepPatternPredOptimizability(a, max);
    DBG(
        if (f) {
            fprintf(stderr, "\nStepPattern Pred is optimizable:\n");
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
    if (!a) {
        if (*errMsg == NULL) { ErrExpected("StepPattern") }; 
        return NULL;
    }
    {
        ast b = NULL, c = NULL, aCopy = NULL;
        int stepIsOptimizable = 1, isFirst = 1;
        long max, savedmax;
        while (LA==LBRACKET) {
            b = Recurse (Predicate);
            if (!b) return a;
            if (stepIsOptimizable) {
                if (!IsStepPatternPredOptimizable(b, &max)) 
                    stepIsOptimizable = 0;
            }







|







2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
    if (!a) {
        if (*errMsg == NULL) { ErrExpected("StepPattern") }; 
        return NULL;
    }
    {
        ast b = NULL, c = NULL, aCopy = NULL;
        int stepIsOptimizable = 1, isFirst = 1;
        domLength max, savedmax;
        while (LA==LBRACKET) {
            b = Recurse (Predicate);
            if (!b) return a;
            if (stepIsOptimizable) {
                if (!IsStepPatternPredOptimizable(b, &max)) 
                    stepIsOptimizable = 0;
            }
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
        newlen = strlen(xpath);
        *errMsg = (char*)REALLOC(*errMsg, len+newlen+10);
        memmove(*errMsg + len, " for '", 6);
        memmove(*errMsg + len+6, xpath, newlen);
        memmove(*errMsg + len+6+newlen, "' ", 3);

        for (i=0; tokens[i].token != EOS; i++) {
            sprintf(tmp, "%s\n%3s%3d %-12s %5ld %09.3g %5ld  ",
                         (i==0) ? "\n\nParsed symbols:" : "",
                         (i==l) ? "-->" : "   ",
                          i,
                         token2str[tokens[i].token-LPAR],
                         tokens[i].intvalue,
                         tokens[i].realvalue,
                         tokens[i].pos







|







2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
        newlen = strlen(xpath);
        *errMsg = (char*)REALLOC(*errMsg, len+newlen+10);
        memmove(*errMsg + len, " for '", 6);
        memmove(*errMsg + len+6, xpath, newlen);
        memmove(*errMsg + len+6+newlen, "' ", 3);

        for (i=0; tokens[i].token != EOS; i++) {
            sprintf(tmp, "%s\n%3s%3d %-12s %5" TCL_SIZE_MODIFIER "d %09.3g %5" TCL_SIZE_MODIFIER "d  ",
                         (i==0) ? "\n\nParsed symbols:" : "",
                         (i==l) ? "-->" : "   ",
                          i,
                         token2str[tokens[i].token-LPAR],
                         tokens[i].intvalue,
                         tokens[i].realvalue,
                         tokens[i].pos
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
{
    double d;
    char  *pc, *tailptr;

    *NaN = 0;
    switch (rs->type) {
        case BoolResult:   return (rs->intvalue? 1.0 : 0.0);
        case IntResult:    return rs->intvalue;
        case RealResult:   
            if (IS_NAN(rs->realvalue)) *NaN = 2;
            else if (IS_INF(rs->realvalue)!=0) *NaN = IS_INF(rs->realvalue);
            return rs->realvalue;
        case NaNResult:
            *NaN = 2;
            return 0.0;







|







2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
{
    double d;
    char  *pc, *tailptr;

    *NaN = 0;
    switch (rs->type) {
        case BoolResult:   return (rs->intvalue? 1.0 : 0.0);
    case IntResult:        return (double)rs->intvalue;
        case RealResult:   
            if (IS_NAN(rs->realvalue)) *NaN = 2;
            else if (IS_INF(rs->realvalue)!=0) *NaN = IS_INF(rs->realvalue);
            return rs->realvalue;
        case NaNResult:
            *NaN = 2;
            return 0.0;
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
    domLength    len;

    switch (rs->type) {
        case BoolResult:
            if (rs->intvalue) return (tdomstrdup("true"));
                         else return (tdomstrdup("false"));
        case IntResult:
            sprintf(tmp, "%ld", rs->intvalue);
            return (tdomstrdup(tmp));

        case RealResult:
            if (IS_NAN (rs->realvalue)) return tdomstrdup ("NaN");
            else if (IS_INF (rs->realvalue)) {
                if (IS_INF (rs->realvalue) == 1) return tdomstrdup ("Infinity");
                else                             return tdomstrdup ("-Infinity");







|







2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
    domLength    len;

    switch (rs->type) {
        case BoolResult:
            if (rs->intvalue) return (tdomstrdup("true"));
                         else return (tdomstrdup("false"));
        case IntResult:
            sprintf(tmp, "%" TCL_SIZE_MODIFIER "d", rs->intvalue);
            return (tdomstrdup(tmp));

        case RealResult:
            if (IS_NAN (rs->realvalue)) return tdomstrdup ("NaN");
            else if (IS_INF (rs->realvalue)) {
                if (IS_INF (rs->realvalue) == 1) return tdomstrdup ("Infinity");
                else                             return tdomstrdup ("-Infinity");
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
            if      (NaN == 2)  rsSetNaN (result);
            else if (NaN == 1)  rsSetInf (result);
            else                rsSetNInf (result);
        } else {
            if      (step->intvalue == f_floor)   leftReal = floor(leftReal);
            else if (step->intvalue == f_ceiling) leftReal = ceil(leftReal);
            else                                  leftReal = 
                                                      xpathRound(leftReal);
            rsSetReal2 (result, leftReal);
        }
        xpathRSFree( &leftResult );
        break;

    case f_boolean:
        XPATH_ARITYCHECK(step,1,errMsg);







|







3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
            if      (NaN == 2)  rsSetNaN (result);
            else if (NaN == 1)  rsSetInf (result);
            else                rsSetNInf (result);
        } else {
            if      (step->intvalue == f_floor)   leftReal = floor(leftReal);
            else if (step->intvalue == f_ceiling) leftReal = ceil(leftReal);
            else                                  leftReal = 
                                                      (double)xpathRound(leftReal);
            rsSetReal2 (result, leftReal);
        }
        xpathRSFree( &leftResult );
        break;

    case f_boolean:
        XPATH_ARITYCHECK(step,1,errMsg);
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
                    break;
                }
                ufStr++;
            }
            if (found) {
                if (j < len) {
                    unichar = Tcl_UniCharAtIndex (replaceStr, j);
                    utfCharLen = Tcl_UniCharToUtf (unichar, utfBuf);
                    Tcl_DStringAppend (&tresult, utfBuf, utfCharLen);
                }
            } else {
                utfCharLen = Tcl_UniCharToUtf (*upfrom, utfBuf);
                Tcl_DStringAppend (&tresult, utfBuf, utfCharLen);
            }
            upfrom++;
        }
        rsSetString (result, Tcl_DStringValue (&tresult));
        Tcl_DStringFree (&tstr);
        Tcl_DStringFree (&tfrom);







|



|







3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
                    break;
                }
                ufStr++;
            }
            if (found) {
                if (j < len) {
                    unichar = Tcl_UniCharAtIndex (replaceStr, j);
                    utfCharLen = (int)Tcl_UniCharToUtf (unichar, utfBuf);
                    Tcl_DStringAppend (&tresult, utfBuf, utfCharLen);
                }
            } else {
                utfCharLen = (int)Tcl_UniCharToUtf (*upfrom, utfBuf);
                Tcl_DStringAppend (&tresult, utfBuf, utfCharLen);
            }
            upfrom++;
        }
        rsSetString (result, Tcl_DStringValue (&tresult));
        Tcl_DStringFree (&tstr);
        Tcl_DStringFree (&tfrom);
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
    domNode   * node,
    char     ** xpath,
    domLength * xpathLen,
    domLength * xpathAllocated,
    int         legacy
)
{
    domNode *parent, *child;
    char    step[200], *nTest;
    size_t  len;
    int     sameNodes, nodeIndex;

    parent = node->parentNode;
    if (parent == NULL) {
        parent = node->ownerDocument->rootNode;
    } else {
        nodeToXPath (parent, xpath, xpathLen, xpathAllocated, legacy);
    }







|
|
|
|







5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
    domNode   * node,
    char     ** xpath,
    domLength * xpathLen,
    domLength * xpathAllocated,
    int         legacy
)
{
    domNode  *parent, *child;
    char      step[200], *nTest;
    domLength len;
    int       sameNodes, nodeIndex;

    parent = node->parentNode;
    if (parent == NULL) {
        parent = node->ownerDocument->rootNode;
    } else {
        nodeToXPath (parent, xpath, xpathLen, xpathAllocated, legacy);
    }
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
\---------------------------------------------------------------------------*/
char * xpathNodeToXPath (
    domNode *node,
    int      legacy
)
{
    char  * xpath;
    int     xpathLen, xpathAllocated;


    xpathAllocated = 100;
    xpathLen       = 0;
    xpath          = MALLOC(xpathAllocated + 1);

    nodeToXPath (node, &xpath, &xpathLen, &xpathAllocated, legacy);

    return xpath;

} /* xpathNodeToXPath */








|












5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
\---------------------------------------------------------------------------*/
char * xpathNodeToXPath (
    domNode *node,
    int      legacy
)
{
    char  * xpath;
    domLength xpathLen, xpathAllocated;


    xpathAllocated = 100;
    xpathLen       = 0;
    xpath          = MALLOC(xpathAllocated + 1);

    nodeToXPath (node, &xpath, &xpathLen, &xpathAllocated, legacy);

    return xpath;

} /* xpathNodeToXPath */

Changes to generic/domxpath.h.

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104


typedef struct astElem {
    astType         type;
    struct astElem *child;
    struct astElem *next;
    char           *strvalue;
    long            intvalue;
    double          realvalue;
} astElem;

typedef astElem *ast;


/*----------------------------------------------------------------------------







|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104


typedef struct astElem {
    astType         type;
    struct astElem *child;
    struct astElem *next;
    char           *strvalue;
    domLength       intvalue;
    double          realvalue;
} astElem;

typedef astElem *ast;


/*----------------------------------------------------------------------------
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
} xpathResultType;

typedef struct xpathResultSet {

    xpathResultType type;
    char           *string;
    domLength       string_len;
    long            intvalue;
    double          realvalue;          
    domNode       **nodes;
    domLength       nr_nodes;
    domLength       allocated;

} xpathResultSet;








|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
} xpathResultType;

typedef struct xpathResultSet {

    xpathResultType type;
    char           *string;
    domLength       string_len;
    domLength       intvalue;
    double          realvalue;          
    domNode       **nodes;
    domLength       nr_nodes;
    domLength       allocated;

} xpathResultSet;

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
226
227
228
229
230
231
232
233
char * xpathFuncStringForNode (domNode *node);
domLength xpathRound        (double r);

char * xpathGetStringValue (domNode *node, domLength *strLen);

char * xpathNodeToXPath  (domNode *node, int legacy);
    
void rsSetBool      ( xpathResultSet *rs, long         i    );
void rsSetLong      ( xpathResultSet *rs, long         i    );
void rsSetReal      ( xpathResultSet *rs, double       d    );
void rsSetReal2     ( xpathResultSet *rs, double       d    );
void rsSetString    ( xpathResultSet *rs, const char  *s    );
void rsAddNode      ( xpathResultSet *rs, domNode     *node );
void rsAddNodeFast  ( xpathResultSet *rs, domNode     *node );
void rsCopy         ( xpathResultSet *to, xpathResultSet *from );

/* This function is only used for debugging code */
void rsPrint        ( xpathResultSet *rs );

const char * xpathResultType2string (xpathResultType type);

/* This function is used (outside of tcldom.c) only by schema.c. It
 * has to have a prototype somewhere. */
int tcldom_xpathFuncCallBack (
    void            *clientData,
    char            *functionName,
    domNode         *ctxNode,
    int              position,
    xpathResultSet  *nodeList,
    domNode         *exprContext,
    int              argc,
    xpathResultSets *args,
    xpathResultSet  *result,
    char           **errMsg
    );

#endif








|
|


















|










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
226
227
228
229
230
231
232
233
char * xpathFuncStringForNode (domNode *node);
domLength xpathRound        (double r);

char * xpathGetStringValue (domNode *node, domLength *strLen);

char * xpathNodeToXPath  (domNode *node, int legacy);
    
void rsSetBool      ( xpathResultSet *rs, domLength    i    );
void rsSetLong      ( xpathResultSet *rs, domLength    i    );
void rsSetReal      ( xpathResultSet *rs, double       d    );
void rsSetReal2     ( xpathResultSet *rs, double       d    );
void rsSetString    ( xpathResultSet *rs, const char  *s    );
void rsAddNode      ( xpathResultSet *rs, domNode     *node );
void rsAddNodeFast  ( xpathResultSet *rs, domNode     *node );
void rsCopy         ( xpathResultSet *to, xpathResultSet *from );

/* This function is only used for debugging code */
void rsPrint        ( xpathResultSet *rs );

const char * xpathResultType2string (xpathResultType type);

/* This function is used (outside of tcldom.c) only by schema.c. It
 * has to have a prototype somewhere. */
int tcldom_xpathFuncCallBack (
    void            *clientData,
    char            *functionName,
    domNode         *ctxNode,
    domLength       position,
    xpathResultSet  *nodeList,
    domNode         *exprContext,
    int              argc,
    xpathResultSets *args,
    xpathResultSet  *result,
    char           **errMsg
    );

#endif

Changes to generic/domxslt.c.

924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
    domLength         value,
    Tcl_DString      *str,
    char             *groupingSeparator,
    long              groupingSize,
    int               addSeparater
)
{
    size_t      len, fulllen, gslen, m, i;
    int         upper = 0, e, b, z, v;
    char        tmp[80], *pt;
    Tcl_DString tmp1;
    static struct { char *digit; char *ldigit; int value; } RomanDigit[] = {
          { "M" , "m" , 1000, },
          { "CM", "cm",  900, },
          { "D" , "d" ,  500, },
          { "CD", "cd",  400, },
          { "C" , "c" ,  100, },
          { "XC", "xc",   90, },
          { "L" , "l" ,   50, },
          { "XL", "xl",   40, },
          { "X" , "x" ,   10, },
          { "IX", "ix",    9, },
          { "V" , "v" ,    5, },
          { "IV", "iv",    4, },
          { "I" , "i" ,    1  }
    };

    switch (f->tokens[*useFormatToken].type) {
    case latin_number:
        sprintf (tmp, "%d", value);
        fulllen = len = strlen (tmp);
        if (f->tokens[*useFormatToken].minlength > fulllen) {
            fulllen = f->tokens[*useFormatToken].minlength;
        }
        if (groupingSeparator) {
            gslen = strlen (groupingSeparator);
            Tcl_DStringInit (&tmp1);







|
|




















|







924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
    domLength         value,
    Tcl_DString      *str,
    char             *groupingSeparator,
    long              groupingSize,
    int               addSeparater
)
{
    domLength   len, fulllen, gslen, m, i;
    int         upper = 0, e, b, v, z;
    char        tmp[80], *pt;
    Tcl_DString tmp1;
    static struct { char *digit; char *ldigit; int value; } RomanDigit[] = {
          { "M" , "m" , 1000, },
          { "CM", "cm",  900, },
          { "D" , "d" ,  500, },
          { "CD", "cd",  400, },
          { "C" , "c" ,  100, },
          { "XC", "xc",   90, },
          { "L" , "l" ,   50, },
          { "XL", "xl",   40, },
          { "X" , "x" ,   10, },
          { "IX", "ix",    9, },
          { "V" , "v" ,    5, },
          { "IV", "iv",    4, },
          { "I" , "i" ,    1  }
    };

    switch (f->tokens[*useFormatToken].type) {
    case latin_number:
        sprintf (tmp, "%" TCL_SIZE_MODIFIER "d", value);
        fulllen = len = strlen (tmp);
        if (f->tokens[*useFormatToken].minlength > fulllen) {
            fulllen = f->tokens[*useFormatToken].minlength;
        }
        if (groupingSeparator) {
            gslen = strlen (groupingSeparator);
            Tcl_DStringInit (&tmp1);
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
           faster / more clever. */

        if (value <= 0) {
            /* Hm, zero can't be expressed with letter sequences...
               What to do? One of the several cases, not mentioned
               by the spec. */
            /* fall back to latin numbers */
            sprintf (tmp, "%d", value);
            break;
        }
        e = 1;
        m = b = 26;
        while (value > m) {
            b *= 26;
            m += b;
            e++;
        }
        m -= b;
        value -= m;
        for (i = 0; i < e; i++) {
            b /= 26;
            z = value / b;
            value = value - z*b;
            if (i < e -1) {
                if (value == 0) {
                    value += b;
                } else {
                    z++;
                }







|













|







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
           faster / more clever. */

        if (value <= 0) {
            /* Hm, zero can't be expressed with letter sequences...
               What to do? One of the several cases, not mentioned
               by the spec. */
            /* fall back to latin numbers */
            sprintf (tmp, "%" TCL_SIZE_MODIFIER "d", value);
            break;
        }
        e = 1;
        m = b = 26;
        while (value > m) {
            b *= 26;
            m += b;
            e++;
        }
        m -= b;
        value -= m;
        for (i = 0; i < e; i++) {
            b /= 26;
            z = (int)(value / b);
            value = value - z*b;
            if (i < e -1) {
                if (value == 0) {
                    value += b;
                } else {
                    z++;
                }
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078

        /* Side note: There exists a rarely used roman notation
           to express figures up to a few millions. Does somebody
           really need this? */

        if (value > 3999 || value <= 0) {
            /* fall back to latin numbers */
            sprintf (tmp, "%d", value);
            break;
        }
        if (value == 0) {
            /* what to do with zero??? */
            sprintf (tmp, "%d", 0);
            break;
        }
        v = 0;  tmp[0] = '\0';
        while (value > 0) {
            while (value >= RomanDigit[v].value) {
                if (upper) { strcat(tmp,  RomanDigit[v].digit);  }
                      else { strcat(tmp,  RomanDigit[v].ldigit); }
                value -= RomanDigit[v].value;
            }
            v++;
        }
        break;

    default:
        sprintf (tmp, "%d", value);
        break;
    }
    len = strlen (tmp);
    Tcl_DStringAppend (str, tmp, len);
 appendSeperator:
    if (addSeparater) {
        if (f->tokens[*useFormatToken].sepStart) {







|



















|







1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078

        /* Side note: There exists a rarely used roman notation
           to express figures up to a few millions. Does somebody
           really need this? */

        if (value > 3999 || value <= 0) {
            /* fall back to latin numbers */
            sprintf (tmp, "%" TCL_SIZE_MODIFIER "d", value);
            break;
        }
        if (value == 0) {
            /* what to do with zero??? */
            sprintf (tmp, "%d", 0);
            break;
        }
        v = 0;  tmp[0] = '\0';
        while (value > 0) {
            while (value >= RomanDigit[v].value) {
                if (upper) { strcat(tmp,  RomanDigit[v].digit);  }
                      else { strcat(tmp,  RomanDigit[v].ldigit); }
                value -= RomanDigit[v].value;
            }
            v++;
        }
        break;

    default:
        sprintf (tmp, "%" TCL_SIZE_MODIFIER "d", value);
        break;
    }
    len = strlen (tmp);
    Tcl_DStringAppend (str, tmp, len);
 appendSeperator:
    if (addSeparater) {
        if (f->tokens[*useFormatToken].sepStart) {
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
|   xsltXPathFuncs
|
\---------------------------------------------------------------------------*/
static int xsltXPathFuncs (
    void            * clientData,
    char            * funcName,
    domNode         * ctxNode,
    int               ctxPos,
    xpathResultSet  * ctx,
    domNode         * exprContext,
    int               argc,
    xpathResultSets * argv,
    xpathResultSet  * result,
    char           ** errMsg
)







|







1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
|   xsltXPathFuncs
|
\---------------------------------------------------------------------------*/
static int xsltXPathFuncs (
    void            * clientData,
    char            * funcName,
    domNode         * ctxNode,
    domLength         ctxPos,
    xpathResultSet  * ctx,
    domNode         * exprContext,
    int               argc,
    xpathResultSets * argv,
    xpathResultSet  * result,
    char           ** errMsg
)

Changes to generic/schema.c.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
|
|   written by Rolf Ade
|   2018-2022
|
\---------------------------------------------------------------------------*/

#include <tdom.h>
#include <tcldom.h>
#include <domxpath.h>
#include <domjson.h>
#include <schema.h>
#include <datatypes.h>

#ifndef TDOM_NO_SCHEMA







|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
|
|   written by Rolf Ade
|   2018-2022
|
\---------------------------------------------------------------------------*/

#include <dom.h>
#include <tcldom.h>
#include <domxpath.h>
#include <domjson.h>
#include <schema.h>
#include <datatypes.h>

#ifndef TDOM_NO_SCHEMA
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
    XML_SetBase (extparser, extbase);

    Tcl_ResetResult (vdata->interp);
    result = 1;
    if (chan == NULL) {
        do {
            done = (len < PARSE_CHUNK_SIZE);
            status = XML_Parse (extparser, xmlstring, done ? len : PARSE_CHUNK_SIZE,
                                done);
            if (!done) {
                xmlstring += PARSE_CHUNK_SIZE;
                len -= PARSE_CHUNK_SIZE;
            }
        }  while (!done && status == XML_STATUS_OK);
        switch (status) {
        case XML_STATUS_ERROR:







|
|







4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
    XML_SetBase (extparser, extbase);

    Tcl_ResetResult (vdata->interp);
    result = 1;
    if (chan == NULL) {
        do {
            done = (len < PARSE_CHUNK_SIZE);
            status = XML_Parse (extparser, xmlstring,
                                (int)(done ? len : PARSE_CHUNK_SIZE), done);
            if (!done) {
                xmlstring += PARSE_CHUNK_SIZE;
                len -= PARSE_CHUNK_SIZE;
            }
        }  while (!done && status == XML_STATUS_OK);
        switch (status) {
        case XML_STATUS_ERROR:
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
        default:
            break;
        }
    } else {
        do {
            len = Tcl_Read (chan, buf, sizeof(buf));
            done = len < sizeof(buf);
            status = XML_Parse (extparser, buf, len, done);
            switch (status) {
            case XML_STATUS_ERROR:
                interpResult = Tcl_GetStringResult(vdata->interp);
                sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));
                if (interpResult[0] == '\0') {
                    Tcl_ResetResult (vdata->interp);
                    Tcl_AppendResult(vdata->interp, "error \"",







|







4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
        default:
            break;
        }
    } else {
        do {
            len = Tcl_Read (chan, buf, sizeof(buf));
            done = len < sizeof(buf);
            status = XML_Parse (extparser, buf, (int)len, done);
            switch (status) {
            case XML_STATUS_ERROR:
                interpResult = Tcl_GetStringResult(vdata->interp);
                sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));
                if (interpResult[0] == '\0') {
                    Tcl_ResetResult (vdata->interp);
                    Tcl_AppendResult(vdata->interp, "error \"",
5014
5015
5016
5017
5018
5019
5020
5021

5022
5023
5024
5025
5026
5027
5028

    switch (source) {
    case VALIDATE_STRING:
        xmlstr = Tcl_GetStringFromObj (objv[0], &len);
        result = TCL_OK;
        do {
            done = (len < PARSE_CHUNK_SIZE);
            if (XML_Parse (parser, xmlstr, done ? len : PARSE_CHUNK_SIZE, done)

                != XML_STATUS_OK
                || sdata->validationState == VALIDATION_ERROR) {
                validateReportError (interp, sdata, parser);
                result = TCL_ERROR;
                break;
            }
            if (!done) {







|
>







5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029

    switch (source) {
    case VALIDATE_STRING:
        xmlstr = Tcl_GetStringFromObj (objv[0], &len);
        result = TCL_OK;
        do {
            done = (len < PARSE_CHUNK_SIZE);
            if (XML_Parse (parser, xmlstr,
                           (int)(done ? len : PARSE_CHUNK_SIZE), done)
                != XML_STATUS_OK
                || sdata->validationState == VALIDATION_ERROR) {
                validateReportError (interp, sdata, parser);
                result = TCL_ERROR;
                break;
            }
            if (!done) {
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
                close (fd);
                Tcl_ResetResult (interp);
                Tcl_AppendResult (interp, "error reading from file \"",
                                  filename, "\"", (char *) NULL);
                result = TCL_ERROR;
                goto cleanup;
            }
            result = XML_ParseBuffer (parser, nread, nread == 0);
            if (result != XML_STATUS_OK || !nread
                || sdata->validationState == VALIDATION_ERROR) {
                close (fd);
                break;
            }
        }
        if (result != XML_STATUS_OK







|







5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
                close (fd);
                Tcl_ResetResult (interp);
                Tcl_AppendResult (interp, "error reading from file \"",
                                  filename, "\"", (char *) NULL);
                result = TCL_ERROR;
                goto cleanup;
            }
            result = XML_ParseBuffer (parser, (int)nread, nread == 0);
            if (result != XML_STATUS_OK || !nread
                || sdata->validationState == VALIDATION_ERROR) {
                close (fd);
                break;
            }
        }
        if (result != XML_STATUS_OK
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
        bufObj = Tcl_NewObj();
        Tcl_SetObjLength (bufObj, 6144);
        result = TCL_OK;
        do {
            len = Tcl_ReadChars (channel, bufObj, 1024, 0);
            done = (len < 1024);
            str = Tcl_GetStringFromObj(bufObj, &tclLen);
            rc = XML_Parse (parser, str, tclLen, done);
            if (rc != XML_STATUS_OK 
                || sdata->validationState == VALIDATION_ERROR) {
                validateReportError (interp, sdata, parser);
                result = TCL_ERROR;
                break;
            }
        } while (!done);







|







5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
        bufObj = Tcl_NewObj();
        Tcl_SetObjLength (bufObj, 6144);
        result = TCL_OK;
        do {
            len = Tcl_ReadChars (channel, bufObj, 1024, 0);
            done = (len < 1024);
            str = Tcl_GetStringFromObj(bufObj, &tclLen);
            rc = XML_Parse (parser, str, (int)tclLen, done);
            if (rc != XML_STATUS_OK 
                || sdata->validationState == VALIDATION_ERROR) {
                validateReportError (interp, sdata, parser);
                result = TCL_ERROR;
                break;
            }
        } while (!done);

Changes to generic/tcldom.c.

1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
|   tcldom_xpathFuncCallBack
|
\---------------------------------------------------------------------------*/
int tcldom_xpathFuncCallBack (
    void            *clientData,
    char            *functionName,
    domNode         *ctxNode,
    int              position,
    xpathResultSet  *nodeList,
    domNode         *UNUSED(exprContext),
    int              argc,
    xpathResultSets *args,
    xpathResultSet  *result,
    char           **errMsg
)







|







1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
|   tcldom_xpathFuncCallBack
|
\---------------------------------------------------------------------------*/
int tcldom_xpathFuncCallBack (
    void            *clientData,
    char            *functionName,
    domNode         *ctxNode,
    domLength        position,
    xpathResultSet  *nodeList,
    domNode         *UNUSED(exprContext),
    int              argc,
    xpathResultSets *args,
    xpathResultSet  *result,
    char           **errMsg
)

Changes to generic/tcldom.h.

46
47
48
49
50
51
52


53
54
55
56
57
58
59
int  tcldom_PINameCheck(Tcl_Interp *interp, char *name);
int  tcldom_nameCheck(Tcl_Interp *interp, char *name, char *nameType,
                      int isFQName);
void tcldom_createNodeObj(Tcl_Interp * interp, domNode *node,
                          char *objCmdName);

domNode * tcldom_getNodeFromObj(Tcl_Interp  *interp, Tcl_Obj *nodeObj);


int tcldom_prefixNSlist (char ***prefixnsPtr, Tcl_Interp *interp, int objc,
                         Tcl_Obj *const objv[], const char *methodName);
int tcldom_setInterpAndReturnVar (Tcl_Interp *interp, domNode *node,
                                  int setVariable, Tcl_Obj *var_name);

void tcldom_initialize(void);
void tcldom_deleteDoc (Tcl_Interp *interp, domDocument *doc);







>
>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
int  tcldom_PINameCheck(Tcl_Interp *interp, char *name);
int  tcldom_nameCheck(Tcl_Interp *interp, char *name, char *nameType,
                      int isFQName);
void tcldom_createNodeObj(Tcl_Interp * interp, domNode *node,
                          char *objCmdName);

domNode * tcldom_getNodeFromObj(Tcl_Interp  *interp, Tcl_Obj *nodeObj);
domDocument * tcldom_getDocumentFromName(Tcl_Interp *interp,
				char *docName, char **errMsg);
int tcldom_prefixNSlist (char ***prefixnsPtr, Tcl_Interp *interp, int objc,
                         Tcl_Obj *const objv[], const char *methodName);
int tcldom_setInterpAndReturnVar (Tcl_Interp *interp, domNode *node,
                                  int setVariable, Tcl_Obj *var_name);

void tcldom_initialize(void);
void tcldom_deleteDoc (Tcl_Interp *interp, domDocument *doc);

Changes to generic/tclexpat.c.

972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
    Tcl_Interp *interp,
    TclGenExpatInfo *expat,
    char *data,
    domLength len,
    TclExpat_InputType type
) {
  int result, mode, done;
  domLength strlen;
  size_t bytesread;
  char s[255], buf[8*1024];
  int fd;
  XML_Parser  parser;
  Tcl_Channel channel = NULL;
  CHandlerSet *activeCHandlerSet;
  Tcl_Obj       *bufObj = NULL;
  Tcl_DString    dStr;







|
<







972
973
974
975
976
977
978
979

980
981
982
983
984
985
986
    Tcl_Interp *interp,
    TclGenExpatInfo *expat,
    char *data,
    domLength len,
    TclExpat_InputType type
) {
  int result, mode, done;
  domLength strlen, bytesread;

  char s[255], buf[8*1024];
  int fd;
  XML_Parser  parser;
  Tcl_Channel channel = NULL;
  CHandlerSet *activeCHandlerSet;
  Tcl_Obj       *bufObj = NULL;
  Tcl_DString    dStr;
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
  result = 1;
  switch (type) {

  case EXPAT_INPUT_STRING:
      expat->parsingState = 2;
      do {
          done = (len < PARSE_CHUNK_SIZE);
          result = XML_Parse(expat->parser, data, len,
                             done ? expat->final : 0);
          if (!done) {
              data += PARSE_CHUNK_SIZE;
              len -= PARSE_CHUNK_SIZE;
          }
      } while (!done && result == XML_STATUS_OK);
      expat->parsingState = 1;







|







1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
  result = 1;
  switch (type) {

  case EXPAT_INPUT_STRING:
      expat->parsingState = 2;
      do {
          done = (len < PARSE_CHUNK_SIZE);
          result = XML_Parse(expat->parser, data, (int)len,
                             done ? expat->final : 0);
          if (!done) {
              data += PARSE_CHUNK_SIZE;
              len -= PARSE_CHUNK_SIZE;
          }
      } while (!done && result == XML_STATUS_OK);
      expat->parsingState = 1;
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
      else useBinary = 0;
      Tcl_DStringFree (&dStr);
      expat->parsingState = 2;
      if (useBinary) {
          do {
              bytesread = Tcl_Read (channel, buf, sizeof (buf));
              done = bytesread < sizeof (buf);
              result = XML_Parse (expat->parser, buf, bytesread, done);
              if (result != XML_STATUS_OK) break;
          } while (!done);
      } else {
          bufObj = Tcl_NewObj();
          Tcl_IncrRefCount (bufObj);
          Tcl_SetObjLength (bufObj, 6144);
          do {
              len = Tcl_ReadChars (channel, bufObj, 1024, 0);
              done = (len < 1024);
              str = Tcl_GetStringFromObj (bufObj, &strlen);
              result = XML_Parse (expat->parser, str, strlen, done);
              if (result != XML_STATUS_OK) break;
          } while (!done);
          /* In case of a parsing error we need the string rep of the
             bufObj until the error reporting is done (otherwise,
             calling XML_GetCurrentLineNumber() results in invalid mem
             reads */
          if (result) {







|










|







1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
      else useBinary = 0;
      Tcl_DStringFree (&dStr);
      expat->parsingState = 2;
      if (useBinary) {
          do {
              bytesread = Tcl_Read (channel, buf, sizeof (buf));
              done = bytesread < sizeof (buf);
              result = XML_Parse (expat->parser, buf, (int)bytesread, done);
              if (result != XML_STATUS_OK) break;
          } while (!done);
      } else {
          bufObj = Tcl_NewObj();
          Tcl_IncrRefCount (bufObj);
          Tcl_SetObjLength (bufObj, 6144);
          do {
              len = Tcl_ReadChars (channel, bufObj, 1024, 0);
              done = (len < 1024);
              str = Tcl_GetStringFromObj (bufObj, &strlen);
              result = XML_Parse (expat->parser, str, (int)strlen, done);
              if (result != XML_STATUS_OK) break;
          } while (!done);
          /* In case of a parsing error we need the string rep of the
             bufObj until the error reporting is done (otherwise,
             calling XML_GetCurrentLineNumber() results in invalid mem
             reads */
          if (result) {
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
              close (fd);
              Tcl_ResetResult (interp);
              Tcl_AppendResult (interp, "error reading from file \"",
                                data, "\"", (char *) NULL);
              expat->parsingState = 1;
              return TCL_ERROR;
          }
          result = XML_ParseBuffer (parser, nread, nread == 0);
          if (result != XML_STATUS_OK || !nread) {
              close (fd);
              break;
          }
      }
      expat->parsingState = 1;
      break;







|







1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
              close (fd);
              Tcl_ResetResult (interp);
              Tcl_AppendResult (interp, "error reading from file \"",
                                data, "\"", (char *) NULL);
              expat->parsingState = 1;
              return TCL_ERROR;
          }
          result = XML_ParseBuffer (parser, (int)nread, nread == 0);
          if (result != XML_STATUS_OK || !nread) {
              close (fd);
              break;
          }
      }
      expat->parsingState = 1;
      break;
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
      EXPAT_PARAMENTITYPARSINGALWAYS,
      EXPAT_PARAMENTITYPARSINGNEVER,
      EXPAT_PARAMENTITYPARSINGNOTSTANDALONE
  };
  int optionIndex, value, bool;
  Tcl_Obj *const *objPtr = objv;
  Tcl_CmdInfo cmdInfo;
  int rc, len;

  char *handlerSetName = NULL;
  TclHandlerSet *tmpTclHandlerSet, *activeTclHandlerSet = NULL;
  Tcl_UniChar uniChar;
  double maximumAmplification;
  long activationThreshold;
#ifndef TDOM_NO_SCHEMA
  char *schemacmd;







|
>







1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
      EXPAT_PARAMENTITYPARSINGALWAYS,
      EXPAT_PARAMENTITYPARSINGNEVER,
      EXPAT_PARAMENTITYPARSINGNOTSTANDALONE
  };
  int optionIndex, value, bool;
  Tcl_Obj *const *objPtr = objv;
  Tcl_CmdInfo cmdInfo;
  int rc;
  domLength len;
  char *handlerSetName = NULL;
  TclHandlerSet *tmpTclHandlerSet, *activeTclHandlerSet = NULL;
  Tcl_UniChar uniChar;
  double maximumAmplification;
  long activationThreshold;
#ifndef TDOM_NO_SCHEMA
  char *schemacmd;
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
        SetIntResult (interp, expat->ns_mode);
        return TCL_OK;

      case EXPAT_NAMESPACESEPARATOR: /* -namespaceseparator */

        if (expat->nsSeparator) {
            uniChar = expat->nsSeparator;
            len = Tcl_UniCharToUtf (uniChar, utfBuf);
            Tcl_DStringInit (&dStr);
            Tcl_DStringAppend (&dStr, utfBuf, len);
            Tcl_DStringResult (interp, &dStr);
            Tcl_DStringFree (&dStr);
        }
        return TCL_OK;








|







2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
        SetIntResult (interp, expat->ns_mode);
        return TCL_OK;

      case EXPAT_NAMESPACESEPARATOR: /* -namespaceseparator */

        if (expat->nsSeparator) {
            uniChar = expat->nsSeparator;
            len = (int) Tcl_UniCharToUtf (uniChar, utfBuf);
            Tcl_DStringInit (&dStr);
            Tcl_DStringAppend (&dStr, utfBuf, len);
            Tcl_DStringResult (interp, &dStr);
            Tcl_DStringFree (&dStr);
        }
        return TCL_OK;

3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
      }

      dataStr = Tcl_GetStringFromObj (dataObj, &tclLen);
      switch (inputType) {
      case EXPAT_INPUT_STRING:
          do {
              done = (tclLen < PARSE_CHUNK_SIZE);
              result = XML_Parse(extparser, dataStr, tclLen, done);
              if (!done) {
                  dataStr += PARSE_CHUNK_SIZE;
                  tclLen -= PARSE_CHUNK_SIZE;
              }
          } while (!done && result == XML_STATUS_OK);
          break;








|







3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
      }

      dataStr = Tcl_GetStringFromObj (dataObj, &tclLen);
      switch (inputType) {
      case EXPAT_INPUT_STRING:
          do {
              done = (tclLen < PARSE_CHUNK_SIZE);
              result = XML_Parse(extparser, dataStr, (int)tclLen, done);
              if (!done) {
                  dataStr += PARSE_CHUNK_SIZE;
                  tclLen -= PARSE_CHUNK_SIZE;
              }
          } while (!done && result == XML_STATUS_OK);
          break;

3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
              expat->parser = oldparser;
              return 0;
          }
          result = 1;
          do {
              len = Tcl_Read (chan, buf, sizeof (buf));
              done = len < sizeof (buf);
              result = XML_Parse (extparser, buf, len, done);
              if (result != XML_STATUS_OK) break;
          } while (!done);
          Tcl_UnregisterChannel (expat->interp, chan);
          break;

      case EXPAT_INPUT_FILENAME:
          fd = open(dataStr, O_BINARY|O_RDONLY);







|







3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
              expat->parser = oldparser;
              return 0;
          }
          result = 1;
          do {
              len = Tcl_Read (chan, buf, sizeof (buf));
              done = len < sizeof (buf);
              result = XML_Parse (extparser, buf, (int)len, done);
              if (result != XML_STATUS_OK) break;
          } while (!done);
          Tcl_UnregisterChannel (expat->interp, chan);
          break;

      case EXPAT_INPUT_FILENAME:
          fd = open(dataStr, O_BINARY|O_RDONLY);
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
                  Tcl_AppendResult (expat->interp,
                                    "error reading from file \"",
                                    dataStr, "\"", (char *) NULL);
                  TclExpatHandlerResult (expat, activeTclHandlerSet,
                                         ERROR_IN_EXTREFHANDLER);
                  return 0;
              }
              result = XML_ParseBuffer (extparser, nread, nread == 0);
              if (result != XML_STATUS_OK || !nread) {
                  close (fd);
                  break;
              }
          }
          break;
      }







|







3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
                  Tcl_AppendResult (expat->interp,
                                    "error reading from file \"",
                                    dataStr, "\"", (char *) NULL);
                  TclExpatHandlerResult (expat, activeTclHandlerSet,
                                         ERROR_IN_EXTREFHANDLER);
                  return 0;
              }
              result = XML_ParseBuffer (extparser, (int)nread, nread == 0);
              if (result != XML_STATUS_OK || !nread) {
                  close (fd);
                  break;
              }
          }
          break;
      }

Changes to generic/tclpull.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|   written by Rolf Ade
|   February 2018
|
\---------------------------------------------------------------------------*/

#ifndef TDOM_NO_PULL

#include <tdom.h>
#include <fcntl.h>
#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#endif








|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|   written by Rolf Ade
|   February 2018
|
\---------------------------------------------------------------------------*/

#ifndef TDOM_NO_PULL

#include <dom.h>
#include <fcntl.h>
#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#endif

431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
                                     pullInfo->channelReadBuf,
                                     1024, 0);
                done = (len < 1024);
                data = Tcl_GetStringFromObj (
                    pullInfo->channelReadBuf, &len
                    );
                result = XML_Parse (pullInfo->parser, data,
                                    len, done);
            } while (result == XML_STATUS_OK && !done);
        } else {
            /* inputfile */
            do {
                char *fbuf = 
                    XML_GetBuffer (pullInfo->parser,
                                   TDOM_EXPAT_READ_SIZE);
                len = read (pullInfo->inputfd, fbuf,
                            TDOM_EXPAT_READ_SIZE);
                done = (len < TDOM_EXPAT_READ_SIZE);
                result = XML_ParseBuffer (pullInfo->parser,
                                          len, done);
            } while (result == XML_STATUS_OK && !done);
        }
        if (result == XML_STATUS_ERROR) {
            tDOM_CleanupInputSource (pullInfo);
            tDOM_ReportXMLError (interp, pullInfo);
            pullInfo->state = PULLPARSERSTATE_PARSE_ERROR;
            return TCL_ERROR;







|











|







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
                                     pullInfo->channelReadBuf,
                                     1024, 0);
                done = (len < 1024);
                data = Tcl_GetStringFromObj (
                    pullInfo->channelReadBuf, &len
                    );
                result = XML_Parse (pullInfo->parser, data,
                                    (int)len, done);
            } while (result == XML_STATUS_OK && !done);
        } else {
            /* inputfile */
            do {
                char *fbuf = 
                    XML_GetBuffer (pullInfo->parser,
                                   TDOM_EXPAT_READ_SIZE);
                len = read (pullInfo->inputfd, fbuf,
                            TDOM_EXPAT_READ_SIZE);
                done = (len < TDOM_EXPAT_READ_SIZE);
                result = XML_ParseBuffer (pullInfo->parser,
                                          (int)len, done);
            } while (result == XML_STATUS_OK && !done);
        }
        if (result == XML_STATUS_ERROR) {
            tDOM_CleanupInputSource (pullInfo);
            tDOM_ReportXMLError (interp, pullInfo);
            pullInfo->state = PULLPARSERSTATE_PARSE_ERROR;
            return TCL_ERROR;
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647

648
649
650
651
652
653
654
                    do {
                        char *fbuf =
                            XML_GetBuffer (pullInfo->parser,
                                           TDOM_EXPAT_READ_SIZE);
                        len = read(pullInfo->inputfd, fbuf,
                                   TDOM_EXPAT_READ_SIZE);
                        result = XML_ParseBuffer (pullInfo->parser,
                                                  len, len == 0);
                    } while (result == XML_STATUS_OK);
                } else if (pullInfo->inputChannel) {
                    do {
                        len = Tcl_ReadChars (pullInfo->inputChannel,
                                             pullInfo->channelReadBuf,
                                             1024, 0);
                        data = Tcl_GetString (pullInfo->channelReadBuf);
                        result = XML_Parse (pullInfo->parser, data, len,
                                            len == 0);
                    } while (result == XML_STATUS_OK);
                } else {
                    data = Tcl_GetStringFromObj(pullInfo->inputString, &len);
                    do {
                        done = (len < PARSE_CHUNK_SIZE);
                        result = XML_Parse (pullInfo->parser, data, len, done);

                        if (!done) {
                            data += PARSE_CHUNK_SIZE;
                            len -= PARSE_CHUNK_SIZE;
                        }
                    } while (!done && result == XML_STATUS_OK);
                }
                switch (result) {







|







|






|
>







625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
                    do {
                        char *fbuf =
                            XML_GetBuffer (pullInfo->parser,
                                           TDOM_EXPAT_READ_SIZE);
                        len = read(pullInfo->inputfd, fbuf,
                                   TDOM_EXPAT_READ_SIZE);
                        result = XML_ParseBuffer (pullInfo->parser,
                                                  (int)len, len == 0);
                    } while (result == XML_STATUS_OK);
                } else if (pullInfo->inputChannel) {
                    do {
                        len = Tcl_ReadChars (pullInfo->inputChannel,
                                             pullInfo->channelReadBuf,
                                             1024, 0);
                        data = Tcl_GetString (pullInfo->channelReadBuf);
                        result = XML_Parse (pullInfo->parser, data, (int)len,
                                            len == 0);
                    } while (result == XML_STATUS_OK);
                } else {
                    data = Tcl_GetStringFromObj(pullInfo->inputString, &len);
                    do {
                        done = (len < PARSE_CHUNK_SIZE);
                        result = XML_Parse (pullInfo->parser, data, (int)len,
                                            done);
                        if (!done) {
                            data += PARSE_CHUNK_SIZE;
                            len -= PARSE_CHUNK_SIZE;
                        }
                    } while (!done && result == XML_STATUS_OK);
                }
                switch (result) {