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