public I8 PopUpReplaceSkipAllCancelEdit(I1 *msg) { I8 i; Ltf *l=LtfNew; LtfPutS(l,msg); LtfPutS(l,"$$CM +LX, 2,4$$$$BT, \"REPLACE\",0$$"); LtfPutS(l,"$$CM +LX, 22,0$$$$BT, \"SKIP\",1$$"); LtfPutS(l,"$$CM +LX, 2,4$$$$BT, \"ALL\",2$$"); LtfPutS(l,"$$CM +LX, 22,0$$$$BT, \"ABORT ALL\",3$$"); LtfPutS(l,"$$CM +LX, 2,4$$$$BT, \"EDIT\",4$$"); LtfPutS(l,"$$CM +LX, 22,0$$$$BT, \"ABORT FILE\",5$$"); LtfPutS(l,"$$CM +LX, 2,4$$$$BT, \"SKIP FILE\",6$$"); i=PopUpMenu(l); LtfDel(l); return i; } U8 GrepFile(I1 *pattern,I1 *name,U8 *flags,I1 *replace_text) { BoolU4 first_on_line,write_this_file=FALSE,cont=!Bt(flags,FUf_CANCEL); I1 *src,*dst,*dst2,*name_buf=NULL; U8 ss_flags; Ltf *l=LtfRead(name, LTFF_PLAIN_TEXT_WITH_TABS | LTFF_NO_CURSOR); LtfEntry *cl; I8 i,j,plen,rlen,dlen; U8 cnt=0; ss_flags=(Bt(flags,FUf_IGNORE)) ? SS_IGNORE_CASE :0; if (Bt(flags,FUf_LABEL)) ss_flags|=SS_WHOLE_LABELS; plen=StrLen(pattern); if (replace_text) rlen=StrLen(replace_text); cl=l->dummy.next; while (cl!=l && cont) { if (cl->btype==LTFT_TEXT) { src=cl->display; first_on_line=TRUE; while (src && cont) { if (src=SearchString(src,pattern,ss_flags)) { cnt++; if (first_on_line || Bt(flags,FUf_REPLACE)) { first_on_line=FALSE; PutFileLink(name,cl->y+1,TRUE); name_buf=MSPrintF("%s,%d",name,cl->y+1); PrintF(" %s\r\n",cl->display); } if (Bt(flags,FUf_REPLACE)) { if (Bt(flags,FUf_ALL)) i=2; else { i=PopUpReplaceSkipAllCancelEdit(""); if (i==3) { Bts(flags,FUf_CANCEL); cont=FALSE; write_this_file=FALSE; } else if (i==2) Bts(flags,FUf_ALL); else if (i==5) { cont=FALSE; write_this_file=FALSE; } else if (i==6) cont=FALSE; } if (!i || i==2) { dlen=StrLen(cl->display); dst=MAlloc(dlen+1+rlen-plen); dst2=dst; j=src-cl->display; for (i=0;idisplay[i]; for (i=0;idisplay[i]; Free(cl->display); cl->display=dst2; PrintF("%12s,%04X*%s\r\n",name,cl->y+1,dst2); write_this_file=TRUE; } else { src++; if (i==4) { Free(name_buf); name_buf=NewString(l->filename.name); l->flags&=~LTFF_NO_CURSOR; l->cur_entry=cl; l->cur_data_col=cl->min_col; LtfWrite(l); LtfDel(l); PrintF("Wrote:%s\r\n",name_buf); Edit(name_buf); l=LtfRead(name_buf, LTFF_PLAIN_TEXT_WITH_TABS); cl=l->cur_entry; if (cl->last!=l) cl=cl->last; src=NULL; write_this_file=FALSE; } } } else src++; Free(name_buf); name_buf=NULL; } } } cl=cl->next; } if (write_this_file) { LtfWrite(l); PrintF("Wrote:%s\r\n",l->filename.name); } LtfDel(l); return cnt; } U8 GrepList(I1 *pattern,LTDirEntry *tempm1,U8 *flags,I1 *replace_text) { U8 cnt=0; LTDirEntry *tempm2; while (tempm1 && !Bt(flags,FUf_CANCEL)) { tempm2=tempm1->next; if (tempm1->attr & LT_ATTR_DIR) { if (tempm1->sub) { PrintF("%S %s\r\n","ST_SCANNING_DIRECTORY",tempm1->full_name); cnt+=GrepList(pattern,tempm1->sub,flags,replace_text); } } else cnt+=GrepFile(pattern,tempm1->full_name,flags,replace_text); DelLTDirEntry(tempm1); tempm1=tempm2; } return cnt; } public U8 Grep(I1 *pattern,I1 *wild=TEXT_FILE_MASK,I1 *flags="+r+i+l",I1 *replace_text=NULL) //This does not do regular expressions--my bad //Anyway, it's good for searching and replacing. //Let's say it stands for global replace ;-) //"+r"=recurse //"+i"=ignore case //"+l"=whole labels only. // This will check for a nonlabel character before // and after. If you have a variable, "ll" and don't // want to match words like "will" and "wallow", you // set this flag and it will see that the characters // before or after "ll" are label characters. { U8 cnt=0; FlagsStruct f; GetFFlags(&f,"ST_FILE_UTIL_FLAGS",flags); AssignBit(&f.on,FUf_REPLACE,replace_text); cnt+=GrepList(pattern,FindFiles(wild,&f.on),&f.on,replace_text); return cnt; } public U8 FileOccurrences(I1 *pattern,I1 *wild=TEXT_FILE_MASK,I1 *flags="+r+i+l") { U8 cnt; BoolU4 old_silent=Silent(TRUE); cnt=Grep(pattern,wild,flags); Silent(old_silent); return cnt; } LTDirEntry MCFindMatch(LTDirEntry *pattern,LTDirEntry *list) { while (list) { if (!StrCmp(pattern->name,list->name) && pattern->attr==list->attr) return list; list=list->next; } return NULL; } void MergeChkList(LTDirEntry *m1,LTDirEntry *m2,U8 *fuf_flags,U8 *df_flags) { I8 i; LTDirEntry *tempm2; while (m1 && !(*df_flags & DF_ABORT_ALL_FILES)) { tempm2=MCFindMatch(m1,m2); if (!tempm2) coutln "Does Not Exist:",m1->full_name; else { if (m1->attr & LT_ATTR_DIR) MergeChkList(m1->sub,tempm2->sub,fuf_flags,df_flags); else { i=m1->datetime-tempm2->datetime; if (AbsI8(i)>LTDATE_FREQ*2) { //Filedates can shift due to conversion coutln m1->full_name; if (Bt(fuf_flags,FUf_DIFF)) { if (IsTextFile(m1->full_name)) *df_flags=Diff(tempm2->full_name,m1->full_name,*df_flags); } } } } m1=m1->next; } } public void MergeChk(I1 *dst_mask,I1 *src_mask,I1 *flags="+r") //r=recurse //d=diff { U8 df_flags=0; LTDirEntry *tempm1=NULL,*tempm2=NULL; FlagsStruct f; GetFFlags(&f,"ST_FILE_UTIL_FLAGS",flags); coutln "WARNING:This is based strictly on file dates."; tempm1=FindFiles(src_mask,&f.on); tempm2=FindFiles(dst_mask,&f.on); MergeChkList(tempm1,tempm2,&f.on,&df_flags); DelLTDirList(tempm1); DelLTDirList(tempm2); } void CommMergeChkList(U8 port,LTDirEntry *m1,LTDirEntry *m2,U8 *fuf_flags,U8 *df_flags) { I8 i; LTDirEntry *tempm2; while (m1 && !(*df_flags & DF_ABORT_ALL_FILES)) { tempm2=MCFindMatch(m1,m2); if (!tempm2) coutln "Does Not Exist:",m1->name; else { if (m1->attr & LT_ATTR_DIR) CommMergeChkList(port,m1->sub,tempm2->sub,fuf_flags,df_flags); else { i=m1->datetime-tempm2->datetime; if (AbsI8(i)>LTDATE_FREQ*2) { //Filedates can shift due to conversion coutln m1->name; if (Bt(fuf_flags,FUf_DIFF)) { if (IsTextFile(m1->name)) *df_flags=Diff(tempm2->name,m1->name,*df_flags); } } } } m1=m1->next; } } //$BK,1$Not Done$BK,0$ public void CommMergeChk(U8 port,I1 *dst_mask,I1 *src_mask,I1 *flags="+r") //r=recurse //d=diff { U8 df_flags=0; LTDirEntry *tempm1=NULL,*tempm2=NULL; FlagsStruct f; GetFFlags(&f,"ST_FILE_UTIL_FLAGS",flags); coutln "WARNING:This is based strictly on file dates."; tempm1=FindFiles(src_mask,&f.on); tempm2=FindFiles(dst_mask,&f.on); CommMergeChkList(port,tempm1,tempm2,&f.on,&df_flags); DelLTDirList(tempm1); DelLTDirList(tempm2); }