Fossil SCM

Make sure side-by-side diff highlighting encloses complete UTF8 characters and does not divide a UTF8 character into two invalid characters.

drh 2013-02-28 20:44 trunk
Commit e2b34906761dd94ae5c0701c12ac636605272d06
1 file changed +27 -7
+27 -7
--- src/diff.c
+++ src/diff.c
@@ -855,21 +855,33 @@
855855
/*
856856
** Simplify iStart and iStart2:
857857
**
858858
** * If iStart is a null-change then move iStart2 into iStart
859859
** * Make sure any null-changes are in canonoical form.
860
+** * Make sure all changes are at character boundaries for
861
+** multi-byte characters.
860862
*/
861863
static void sbsSimplifyLine(SbsLine *p){
862
- if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
864
+ if( p->iStart2==p->iEnd2 ){
865
+ p->iStart2 = p->iEnd2 = 0;
866
+ }else if( p->iStart2 ){
867
+ while( p->iStart2>0 && (p->zLine[p->iStart2]&0xc0)==0x80 ) p->iStart2--;
868
+ while( (p->zLine[p->iEnd2+1]&0xc0)==0x80 ) p->iEnd2++;
869
+ }
863870
if( p->iStart==p->iEnd ){
864871
p->iStart = p->iStart2;
865872
p->iEnd = p->iEnd2;
866873
p->zStart = p->zStart2;
867874
p->iStart2 = 0;
868875
p->iEnd2 = 0;
869876
}
870
- if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
877
+ if( p->iStart==p->iEnd ){
878
+ p->iStart = p->iEnd = -1;
879
+ }else if( p->iStart>0 ){
880
+ while( p->iStart>0 && (p->zLine[p->iStart]&0xc0)==0x80 ) p->iStart--;
881
+ while( (p->zLine[p->iEnd+1]&0xc0)==0x80 ) p->iEnd++;
882
+ }
871883
}
872884
873885
/*
874886
** Write out lines that have been edited. Adjust the highlight to cover
875887
** only those parts of the line that actually changed.
@@ -881,10 +893,11 @@
881893
DLine *pRight, /* Right line of the change */
882894
int lnRight /* Line number of the right line */
883895
){
884896
int nLeft; /* Length of left line in bytes */
885897
int nRight; /* Length of right line in bytes */
898
+ int nShort; /* Shortest of left and right */
886899
int nPrefix; /* Length of common prefix */
887900
int nSuffix; /* Length of common suffix */
888901
const char *zLeft; /* Text of the left line */
889902
const char *zRight; /* Text of the right line */
890903
int nLeftDiff; /* nLeft - nPrefix - nSuffix */
@@ -896,25 +909,32 @@
896909
897910
nLeft = pLeft->h & LENGTH_MASK;
898911
zLeft = pLeft->z;
899912
nRight = pRight->h & LENGTH_MASK;
900913
zRight = pRight->z;
914
+ nShort = nLeft<nRight ? nLeft : nRight;
901915
902916
nPrefix = 0;
903
- while( nPrefix<nLeft && nPrefix<nRight && zLeft[nPrefix]==zRight[nPrefix] ){
917
+ while( nPrefix<nShort && zLeft[nPrefix]==zRight[nPrefix] ){
904918
nPrefix++;
905919
}
920
+ if( nPrefix<nShort ){
921
+ while( nPrefix>0 && (zLeft[nPrefix]&0xc0)==0x80 ) nPrefix--;
922
+ }
906923
nSuffix = 0;
907
- if( nPrefix<nLeft && nPrefix<nRight ){
908
- while( nSuffix<nLeft && nSuffix<nRight
924
+ if( nPrefix<nShort ){
925
+ while( nSuffix<nShort
909926
&& zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
910927
nSuffix++;
911928
}
929
+ if( nSuffix<nShort ){
930
+ while( nSuffix>0 && (zLeft[nLeft-nSuffix+1]&0xc0)==0x80 ) nSuffix--;
931
+ }
912932
if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
913933
}
914
- if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
915
- if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
934
+ if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
935
+
916936
917937
/* A single chunk of text inserted on the right */
918938
if( nPrefix+nSuffix==nLeft ){
919939
sbsWriteLineno(p, lnLeft);
920940
p->iStart2 = p->iEnd2 = 0;
921941
--- src/diff.c
+++ src/diff.c
@@ -855,21 +855,33 @@
855 /*
856 ** Simplify iStart and iStart2:
857 **
858 ** * If iStart is a null-change then move iStart2 into iStart
859 ** * Make sure any null-changes are in canonoical form.
 
 
860 */
861 static void sbsSimplifyLine(SbsLine *p){
862 if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
 
 
 
 
 
863 if( p->iStart==p->iEnd ){
864 p->iStart = p->iStart2;
865 p->iEnd = p->iEnd2;
866 p->zStart = p->zStart2;
867 p->iStart2 = 0;
868 p->iEnd2 = 0;
869 }
870 if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
 
 
 
 
 
871 }
872
873 /*
874 ** Write out lines that have been edited. Adjust the highlight to cover
875 ** only those parts of the line that actually changed.
@@ -881,10 +893,11 @@
881 DLine *pRight, /* Right line of the change */
882 int lnRight /* Line number of the right line */
883 ){
884 int nLeft; /* Length of left line in bytes */
885 int nRight; /* Length of right line in bytes */
 
886 int nPrefix; /* Length of common prefix */
887 int nSuffix; /* Length of common suffix */
888 const char *zLeft; /* Text of the left line */
889 const char *zRight; /* Text of the right line */
890 int nLeftDiff; /* nLeft - nPrefix - nSuffix */
@@ -896,25 +909,32 @@
896
897 nLeft = pLeft->h & LENGTH_MASK;
898 zLeft = pLeft->z;
899 nRight = pRight->h & LENGTH_MASK;
900 zRight = pRight->z;
 
901
902 nPrefix = 0;
903 while( nPrefix<nLeft && nPrefix<nRight && zLeft[nPrefix]==zRight[nPrefix] ){
904 nPrefix++;
905 }
 
 
 
906 nSuffix = 0;
907 if( nPrefix<nLeft && nPrefix<nRight ){
908 while( nSuffix<nLeft && nSuffix<nRight
909 && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
910 nSuffix++;
911 }
 
 
 
912 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
913 }
914 if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
915 if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
916
917 /* A single chunk of text inserted on the right */
918 if( nPrefix+nSuffix==nLeft ){
919 sbsWriteLineno(p, lnLeft);
920 p->iStart2 = p->iEnd2 = 0;
921
--- src/diff.c
+++ src/diff.c
@@ -855,21 +855,33 @@
855 /*
856 ** Simplify iStart and iStart2:
857 **
858 ** * If iStart is a null-change then move iStart2 into iStart
859 ** * Make sure any null-changes are in canonoical form.
860 ** * Make sure all changes are at character boundaries for
861 ** multi-byte characters.
862 */
863 static void sbsSimplifyLine(SbsLine *p){
864 if( p->iStart2==p->iEnd2 ){
865 p->iStart2 = p->iEnd2 = 0;
866 }else if( p->iStart2 ){
867 while( p->iStart2>0 && (p->zLine[p->iStart2]&0xc0)==0x80 ) p->iStart2--;
868 while( (p->zLine[p->iEnd2+1]&0xc0)==0x80 ) p->iEnd2++;
869 }
870 if( p->iStart==p->iEnd ){
871 p->iStart = p->iStart2;
872 p->iEnd = p->iEnd2;
873 p->zStart = p->zStart2;
874 p->iStart2 = 0;
875 p->iEnd2 = 0;
876 }
877 if( p->iStart==p->iEnd ){
878 p->iStart = p->iEnd = -1;
879 }else if( p->iStart>0 ){
880 while( p->iStart>0 && (p->zLine[p->iStart]&0xc0)==0x80 ) p->iStart--;
881 while( (p->zLine[p->iEnd+1]&0xc0)==0x80 ) p->iEnd++;
882 }
883 }
884
885 /*
886 ** Write out lines that have been edited. Adjust the highlight to cover
887 ** only those parts of the line that actually changed.
@@ -881,10 +893,11 @@
893 DLine *pRight, /* Right line of the change */
894 int lnRight /* Line number of the right line */
895 ){
896 int nLeft; /* Length of left line in bytes */
897 int nRight; /* Length of right line in bytes */
898 int nShort; /* Shortest of left and right */
899 int nPrefix; /* Length of common prefix */
900 int nSuffix; /* Length of common suffix */
901 const char *zLeft; /* Text of the left line */
902 const char *zRight; /* Text of the right line */
903 int nLeftDiff; /* nLeft - nPrefix - nSuffix */
@@ -896,25 +909,32 @@
909
910 nLeft = pLeft->h & LENGTH_MASK;
911 zLeft = pLeft->z;
912 nRight = pRight->h & LENGTH_MASK;
913 zRight = pRight->z;
914 nShort = nLeft<nRight ? nLeft : nRight;
915
916 nPrefix = 0;
917 while( nPrefix<nShort && zLeft[nPrefix]==zRight[nPrefix] ){
918 nPrefix++;
919 }
920 if( nPrefix<nShort ){
921 while( nPrefix>0 && (zLeft[nPrefix]&0xc0)==0x80 ) nPrefix--;
922 }
923 nSuffix = 0;
924 if( nPrefix<nShort ){
925 while( nSuffix<nShort
926 && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
927 nSuffix++;
928 }
929 if( nSuffix<nShort ){
930 while( nSuffix>0 && (zLeft[nLeft-nSuffix+1]&0xc0)==0x80 ) nSuffix--;
931 }
932 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
933 }
934 if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
935
936
937 /* A single chunk of text inserted on the right */
938 if( nPrefix+nSuffix==nLeft ){
939 sbsWriteLineno(p, lnLeft);
940 p->iStart2 = p->iEnd2 = 0;
941

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button