1 """Parameter file is read into memory and modified there"""
2
3 import string,sys
4
5 from FileBasis import FileBasisBackup
6
8 """ Parameterfile whose complete representation is read into
9 memory, can be manipulated and afterwards written to disk"""
10
11 - def __init__(self,name,backup=False,debug=False):
12 """@param name: The name of the parameter file
13 @param backup: create a backup-copy of the file"""
14
15 FileBasisBackup.__init__(self,name,backup=backup)
16 self.debug=debug
17
18 self.header=None
19
20 self.readFile()
21
22 if self.content.has_key("FoamFile"):
23 self.header={ "FoamFile" : self.content["FoamFile"] }
24 self.content.pop("FoamFile")
25
27 """Constructs a representation of the file"""
28 parser=FoamFileParser(content,debug=self.debug)
29 self.content=parser.getData()
30 return self.content
31
33 """Generates a string from the contents in memory"""
34 string="// File generated by PyFoam - sorry for the ugliness\n\n"
35 if self.header:
36 generator=FoamFileGenerator(self.header)
37 string+=generator.makeString()
38 string+="\n// End of header\n\n"
39
40 generator=FoamFileGenerator(self.content)
41 string+=generator.makeString()
42
43 return string
44
46 """Class that parses a string that contains the contents of an
47 OpenFOAM-file and bilds a nested structure of directories and
48 lists from it"""
49
51 """@param content: the string to be parsed
52 @param debug: output debug information during parsing"""
53
54 self.data=None
55 self.debug=debug
56 content=self.rmComments(content)
57 self.data,ind=self.parseDict(content,0)
58
60 """ Get the data structure"""
61 return self.data
62
64 """Get the next character from a string (if there is any)
65 @param c: the string
66 @param ind: the current index
67 @return: the character (empty string if past the end) and the new index"""
68
69 if self.isOK(c,ind):
70
71 return c[ind],ind+1
72 else:
73 return "",ind
74
76 if self.isOK(c,ind):
77 return c[ind]
78 else:
79 return ""
80
81 - def isOK(self,c,ind):
82 """Check whether there are still characters in the string"""
83
84
85 return ind<len(c)
86
88 """Skip spaces and set index to the next non-whitespace character
89 @return: The index of the next non-whitespace character"""
90
91 while self.isOK(c,ind) and string.whitespace.find(self.peekChar(c,ind))>=0:
92
93 ind+=1
94
95 return ind
96
98 """Gets a name for a dictionary entry
99 @return: name and index of the next char after it"""
100 name=""
101
102 first=True
103
104 while self.isOK(c,ind):
105 if first:
106 first=False
107 z=self.peekChar(c,ind)
108 if string.digits.find(z)>=0:
109 return name,ind
110
111 z,ind=self.getChar(c,ind)
112 if string.whitespace.find(z)>=0:
113 break
114 elif z==";":
115 ind-=1
116 break
117 else:
118 name+=z
119
120 if self.debug:
121 print "Got Name:",name
122
123 return name,ind
124
126 """Get a quoted string and return it (including the quotes)"""
127
128 z,ind=self.getChar(c,ind)
129 prev=z
130 qs=z
131
132 while self.isOK(c,ind):
133 z,ind=self.getChar(c,ind)
134 qs+=z
135 if z!="\"" and prev!="\\":
136 prev=z
137 else:
138 if self.peekChar(c,ind)==";":
139 break
140 else:
141 prev=z
142
143 if self.debug:
144 print "Got String:",qs
145
146 return qs,ind
147
149 """Look-ahead to find out whether the next thing is a list"""
150
151 z=self.peekChar(c,ind)
152 if z=="(":
153 return True,ind+1
154 elif string.digits.find(z)<0 and c.find("List",ind)==ind:
155 return False,ind
156 else:
157 indOld=ind
158 while self.isOK(c,ind):
159 z,ind=self.getChar(c,ind)
160 if z=="(":
161 break
162 elif z==";":
163 break
164 if z=="(":
165 return True,ind
166 else:
167 return False,indOld
168
170 """Parse a list"""
171 data=[]
172
173 while self.isOK(c,ind):
174 d=None
175 ind=self.skipSpace(c,ind)
176 z=self.peekChar(c,ind)
177 if z==")":
178 ind+=1
179 ind=self.skipSpace(c,ind)
180 z,ind=self.getChar(c,ind)
181 if z!=";":
182
183
184 if not self.isOK(c,ind):
185
186 pass
187 else:
188 self.parserError("';' expected in parseList",c,ind)
189 break
190 elif z=="{":
191 d,ind=self.parseDict(c,ind+1)
192 ind=self.skipSpace(c,ind)
193 z,ind=self.getChar(c,ind)
194 if z!="}":
195 self.parserError("'}' expected",c,ind)
196 elif z=="(":
197 d,ind=self.parseList(c,ind+1)
198 elif z=="\"":
199 d,ind=self.getString(c,ind)
200 else:
201 d,ind=self.getValue(c,ind)
202
203
204 if self.debug:
205 print "Appending:",d,"to list"
206
207 data.append(d)
208
209 return data,ind
210
212 """Get characters up to the next white-space"""
213 v=""
214 while self.isOK(c,ind):
215 z,ind=self.getChar(c,ind)
216 if string.whitespace.find(z)>=0:
217 ind-=1
218 break
219 else:
220 v+=z
221
222 if self.debug:
223 print "Got Value:",v
224
225 return v,ind
226
228 """Parse a value that ends withe semi-colon"""
229 data=""
230
231 while self.isOK(c,ind):
232 z,ind=self.getChar(c,ind)
233 if z==";":
234 break
235 else:
236 data+=z
237
238 if self.debug:
239 print "Parsed value:",data
240
241 return data,ind
242
243 - def printContext(self,c,ind):
244 """Prints the context of the current index"""
245 print "------"
246 print c[max(0,ind-100):max(0,ind-1)]
247 print "------"
248 print ">",c[ind-1],"<"
249 print "------"
250 print c[min(len(c),ind):min(len(c),ind+100)]
251 print "------"
252
254 """Prints the error message of the parser and exit"""
255 print "PARSER ERROR:",text
256 print "On index",ind
257 self.printContext(c,ind)
258 raise ParseError
259 sys.exit(-1)
260
262 """Parse assuming a dictionary
263 @param c: the string that is to be parsed
264 @param ind: index of the next chatacter to analyze"""
265
266 data={}
267 nrAnonym=1
268
269 while self.isOK(c,ind):
270 name=""
271 d=None
272
273 ind=self.skipSpace(c,ind)
274
275 z=self.peekChar(c,ind)
276 if z=="}":
277 break
278 name,ind=self.getName(c,ind)
279 ind=self.skipSpace(c,ind)
280 z=self.peekChar(c,ind)
281 if z=="{":
282 d,ind=self.parseDict(c,ind+1)
283
284
285 ind=self.skipSpace(c,ind)
286 z,ind=self.getChar(c,ind)
287 if z!="}":
288 print d
289 self.parserError("'}' expected",c,ind)
290 elif z=="\"":
291 d,ind=self.getString(c,ind)
292 ind=self.skipSpace(c,ind)
293 z,ind=self.getChar(c,ind)
294 if z!=";":
295 self.parserError("';' expected",c,ind)
296 elif z==";":
297 z,ind=self.getChar(c,ind)
298 d=""
299 elif c[ind:ind+len("uniform ")]=="uniform ":
300 semiPos=c.find(";",ind+len("uniform "))
301 d=c[ind+len("uniform "):semiPos]
302 ind=semiPos+1
303 else:
304 isLst,ind=self.checkForList(c,ind)
305 if isLst:
306 d,ind=self.parseList(c,ind)
307 else:
308 d,ind=self.parseValue(c,ind)
309
310 if name=="" and d!="":
311 name="anonymValue%03d" % nrAnonym
312 nrAnonym+=1
313
314 if name!="":
315 if self.debug:
316 print "Got Name:",name,"with value:",d
317
318 data[name]=d
319
320
321 return data,ind
322
362
364 """Class that generates a OpenFOAM-compatible representation of a
365 data-structure"""
366
368 self.data=data
369
372
374 s=""
375 for k,v in dic.iteritems():
376 if k.find("anonymValue")==0:
377 k=""
378
379 s+=(" "*indent)+k
380 if type(v)==str:
381 s+=" "+v+";\n"
382 elif type(v)==dict:
383 s+="\n"+(" "*indent)+"{\n"
384 s+=self.strDict(v,indent+2)
385 s+="\n"+(" "*indent)+"}\n"
386 elif type(v)==list:
387 s+="\n"
388 s+=self.strList(v,indent+2)
389 else:
390 s+=" "+str(v)+";\n"
391
392 return s
393
395 s=""
396
397 theLen=len(lst)
398
399 if len(lst)>2 and len(lst)%2==0:
400 if type(lst[0])==str and type(lst[1])==dict:
401 theLen=len(lst)/2
402
403 s+=(" "*indent)+str(theLen)+"\n"
404 s+=(" "*indent)+"(\n"
405 for v in lst:
406 if type(v)==str:
407 s+=(" "*(indent+2))+v+"\n"
408 elif type(v)==dict:
409 s+="\n"+(" "*(indent+2))+"{\n"
410 s+=self.strDict(v,indent+4)
411 s+="\n"+(" "*(indent+2))+"}\n"
412 elif type(v)==list:
413 s+="\n"
414 s+=self.strList(v,indent+2)
415 else:
416 s+=(" "*(indent+2))+str(v)+"\n"
417
418 s+=(" "*indent)+");\n"
419
420 return s
421