Diff
Not logged in

Differences From Artifact [73e1a9bb8b]:

To Artifact [91d7ab8dba]:


672
673
674
675
676
677
678
679
680
681
682


683
684
685
686
687
688
689
690
691
692
693
694
695
696
697


698
699
700

701
702
703
704
705



706

707


708
709
710
711
712

713
714


715
716
717
718
719
720
721
722
723
724
725
726
727

CONST char *
Tcl_UtfPrev(
    CONST char *src,		/* The current location in the string. */
    CONST char *start)		/* Pointer to the beginning of the string, to
				 * avoid going backwards too far. */
{
    static unsigned char maxLead = (TCL_UTF_MAX == 3) ? 0xEF : 0xF7;
    static unsigned char leads[6] = {0xC0, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8};
    int limit,n = 0;
    CONST char *look = src - 1;



    if (look <= start) {
	return start;
    }

    limit = ((src - start) < TCL_UTF_MAX) ? (src - start) : TCL_UTF_MAX;

    do {
	unsigned char byte = *((unsigned char *) look);

	if (byte < 0x80) {
	    /* An 7-bit ASCII byte followed by n trail bytes indicates the
	     * last trail byte was the answer. */
	    return src - 1;
	}


	if (byte > maxLead) {
	    /* A byte value too large to be a valid lead byte indicates the
	     * last trail byte was the answer */

	   return src - 1;
	}
	if (byte >= leads[n++]) {
	    /* A lead byte that can accept up to n trail bytes becomes
	     * the answer. */



	    return look;

	}


	if (byte >= 0xC0) {
	    /* A lead byte that cannot accept n trail bytes indicates
	     * the last trail byte the answer. */
	    return src - 1;
	}


	/* We saw a trail byte; keep scanning. */


	look--;
    } while (n < limit);

    /* We saw nothing but trail bytes until the limit was reached.
     * Indicates the last trail byte is the answer. */
    return src - 1;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UniCharAtIndex --
 *







<
<
<

>
>

|


|
<
<
<
|
<
<
<
<
|
|
>
>
|
<
<
>
|

|
<
<
>
>
>
|
>

>
>
|
<
<
|

>
|
<
>
>
|
<
|
<
<
|







672
673
674
675
676
677
678



679
680
681
682
683
684
685
686



687




688
689
690
691
692


693
694
695
696


697
698
699
700
701
702
703
704
705


706
707
708
709

710
711
712

713


714
715
716
717
718
719
720
721

CONST char *
Tcl_UtfPrev(
    CONST char *src,		/* The current location in the string. */
    CONST char *start)		/* Pointer to the beginning of the string, to
				 * avoid going backwards too far. */
{



    CONST char *look = src - 1;
    int i, o, known = 0;
    Tcl_UniChar ch;

    if (src <= start) {
	return start;
    }
    /* simplest case - ascii char */



    if (*((unsigned char *) look) < 0x80) {




	return look;
    }
    /* navigate up to max return value of Tcl_UtfToUniChar */
    for (i = 1; i <= 4; i++) {
	if (look < start) {


	    look = start;
	    break;
	}
	if (*((unsigned char *) look) < 0x80) {


	    /* traversing back reaches ascii - either known mark points to char,
	     * or unexpected case with invalid utf-8 or unsupported surrogate 
	     * starting from next char, so goto next char and stop search: */
	    look++;
	    break;
	}
	o = Tcl_UtfToUniChar(look, &ch);
	/* if we are reached start of some char, mark as known and try further */
	if (o >= i) {


	    known = i;
	}
	look--;
    }

    /* use best (marked as known) char position, or current found if unknown: */
    if (known) {
	look = src - known;

    }


    return look;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UniCharAtIndex --
 *