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
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. */
{
    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;
    int i, o, known = 0;
    Tcl_UniChar ch;

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

    /* simplest case - ascii char */
    limit = ((src - start) < TCL_UTF_MAX) ? (src - start) : TCL_UTF_MAX;

    do {
	unsigned char byte = *((unsigned char *) look);
    if (*((unsigned char *) look) < 0x80) {

	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) {
	return look;
    }
    /* navigate up to max return value of Tcl_UtfToUniChar */
    for (i = 1; i <= 4; i++) {
	if (look < start) {
	    /* A byte value too large to be a valid lead byte indicates the
	     * last trail byte was the answer */
	   return src - 1;
	    look = start;
	    break;
	}
	if (byte >= leads[n++]) {
	if (*((unsigned char *) look) < 0x80) {
	    /* A lead byte that can accept up to n trail bytes becomes
	     * the answer. */
	    return look;
	    /* 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 (byte >= 0xC0) {
	if (o >= i) {
	    /* A lead byte that cannot accept n trail bytes indicates
	     * the last trail byte the answer. */
	    return src - 1;
	    known = i;
	}
	look--;

    }
	/* We saw a trail byte; keep scanning. */
	look--;
    /* use best (marked as known) char position, or current found if unknown: */
    if (known) {
	look = src - known;
    } 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;
    return look;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UniCharAtIndex --
 *