#help_index "Utils;Cmd Line (Typically)" #define DS_USE_FILE1 0 #define DS_USE_FILE2 1 #define DS_REMAINDER_1 2 #define DS_REMAINDER_2 3 #define DS_ABORT_FILE 4 I64 PopUpDiffOptions() { I64 i; CDoc *doc=DocNew; DocPutS(doc,"$$CM+LX,2,4$$$$FG$$$$BT,\"USE FILE1\",DS_USE_FILE1$$" "$$CM+LX,24,0$$$$FG,CYAN$$$$BT,\"USE FILE2\",DS_USE_FILE2$$" "$$CM+LX,2,4$$$$FG$$$$BT,\"REMAINDER ALL FILE1\",DS_REMAINDER_1$$" "$$CM+LX,24,0$$$$FG,CYAN$$$$BT,\"REMAINDER ALL FILE2\",DS_REMAINDER_2$$" "$$CM+LX,2,4$$$$FG$$$$BT,\"ABORT FILE\",DS_ABORT_FILE$$" "$$CM+LX,24,0$$$$FG$$$$BT,\"ABORT ALL FILES\",DOCM_CANCEL$$\n"); i=PopUpMenu(doc); DocDel(doc); return i; } I64 DiffEntriesCompare(CDocEntry *doc_e1,CDocEntry *doc_e2) { return StrCmp(doc_e1->tag,doc_e2->tag); } #define DF_MODIFIED 1 #define DF_DONT_MODIFIED 2 #define DF_REMAINDER_ALL_FILE1 4 #define DF_REMAINDER_ALL_FILE2 8 #define DF_ABORT_FILE 16 #define DF_ABORT_ALL_FILES 32 #define DF_NO_MORE_PROMPTS_THIS_FILE 64 U0 DiffSelect(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi, I64 j2_lo,I64 j2_hi,CDocEntry **doc_us1,CDocEntry **doc_us2) { I64 i; CDocEntry *doc_e,*doc_e1,*doc_e2; Bool use_file1; I64 old_flags; CDoc *cur_l; if (!(*_df_flags & (DF_ABORT_FILE|DF_ABORT_ALL_FILES))) { "$$FG,RED$$%d,%d---------------------$$FG$$\n",j1_lo,j2_lo; i= j1_lo<=0 ? 0:j1_lo-1; while (iflags&DOCF_PLAIN_TEXT; cur_l->flags|=DOCF_PLAIN_TEXT; } "" doc_us1[i++]->tag; if (cur_l) cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags; NewLine; } "$$FG,CYAN$$"; i= j2_lo<=0 ? 0:j2_lo-1; while (iflags&DOCF_PLAIN_TEXT; cur_l->flags|=DOCF_PLAIN_TEXT; } "" doc_us2[i++]->tag; if (cur_l) cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags; NewLine; } "$$FG$$"; use_file1=TRUE; if (!(*_df_flags & DF_NO_MORE_PROMPTS_THIS_FILE)) { switch (PopUpDiffOptions) { case DS_USE_FILE1: break; case DS_USE_FILE2: use_file1=FALSE; break; case DS_REMAINDER_1: *_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE2|DF_REMAINDER_ALL_FILE1|DF_NO_MORE_PROMPTS_THIS_FILE; break; case DS_REMAINDER_2: *_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE1|DF_REMAINDER_ALL_FILE2|DF_NO_MORE_PROMPTS_THIS_FILE; break; case DS_ABORT_FILE: *_df_flags|=DF_DONT_MODIFIED|DF_ABORT_FILE|DF_NO_MORE_PROMPTS_THIS_FILE; break; default: *_df_flags|=DF_DONT_MODIFIED|DF_ABORT_ALL_FILES|DF_NO_MORE_PROMPTS_THIS_FILE; } } if (*_df_flags & DF_REMAINDER_ALL_FILE2 && !(*_df_flags & (DF_DONT_MODIFIED|DF_REMAINDER_ALL_FILE1))) use_file1=FALSE; if (!use_file1) { *_df_flags|=DF_MODIFIED; doc_e1=doc_us1[j1_lo]->last; if (j1_lonext; DocEntryDel(doc,doc_e); doc_e=doc_e2; } } if (j2_lonext; } } } } } U0 DiffSub(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi,I64 j2_lo,I64 j2_hi, I64 cnt1,I64 cnt2,CDocEntry **doc_s1,CDocEntry **doc_s2,CDocEntry **doc_us1,CDocEntry **doc_us2) { I64 i,i1=0,i2=0,i2b,j1,j2,n; I64 best_j1,best_j2,best_score=0,score; if (j1_lo>=j1_hi || j2_lo>=j2_hi) { if (j1_loyy>=j1_hi) i1++; else if (doc_s2[i2]->yy>=j2_hi) i2++; else { i=StrCmp(doc_s1[i1]->tag,doc_s2[i2]->tag); if (i>0) i2++; else if (i<0) i1++; else { i2b=i2; while (!StrCmp(doc_s1[i1]->tag,doc_s2[i2]->tag)) { if (doc_s2[i2]->y>=j2_lo && doc_s2[i2]->yy; j2=doc_s2[i2]->y; n=j1_hi-j1; if (j2_hi-j2tag,doc_us2[j2+score]->tag)) score++; else break; } if (score>best_score) { best_score=score; best_j1=j1; best_j2=j2; } } i2++; if (i2>=cnt2) break; } i2=i2b; i1++; } } } if (!best_score) DiffSelect(doc,_df_flags,j1_lo,j1_hi,j2_lo,j2_hi,doc_us1,doc_us2); else { DiffSub(doc,_df_flags,j1_lo,best_j1,j2_lo,best_j2,cnt1,cnt2,doc_s1,doc_s2,doc_us1,doc_us2); DiffSub(doc,_df_flags,best_j1+best_score,j1_hi,best_j2+best_score,j2_hi,cnt1,cnt2, doc_s1,doc_s2,doc_us1,doc_us2); } } Bool DiffBins(CDoc *doc1,CDoc *doc2) { CDocBin *tempb1=doc1->bin_root.next, *tempb2=doc2->bin_root.next; if (tempb1->last->last->num!= tempb2->last->last->num) return FALSE; while (tempb1!=&doc1->bin_root) { if (tempb1->type!=tempb2->type || tempb1->size!=tempb2->size || MemCmp(tempb1->data,tempb2->data,tempb1->size)) return FALSE; tempb1=tempb1->next; tempb2=tempb2->next; } return TRUE; } public I64 Diff(U8 *dst_file,U8 *src_file,I64 df_flags=0) { //The df_flags arg is used when this is called by $LK,"MergeChk","MN:MergeChk"$(). CDoc *doc1=DocRead(dst_file, DOCF_PLAIN_TEXT_WITH_TABS | DOCF_NO_CURSOR); CDoc *doc2=DocRead(src_file, DOCF_PLAIN_TEXT_WITH_TABS | DOCF_NO_CURSOR); CDocEntry *doc_e,**doc_s1,**doc_s2,**doc_us1,**doc_us2; I64 i,cnt1=0,cnt2=0; df_flags&=DF_ABORT_ALL_FILES; doc_e=doc1->root.next; while (doc_e!=doc1) { if (doc_e->type_u8==DOCT_TEXT) doc_e->y=cnt1++; doc_e=doc_e->next; } doc_e=doc2->root.next; while (doc_e!=doc2) { if (doc_e->type_u8==DOCT_TEXT) doc_e->y=cnt2++; doc_e=doc_e->next; } doc_s1=MAlloc(cnt1*sizeof(CDocEntry *)); doc_us1=MAlloc((cnt1+1)*sizeof(CDocEntry *)); i=0; doc_e=doc1->root.next; while (doc_e!=doc1) { if (doc_e->type_u8==DOCT_TEXT) { doc_s1[i]=doc_e; doc_us1[i++]=doc_e; } doc_e=doc_e->next; } doc_us1[i]=doc1; QSortI64(doc_s1,cnt1,&DiffEntriesCompare); doc_s2=MAlloc(cnt2*sizeof(CDocEntry *)); doc_us2=MAlloc((cnt2+1)*sizeof(CDocEntry *)); i=0; doc_e=doc2->root.next; while (doc_e!=doc2) { if (doc_e->type_u8==DOCT_TEXT) { doc_s2[i]=doc_e; doc_us2[i++]=doc_e; } doc_e=doc_e->next; } doc_us2[i]=doc2; QSortI64(doc_s2,cnt2,&DiffEntriesCompare); DiffSub(doc1,&df_flags,0,cnt1,0,cnt2,cnt1,cnt2,doc_s1,doc_s2,doc_us1,doc_us2); if (df_flags&DF_MODIFIED && !(df_flags&DF_DONT_MODIFIED)) DocWrite(doc1); if (!DiffBins(doc1,doc2)) "$$FG,RED$$Bin Data is Different$$FG$$\n"; DocDel(doc1); DocDel(doc2); Free(doc_s1); Free(doc_s2); Free(doc_us1); Free(doc_us2); return df_flags; } #help_index ""