hschumann2/TempleOS-Source-Code
0847
1 2#help_index "Cmd Line (Typically)"3 4#define DS_USE_FILE1 05#define DS_USE_FILE2 16#define DS_REMAINDER_1 27#define DS_REMAINDER_2 38#define DS_ABORT_FILE 49 10I64 PopUpDiffMenu()11{12 I64 i;13 CDoc *doc=DocNew;14 DocPrint(doc,"$CM+LX,2,4$$FG$$BT,\"USE FILE1\",LE=DS_USE_FILE1$"15 "$CM+LX,24,0$$CYAN$$BT,\"USE FILE2\",LE=DS_USE_FILE2$"16 "$CM+LX,2,4$$FG$$BT,\"REMAINDER ALL FILE1\",LE=DS_REMAINDER_1$"17 "$CM+LX,24,0$$CYAN$$BT,\"REMAINDER ALL FILE2\",LE=DS_REMAINDER_2$"18 "$CM+LX,2,4$$FG$$BT,\"ABORT FILE\",LE=DS_ABORT_FILE$"19 "$CM+LX,24,0$$FG$$BT,\"ABORT ALL FILES\",LE=DOCM_CANCEL$\n");20 i=PopUpMenu(doc);21 DocDel(doc);22 return i;23}24 25I64 DiffEntriesCompare(CDocEntry *doc_e1,CDocEntry *doc_e2)26{27 return StrCmp(doc_e1->tag,doc_e2->tag);28}29 30#define DF_MODIFIED 0x0131#define DF_DONT_MODIFIED 0x0232#define DF_REMAINDER_ALL_FILE1 0x0433#define DF_REMAINDER_ALL_FILE2 0x0834#define DF_ABORT_FILE 0x1035#define DF_ABORT_ALL_FILES 0x2036#define DF_NO_MORE_PMTS_THIS_FILE 0x4037 38U0 DiffSel(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi,39 I64 j2_lo,I64 j2_hi,I64 cnt1,I64 cnt2,40 CDocEntry **doc_unsorted1,CDocEntry **doc_unsorted2)41{42 CDocEntry *doc_e,*doc_e1,*doc_e2;43 Bool use_file1;44 I64 i,old_flags;45 CDoc *cur_l;46 if (!(*_df_flags & (DF_ABORT_FILE|DF_ABORT_ALL_FILES))) {47 "$RED$";48 if (0<=j1_lo<cnt1)49 "%d,",doc_unsorted1[j1_lo]->y+1;50 else if (0<=j1_hi-1<cnt1)51 "%d,",doc_unsorted1[j1_hi-1]->y+1;52 else53 "***,";54 if (0<=j2_lo<cnt2)55 "%d",doc_unsorted2[j2_lo]->y+1;56 else if (0<=j2_hi-1<cnt2)57 "%d",doc_unsorted2[j2_hi-1]->y+1;58 else59 "***";60 "---------------------$FG$\n";61 if (j1_lo<=0)62 i=0;63 else64 i=j1_lo-1;65 while (i<j1_hi) {66 if (cur_l=DocPut) {67 old_flags=cur_l->flags&DOCF_PLAIN_TEXT;68 cur_l->flags|=DOCF_PLAIN_TEXT;69 }70 "%s",doc_unsorted1[i++]->tag;71 if (cur_l)72 cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;73 '\n';74 }75 "$CYAN$";76 if (j2_lo<=0)77 i=0;78 else79 i=j2_lo-1;80 while (i<j2_hi) {81 if (cur_l=DocPut) {82 old_flags=cur_l->flags&DOCF_PLAIN_TEXT;83 cur_l->flags|=DOCF_PLAIN_TEXT;84 }85 "%s",doc_unsorted2[i++]->tag;86 if (cur_l)87 cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;88 '\n';89 }90 "$FG$";91 92 use_file1=TRUE;93 if (!(*_df_flags & DF_NO_MORE_PMTS_THIS_FILE)) {94 switch (PopUpDiffMenu) {95 case DS_USE_FILE1:96 break;97 case DS_USE_FILE2:98 use_file1=FALSE;99 break;100 case DS_REMAINDER_1:101 *_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE2|102 DF_REMAINDER_ALL_FILE1|DF_NO_MORE_PMTS_THIS_FILE;103 break;104 case DS_REMAINDER_2:105 *_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE1|106 DF_REMAINDER_ALL_FILE2|DF_NO_MORE_PMTS_THIS_FILE;107 break;108 case DS_ABORT_FILE:109 *_df_flags|=DF_DONT_MODIFIED|DF_ABORT_FILE|110 DF_NO_MORE_PMTS_THIS_FILE;111 break;112 default:113 *_df_flags|=DF_DONT_MODIFIED|DF_ABORT_ALL_FILES|114 DF_NO_MORE_PMTS_THIS_FILE;115 }116 }117 if (*_df_flags & DF_REMAINDER_ALL_FILE2 &&118 !(*_df_flags & (DF_DONT_MODIFIED|DF_REMAINDER_ALL_FILE1)))119 use_file1=FALSE;120 if (!use_file1) {121 *_df_flags|=DF_MODIFIED;122 doc_e1=doc_unsorted1[j1_lo]->last;123 if (j1_lo<j1_hi) {124 doc_e=doc_unsorted1[j1_lo];125 while (doc_e!=doc_unsorted1[j1_hi]) {126 doc_e2=doc_e->next;127 DocEntryDel(doc,doc_e);128 doc_e=doc_e2;129 }130 }131 if (j2_lo<j2_hi) {132 doc_e=doc_unsorted2[j2_lo];133 while (doc_e!=doc_unsorted2[j2_hi]) {134 doc_e2=DocEntryCopy(doc,doc_e);135 QueIns(doc_e2,doc_e1);136 doc_e1=doc_e2;137 doc_e=doc_e->next;138 }139 }140 }141 }142}143 144Bool DiffSub(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi,I64 j2_lo,I64 j2_hi,145 I64 cnt1,I64 cnt2,CDocEntry **doc_sorted1,CDocEntry **doc_sorted2,146 CDocEntry **doc_unsorted1,CDocEntry **doc_unsorted2)147{148 I64 i,i1=0,i2=0,i2b,j1,j2,n,149 best_j1,best_j2,best_score=0,score;150 Bool res=FALSE;151 152 if (j1_lo>=j1_hi || j2_lo>=j2_hi) {153 if (j1_lo<j1_hi || j2_lo<j2_hi) {154 DiffSel(doc,_df_flags,j1_lo,j1_hi,j2_lo,j2_hi,cnt1,cnt2,155 doc_unsorted1,doc_unsorted2);156 return TRUE;157 } else158 return FALSE;159 }160 161 //Locate longest matching str in intervals162 while (i1<cnt1 && i2<cnt2) {163 if (!(j1_lo<=doc_sorted1[i1]->user_data<j1_hi)) //user_data is the new y164 i1++;165 else if (!(j2_lo<=doc_sorted2[i2]->user_data<j2_hi)) //user_data is new y166 i2++;167 else {168 i=StrCmp(doc_sorted1[i1]->tag,doc_sorted2[i2]->tag);169 if (i>0)170 i2++;171 else if (i<0)172 i1++;173 else {174 i2b=i2;175 while (!StrCmp(doc_sorted1[i1]->tag,doc_sorted2[i2]->tag)) {176 if (j2_lo<=doc_sorted2[i2]->user_data<j2_hi) {//user_data is the new y177 score=0;178 j1=doc_sorted1[i1]->user_data; //user_data is the new y179 j2=doc_sorted2[i2]->user_data; //user_data is the new y180 n=j1_hi-j1;181 if (j2_hi-j2<n)182 n=j2_hi-j2;183 while (score<n) {184 if (!StrCmp(doc_unsorted1[j1+score]->tag,185 doc_unsorted2[j2+score]->tag))186 score++;187 else188 break;189 }190 if (score>best_score) {191 best_score=score;192 best_j1=j1;193 best_j2=j2;194 }195 }196 i2++;197 if (i2>=cnt2)198 break;199 }200 i2=i2b;201 i1++;202 }203 }204 }205 if (!best_score) {206 DiffSel(doc,_df_flags,j1_lo,j1_hi,j2_lo,j2_hi,cnt1,cnt2,207 doc_unsorted1,doc_unsorted2);208 return TRUE;209 } else {210 if (DiffSub(doc,_df_flags,j1_lo,best_j1,j2_lo,best_j2,cnt1,cnt2,211 doc_sorted1,doc_sorted2,doc_unsorted1,doc_unsorted2))212 res=TRUE;213 if (DiffSub(doc,_df_flags,best_j1+best_score,j1_hi,best_j2+best_score,214 j2_hi,cnt1,cnt2,215 doc_sorted1,doc_sorted2,doc_unsorted1,doc_unsorted2))216 res=TRUE;217 return res;218 }219}220 221Bool DiffBins(CDoc *doc1,CDoc *doc2)222{223 CDocBin *tmpb1=doc1->bin_head.next,224 *tmpb2=doc2->bin_head.next;225 226 if (tmpb1->last->last->num!=tmpb2->last->last->num)227 return TRUE;228 while (tmpb1!=&doc1->bin_head) {229 if (tmpb1->size!=tmpb2->size ||230 MemCmp(tmpb1->data,tmpb2->data,tmpb1->size))231 return TRUE;232 tmpb1=tmpb1->next;233 tmpb2=tmpb2->next;234 }235 return FALSE;236}237 238public Bool Diff(U8 *dst_file,U8 *src_file,I64 *_df_flags=NULL)239{//Report differences between two files and merge differences240//from src_file to dst_file. Don't use _df_flags arg. (Used by Merge().)241 CDoc *doc1=DocRead(dst_file,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR),242 *doc2=DocRead(src_file,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);243 CDocEntry *doc_e,**doc_sorted1,**doc_sorted2,**doc_unsorted1,**doc_unsorted2;244 I64 i,cnt1=0,cnt2=0,df_flags;245 Bool res=FALSE;246 247 if (_df_flags)248 df_flags=*_df_flags;249 else250 df_flags=0;251 df_flags&=DF_ABORT_ALL_FILES;252 253 doc_e=doc1->head.next;254 while (doc_e!=doc1) {255 if (doc_e->type_u8==DOCT_TEXT)256 doc_e->user_data=cnt1++; //user_data is the new y257 doc_e=doc_e->next;258 }259 260 doc_e=doc2->head.next;261 while (doc_e!=doc2) {262 if (doc_e->type_u8==DOCT_TEXT)263 doc_e->user_data=cnt2++; //user_data is the new y264 doc_e=doc_e->next;265 }266 267 doc_sorted1=MAlloc(cnt1*sizeof(CDocEntry *));268 doc_unsorted1=MAlloc((cnt1+1)*sizeof(CDocEntry *));269 i=0;270 doc_e=doc1->head.next;271 while (doc_e!=doc1) {272 if (doc_e->type_u8==DOCT_TEXT) {273 doc_sorted1[i]=doc_e;274 doc_unsorted1[i++]=doc_e;275 }276 doc_e=doc_e->next;277 }278 doc_unsorted1[i]=doc1;279 QSortI64(doc_sorted1,cnt1,&DiffEntriesCompare);280 281 doc_sorted2=MAlloc(cnt2*sizeof(CDocEntry *));282 doc_unsorted2=MAlloc((cnt2+1)*sizeof(CDocEntry *));283 i=0;284 doc_e=doc2->head.next;285 while (doc_e!=doc2) {286 if (doc_e->type_u8==DOCT_TEXT) {287 doc_sorted2[i]=doc_e;288 doc_unsorted2[i++]=doc_e;289 }290 doc_e=doc_e->next;291 }292 doc_unsorted2[i]=doc2;293 QSortI64(doc_sorted2,cnt2,&DiffEntriesCompare);294 295 res=DiffSub(doc1,&df_flags,0,cnt1,0,cnt2,cnt1,cnt2,296 doc_sorted1,doc_sorted2,doc_unsorted1,doc_unsorted2);297 if (df_flags&DF_MODIFIED && !(df_flags&DF_DONT_MODIFIED))298 DocWrite(doc1);299 300 if (DiffBins(doc1,doc2)) {301 "$RED$Bin Data is Different$FG$\n";302 res=TRUE;303 }304 305 DocDel(doc1);306 DocDel(doc2);307 Free(doc_sorted1);308 Free(doc_sorted2);309 Free(doc_unsorted1);310 Free(doc_unsorted2);311 if (_df_flags)312 *_df_flags=df_flags;313 return res;314}315 316#help_index "Cmd Line (Typically);Info"317I64 ZRepCompare(CDirEntry *e1,CDirEntry *e2)318{319 return SignI64(e2->user_data(F64)-e1->user_data(F64));320}321public U0 ZipRep(U8 *files_find_mask="/*",U8 *fu_flags=NULL,322 Bool just_text_not_graphics=TRUE)323{//Report file compressibility.324//Dft is just src files. (Used to spot325 //src files with redundancy in them.)326 I64 i=0,cnt,size,fuf_flags=0;327 CDirEntry *tmpde,*tmpde1,**sort_buf;328 U8 *buf;329 CArcCompress *arc;330 ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+F+S");331 ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);332 tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);333 cnt=FileCnt(tmpde);334 sort_buf=MAlloc(sizeof(CDirEntry *)*cnt);335 while (tmpde) {336 sort_buf[i++]=tmpde;337 buf=FileRead(tmpde->full_name,&size);338 if (just_text_not_graphics)339 size=StrLen(buf);340 arc=CompressBuf(buf,size);341 Free(buf);342 tmpde->user_data(F64)=100.0*arc->compressed_size/arc->expanded_size;343 Free(arc);344 tmpde=tmpde->next;345 }346 QSortI64(sort_buf,cnt,&ZRepCompare);347 for (i=0;i<cnt;i++) {348 "%4.1f%% %04X ",sort_buf[i]->user_data,sort_buf[i]->size;349 PutFileLink(sort_buf[i]->full_name);350 '\n';351 }352 Free(sort_buf);353 DirTreeDel(tmpde1);354}355 