1
2 """
3 Application class that implements pyFoamCompareDictionary.py
4 """
5
6 import re
7 from os import path
8
9 from PyFoamApplication import PyFoamApplication
10
11 from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile,PyFoamParserError
12 from PyFoam.Basics.DataStructures import DictProxy,Dimension,Tensor,SymmTensor,Vector,Field,TupleProxy
13 from PyFoam.Basics.FoamFileGenerator import makeString
14
15 from PyFoam.Error import error,warning
16
17 from CommonParserOptions import CommonParserOptions
18
19 from PyFoam.Basics.TerminalFormatter import TerminalFormatter
20
21 f=TerminalFormatter()
22 f.getConfigFormat("source",shortName="src")
23 f.getConfigFormat("destination",shortName="dst")
24 f.getConfigFormat("difference",shortName="diff")
25 f.getConfigFormat("error",shortName="name")
26
30 description="""\
31 Takes two dictionary and compares them semantically (by looking at the
32 structure, not the textual representation. If the dictionaries do not
33 have the same name, it looks for the destination file by searching the
34 equivalent place in the destination case. If more than two files are
35 specified then the last name is assumed to be a directory and all the
36 equivalents to the other files are searched there.
37 """
38
39 PyFoamApplication.__init__(self,
40 args=args,
41 description=description,
42 usage="%prog [options] <source> <destination-case>",
43 nr=2,
44 exactNr=False,
45 interspersed=True)
46
48 self.parser.add_option("--not-equal",
49 action="store_true",
50 default=False,
51 dest="notequal",
52 help="Allow source and destination to have different names")
53 self.parser.add_option("--debug",
54 action="store_true",
55 default=False,
56 dest="debug",
57 help="Debug the comparing process")
58 self.parser.add_option("--long-field-threshold",
59 action="store",
60 type="int",
61 default=None,
62 dest="longlist",
63 help="Fields that are longer than this won't be parsed, but read into memory (and compared as strings)")
64
65 CommonParserOptions.addOptions(self)
66
67
68
70 sFiles=self.parser.getArgs()[0:-1]
71 dFile=path.abspath(self.parser.getArgs()[-1])
72
73 for s in sFiles:
74 sName=path.abspath(s)
75 dName=dFile
76
77 if len(s)>1:
78 print f.name+"Source file",sName,f.reset
79 try:
80 source=ParsedParameterFile(sName,
81 backup=False,
82 debug=self.opts.debugParser,
83 listLengthUnparsed=self.opts.longlist,
84 noBody=self.opts.noBody,
85 noHeader=self.opts.noHeader,
86 boundaryDict=self.opts.boundaryDict,
87 listDict=self.opts.listDict,
88 listDictWithHeader=self.opts.listDictWithHeader)
89 except IOError,e:
90 self.warning("Problem with file",sName,":",e)
91 continue
92 except PyFoamParserError,e:
93 self.warning("Parser problem with",sName,":",e)
94 continue
95
96 found=False
97
98 if path.isfile(sName) and path.isfile(dName):
99 found=True
100
101 if not found and not self.opts.notequal and path.basename(sName)!=path.basename(dName):
102 parts=sName.split(path.sep)
103 for i in range(len(parts)):
104 tmp=apply(path.join,[dName]+parts[-(i+1):])
105
106 if path.exists(tmp):
107 found=True
108 dName=tmp
109 warning("Found",dName,"and using this")
110 break
111
112 if not found:
113 error("Could not find a file named",path.basename(sName),"in",dName)
114
115 if path.samefile(sName,dName):
116 error("Source",sName,"and destination",dName,"are the same")
117
118 try:
119 dest=ParsedParameterFile(dName,
120 backup=False,
121 debug=self.opts.debugParser,
122 listLengthUnparsed=self.opts.longlist,
123 noBody=self.opts.noBody,
124 noHeader=self.opts.noHeader,
125 boundaryDict=self.opts.boundaryDict,
126 listDict=self.opts.listDict,
127 listDictWithHeader=self.opts.listDictWithHeader)
128 except IOError,e:
129 self.error("Problem with file",dName,":",e)
130
131 self.pling=False
132
133 if not self.opts.boundaryDict and not self.opts.listDict and not self.opts.listDictWithHeader:
134 self.compareDict(source.content,dest.content,1,path.basename(sName))
135 else:
136 self.compareIterable(source.content,dest.content,1,path.basename(sName))
137
138 if not self.pling:
139 print "\nNo differences found"
140
143
146
147 - def compare(self,src,dst,depth,name):
148 if type(src)!=type(dst):
149 print f.diff+">><<",name,": Types differ"+f.reset+"\n+"+f.src+">>Source:"+f.reset+"\n",makeString(src),"\n"+f.dst+"<<Destination:"+f.reset+"\n",makeString(dst)+f.reset
150 self.pling=True
151 elif type(src) in [tuple,list,TupleProxy]:
152 self.compareIterable(src,dst,depth,name)
153 elif type(src) in [str,float,int,long,type(None)]:
154 self.comparePrimitive(src,dst,depth,name)
155 elif src.__class__ in [Dimension,Tensor,SymmTensor,Vector]:
156 self.comparePrimitive(src,dst,depth,name)
157 elif src.__class__==Field:
158 self.compareField(src,dst,depth,name)
159 elif type(src) in [DictProxy,dict]:
160 self.compareDict(src,dst,depth,name)
161 else:
162 warning("Type of",name,"=",type(src),"unknown")
163 if self.opts.debug:
164 try:
165 print "Class of",name,"=",src.__class__,"unknown"
166 except:
167 pass
168
170 if src!=dst:
171 self.pling=True
172 print f.diff+">><< Field",name,": Differs"+f.reset+"\n"+f.src+">>Source:"+f.reset+"\n",
173 if src.uniform:
174 print src
175 else:
176 print "nonuniform - field not printed"
177 print f.dst+"<<Destination:"+f.reset+"\n",
178 if dst.uniform:
179 print dst
180 else:
181 print "nonuniform - field not printed"
182
184 if src!=dst:
185 print f.diff+">><<",name,": Differs"+f.reset+"\n"+f.src+">>Source:"+f.reset+"\n",src,"\n"+f.dst+"<<Destination:"+f.reset+"\n",dst
186 self.pling=True
187
189 nr=min(len(src),len(dst))
190
191 for i in range(nr):
192 if self.opts.debug:
193 print "Comparing",self.iterString(name,i)
194 self.compare(src[i],dst[i],depth+1,self.iterString(name,i))
195
196 if nr<len(src):
197 print f.src+">>>>",self.iterString(name,nr),"to",self.iterString(name,len(src)-1),"missing from destination\n"+f.reset,makeString(src[nr:])
198 self.pling=True
199 elif nr<len(dst):
200 print f.dst+"<<<<",self.iterString(name,nr),"to",self.iterString(name,len(dst)-1),"missing from source\n"+f.reset,makeString(dst[nr:])
201 self.pling=True
202
204 for n in src:
205 if not n in dst:
206 print f.src+">>>>",self.dictString(name,n),": Missing from destination\n"+f.reset,makeString(src[n])
207 self.pling=True
208 else:
209 if self.opts.debug:
210 print "Comparing",self.dictString(name,n)
211 self.compare(src[n],dst[n],depth+1,self.dictString(name,n))
212
213 for n in dst:
214 if not n in src:
215 print f.dst+"<<<<",self.dictString(name,n),": Missing from source\n"+f.reset,makeString(dst[n])
216 self.pling=True
217