#pragma rtGlobals=1 // Use modern global access method. // edit by tony withers // changed local version of trimstring2 to trimstring22 to avoid clash with // function in recent versions of Igor #pragma version=1.22 #pragma IgorVersion=5 // IPF comparison utility - useful for version control and collaborative writing // To use, run ipf_compare() // James Allan, SEAES, University of Manchester, UK // More of my Igor stuff at http://cloudbase.phy.umist.ac.uk/people/allan/ja_igor.htm // james.allan@manchester.ac.uk - feedback is much appreciated! // Version 1.1 Made the function finding routine more robust and added support for 'proc' // Version 1.2 Allows for pictures and the 'static' keyword. Generally more robust still. // Enhanced output and made more user-friendly. Now inspects preprocessor declarations // Version 1.21 Added an item to the top menu. Added file creation and modification to the output. static strconstant PREF_LIST="function ;function/;window ;macro ;proc ;picture ;menu " menu "Misc" submenu "Packages" "Compare ipfs", /q, ipf_compare() help = {"Compare the contents of two ipf files and produce a report on the differences"} end end function ipf_compare() // The main function to run to compare two ipfs variable file1,file2,i,n,match,nu1,nu2,nd,bytes1,bytes2,lines1,lines2,npu1,npu2,npd string uni1="",uni2="",diff="",filename1,filename2,datafolder,pre1="",pre2="",pred="" datafolder=getdatafolder(1) newdatafolder /o root:Packages newdatafolder /o/s root:Packages:ipfCompare // Open files open /r/m="Please select ipf file 1"/t="IPRC" file1 filename1=s_filename open /r/m="Please select ipf file 2"/t="IPRC" file2 filename2=s_filename if (strlen(filename1)>0&&strlen(filename2)>0) // Perform function comparisons ipf_summary(file1,"funcs1","funcpos1",bytes1,lines1) ipf_summary(file2,"funcs2","funcpos2",bytes2,lines2) wave /t funcs1,funcs2 wave funcpos1,funcpos2 n=numpnts(funcs1) for (i=0;i0) pre1+="\t"+dec1[i]+" = "+dec1vals[i]+"\r" else pre1+="\t"+dec1[i]+"\r" endif elseif (!literal_match(dec1vals[i],dec2vals[match])) pred+="\t"+dec1[i]+" = "+dec1vals[i]+" | "+dec2vals[match]+"\r" endif endfor n=numpnts(dec2) for (i=0;i0) pre2+="\t"+dec2[i]+" = "+dec2vals[i]+"\r" // acw edited this line dec2vals -> dec2vals[i] else pre2+="\t"+dec2[i]+"\r" endif endif endfor npu1=itemsinlist(pre1,"\r") npu2=itemsinlist(pre2,"\r") npd=itemsinlist(pred,"\r") // Display the report if (itemsinlist(winlist("ipfreport",";","WIN:16"))>0) dowindow /f ipfreport notebook ipfreport selection={endoffile,endoffile} else newnotebook /f=0/n=ipfreport as "IPF report" endif notebook ipfreport text="IPF comparison report "+secs2date(DateTime,0)+" "+secs2time(DateTime,2)+"\r\r" getfilefolderinfo /q filename1 notebook ipfreport text=plat_path(filename1)+"\rCreated "+secs2date(V_creationDate,0)+" " notebook ipfreport text=secs2time(V_creationDate,2)+"\rModified "+secs2date(V_modificationDate,0) notebook ipfreport text=" "+secs2time(V_modificationDate,2)+"\r"+num2istr(bytes1)+" bytes, " notebook ipfreport text=num2istr(lines1)+" lines\rFile contains "+num2istr(numpnts(funcs1)) notebook ipfreport text=" functions ("+num2istr(nu1)+" unique)\r"+uni1+num2istr(numpnts(dec1)) notebook ipfreport text=" declarations ("+num2istr(npu1)+" unique)\r"+pre1+"\r" getfilefolderinfo /q filename2 notebook ipfreport text=plat_path(filename2)+"\rCreated "+secs2date(V_creationDate,0)+" " notebook ipfreport text=secs2time(V_creationDate,2)+"\rModified "+secs2date(V_modificationDate,0) notebook ipfreport text=" "+secs2time(V_modificationDate,2)+"\r"+num2istr(bytes2)+" bytes, " notebook ipfreport text=num2istr(lines2)+" lines\rFile contains "+num2istr(numpnts(funcs2)) notebook ipfreport text=" functions ("+num2istr(nu2)+" unique)\r"+uni2+num2istr(numpnts(dec2)) notebook ipfreport text=" declarations ("+num2istr(npu2)+" unique)\r"+pre2+"\r" notebook ipfreport text=num2istr(nd)+" common functions contain differences\r"+diff+"\r" notebook ipfreport text=num2istr(npd)+" common declarations are different\r"+pred+"\r" else doalert 0, "Files were not opened successfully or cancel was pressed" endif // Tidy up closeifopen(file1) closeifopen(file2) killwaves /z chardiff_tmp setdatafolder datafolder end function closeifopen(file) // Close a file if it's open (duh!) variable file fstatus file if (v_flag) close file endif end function findstr_wav(str,wav) // Find a match for a string in a text wave string str wave /t wav variable found=-1,i,n=numpnts(wav) for (i=0;i=v_logeof) poswav[funcno-1][1]=v_logeof bytes=v_logeof break endif i=0 // Check to see if a line contains a function declaration do prefix=stringfromlist(i,PREF_LIST) funcpos=strsearch(fileline,prefix,0,2) if (funcpos!=-1) if (funcpos>0) prefix=replacestring("static ",fileline[0,funcpos-1],"",0,1) prefix=replacestring(" ",prefix,"") if (strlen(prefix)>0) funcpos=-1 endif endif endif i+=1 while (funcpos==-1 && i0) poswav[funcno-1][1]=lastpos endif funcno+=1 endif endif while(1) end function strsearch_end(str,searchstr,start,[options]) // Same at strsearch, only returns the length of the string instead of -1 if not found string str,searchstr variable start,options variable ans if (paramisdefault(options)) ans=strsearch(str,searchstr,start) else ans=strsearch(str,searchstr,start,options) endif return ans>-1?(ans):strlen(str) end function func_compare(file1,file2,start1,start2,end1,end2) // Compare sections of two files variable file1,file2,start1,start2,end1,end2 string line1,line2 variable different=0,pos1,pos2 make /o/n=50 chardiff_tmp=0 fsetpos file1,start1 fsetpos file2,start2 do freadline /n=50 file1,line1 freadline /n=50 file2,line2 chardiff_tmp=abs(char2num(line1[p])-char2num(line2[p])) wavestats /q/m=1 chardiff_tmp if (v_avg>0) different=1 break endif fstatus file1 pos1=v_filepos fstatus file2 pos2=v_filepos while (pos1-1) return str end function literal_match(str1,str2) // Like stringmatch, but without wildcards string str1,str2 variable n1=strlen(str1),n2=strlen(str2),i=0,match=1 if (n1!=n2) match=0 else for (i=0;i