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
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
22 description="""
23 Takes two dictionary and compares them semantically (by looking at the
24 structure, not the textual representation. If the dictionaries do not
25 have the same name, it looks for the destination file by searching the
26 equivalent place in the destination case
27 """
28
29 PyFoamApplication.__init__(self,args=args,description=description,usage="%prog [options] <source> <destination-case>",nr=2,interspersed=True)
30
32 self.parser.add_option("--not-equal",
33 action="store_true",
34 default=False,
35 dest="notequal",
36 help="Allow source and destination to have different names")
37 self.parser.add_option("--debug",
38 action="store_true",
39 default=False,
40 dest="debug",
41 help="Debug the comparing process")
42 self.parser.add_option("--long-field-threshold",
43 action="store",
44 type="int",
45 default=None,
46 dest="longlist",
47 help="Fields that are longer than this won't be parsed, but read into memory (and compared as strings)")
48
49 CommonParserOptions.addOptions(self)
50
51
52
54 sName=path.abspath(self.parser.getArgs()[0])
55 dName=path.abspath(self.parser.getArgs()[1])
56
57 try:
58 source=ParsedParameterFile(sName,
59 backup=False,
60 debug=self.opts.debugParser,
61 listLengthUnparsed=self.opts.longlist,
62 noBody=self.opts.noBody,
63 noHeader=self.opts.noHeader,
64 boundaryDict=self.opts.boundaryDict,
65 listDict=self.opts.listDict)
66 except IOError,e:
67 self.error("Problem with file",sName,":",e)
68
69 found=False
70
71 if path.isfile(sName) and path.isfile(dName):
72 found=True
73
74 if not found and not self.opts.notequal and path.basename(sName)!=path.basename(dName):
75 parts=sName.split(path.sep)
76 for i in range(len(parts)):
77 tmp=apply(path.join,[dName]+parts[-(i+1):])
78
79 if path.exists(tmp):
80 found=True
81 dName=tmp
82 warning("Found",dName,"and using this")
83 break
84
85 if not found:
86 error("Could not find a file named",path.basename(sName),"in",dName)
87
88 if path.samefile(sName,dName):
89 error("Source",sName,"and destination",dName,"are the same")
90
91 try:
92 dest=ParsedParameterFile(dName,
93 backup=False,
94 debug=self.opts.debugParser,
95 listLengthUnparsed=self.opts.longlist,
96 noBody=self.opts.noBody,
97 noHeader=self.opts.noHeader,
98 boundaryDict=self.opts.boundaryDict,
99 listDict=self.opts.listDict)
100 except IOError,e:
101 self.error("Problem with file",dName,":",e)
102
103 self.pling=False
104
105 if not self.opts.boundaryDict and not self.opts.listDict:
106 self.compareDict(source.content,dest.content,1,path.basename(sName))
107 else:
108 self.compareIterable(source.content,dest.content,1,path.basename(sName))
109
110 if not self.pling:
111 print "\nNo differences found"
112
114 return "%s[%s]" % (path,name)
115
117 return "%s[%d]" % (path,index)
118
119 - def compare(self,src,dst,depth,name):
120 if type(src)!=type(dst):
121 print ">><<",name,": Types differ\n>>Source:\n",makeString(src),"\n<<Destination:\n",makeString(dst)
122 self.pling=True
123 elif type(src) in [tuple,list,TupleProxy]:
124 self.compareIterable(src,dst,depth,name)
125 elif type(src) in [str,float,int,long,type(None)]:
126 self.comparePrimitive(src,dst,depth,name)
127 elif src.__class__ in [Dimension,Tensor,SymmTensor,Vector]:
128 self.comparePrimitive(src,dst,depth,name)
129 elif src.__class__==Field:
130 self.compareField(src,dst,depth,name)
131 elif type(src) in [DictProxy,dict]:
132 self.compareDict(src,dst,depth,name)
133 else:
134 warning("Type of",name,"=",type(src),"unknown")
135 if self.opts.debug:
136 try:
137 print "Class of",name,"=",src.__class__,"unknown"
138 except:
139 pass
140
142 if src!=dst:
143 self.pling=True
144 print ">><< Field",name,": Differs\n>>Source:\n",
145 if src.uniform:
146 print src
147 else:
148 print "nonuniform - field not printed"
149 print "<<Destination:\n",
150 if dst.uniform:
151 print dst
152 else:
153 print "nonuniform - field not printed"
154
156 if src!=dst:
157 print ">><<",name,": Differs\n>>Source:\n",src,"\n<<Destination:\n",dst
158 self.pling=True
159
161 nr=min(len(src),len(dst))
162
163 for i in range(nr):
164 if self.opts.debug:
165 print "Comparing",self.iterString(name,i)
166 self.compare(src[i],dst[i],depth+1,self.iterString(name,i))
167
168 if nr<len(src):
169 print ">>>>",self.iterString(name,nr),"to",self.iterString(name,len(src)-1),"missing from destination\n",makeString(src[nr:])
170 self.pling=True
171 elif nr<len(dst):
172 print "<<<<",self.iterString(name,nr),"to",self.iterString(name,len(dst)-1),"missing from source\n",makeString(dst[nr:])
173 self.pling=True
174
176 for n in src:
177 if not n in dst:
178 print ">>>>",self.dictString(name,n),": Missing from destination\n",makeString(src[n])
179 self.pling=True
180 else:
181 if self.opts.debug:
182 print "Comparing",self.dictString(name,n)
183 self.compare(src[n],dst[n],depth+1,self.dictString(name,n))
184
185 for n in dst:
186 if not n in src:
187 print "<<<<",self.dictString(name,n),": Missing from source\n",makeString(dst[n])
188 self.pling=True
189