66import string
77import path
88import sys
9- import fl
109import FL
1110
1211SPLITLINE = '--------------------'
2322# Externally visible function. Load form.
2423#
2524def parse_form (filename , formname ):
25+ forms = checkcache (filename )
26+ if forms != None :
27+ if forms .has_key (formname ):
28+ return forms [formname ]
29+ else :
30+ forms = {}
2631 fp = _open_formfile (filename )
2732 nforms = _parse_fd_header (fp )
2833 for i in range (nforms ):
2934 form = _parse_fd_form (fp , formname )
3035 if form <> None :
31- return form
32- raise error , 'No such form in fd file'
36+ break
37+ else :
38+ raise error , 'No such form in fd file'
39+ forms [formname ] = form
40+ writecache (filename , forms )
41+ return form
3342
3443#
3544# Externally visible function. Load all forms.
3645#
3746def parse_forms (filename ):
47+ forms = checkcache (filename )
48+ if forms != None : return forms
3849 fp = _open_formfile (filename )
3950 nforms = _parse_fd_header (fp )
4051 forms = {}
4152 for i in range (nforms ):
4253 form = _parse_fd_form (fp , None )
4354 forms [form [0 ].Name ] = form
55+ writecache (filename , forms )
4456 return forms
57+
58+ #
59+ # Internal: see if a cached version of the file exists
60+ #
61+ MAGIC = '.fdc'
62+ def checkcache (filename ):
63+ import marshal
64+ fp , filename = _open_formfile2 (filename )
65+ fp .close ()
66+ cachename = filename + 'c'
67+ try :
68+ fp = open (cachename , 'r' )
69+ except IOError :
70+ print 'flp: no cache file' , cachename
71+ return None
72+ try :
73+ if fp .read (4 ) != MAGIC :
74+ print 'flp: bad magic word in cache file' , cachename
75+ return None
76+ cache_mtime = rdlong (fp )
77+ file_mtime = getmtime (filename )
78+ if cache_mtime != file_mtime :
79+ print 'flp: outdated cache file' , cachename
80+ return None
81+ print 'flp: valid cache file' , cachename
82+ altforms = marshal .load (fp )
83+ forms = {}
84+ for name in altforms .keys ():
85+ altobj , altlist = altforms [name ]
86+ obj = _newobj ().init ()
87+ obj .make (altobj )
88+ list = []
89+ for altobj in altlist :
90+ nobj = _newobj ().init ()
91+ nobj .make (altobj )
92+ list .append (nobj )
93+ forms [name ] = obj , list
94+ return forms
95+ finally :
96+ fp .close ()
97+
98+ def rdlong (fp ):
99+ s = fp .read (4 )
100+ if len (s ) != 4 : return None
101+ a , b , c , d = s [0 ], s [1 ], s [2 ], s [3 ]
102+ return ord (a )<< 24 | ord (b )<< 16 | ord (c )<< 8 | ord (d )
103+
104+ def wrlong (fp , x ):
105+ a , b , c , d = (x >> 24 )& 0xff , (x >> 16 )& 0xff , (x >> 8 )& 0xff , x & 0xff
106+ fp .write (chr (a ) + chr (b ) + chr (c ) + chr (d ))
107+
108+ def getmtime (filename ):
109+ import posix
110+ from stat import ST_MTIME
111+ try :
112+ return posix .stat (filename )[ST_MTIME ]
113+ except posix .error :
114+ return None
115+
116+ #
117+ # Internal: write cached version of the form (parsing is too slow!)
118+ #
119+ def writecache (filename , forms ):
120+ import marshal
121+ fp , filename = _open_formfile2 (filename )
122+ fp .close ()
123+ cachename = filename + 'c'
124+ try :
125+ fp = open (cachename , 'w' )
126+ except IOError :
127+ print 'flp: can\' t create cache file' , cachename
128+ return # Never mind
129+ fp .write ('\0 \0 \0 \0 ' ) # Seek back and write MAGIC when done
130+ wrlong (fp , getmtime (filename ))
131+ altforms = {}
132+ for name in forms .keys ():
133+ obj , list = forms [name ]
134+ altobj = obj .__dict__
135+ altlist = []
136+ for obj in list : altlist .append (obj .__dict__ )
137+ altforms [name ] = altobj , altlist
138+ marshal .dump (altforms , fp )
139+ fp .seek (0 )
140+ fp .write (MAGIC )
141+ fp .close ()
142+ print 'flp: wrote cache file' , cachename
45143
46144#
47145# Internal: Locate form file (using PYTHONPATH) and open file
48146#
49147def _open_formfile (filename ):
148+ return _open_formfile2 (filename )[0 ]
149+
150+ def _open_formfile2 (filename ):
50151 if filename [- 3 :] <> '.fd' :
51152 filename = filename + '.fd'
52153 if filename [0 ] == '/' :
@@ -59,12 +160,13 @@ def _open_formfile(filename):
59160 pn = path .join (pc , filename )
60161 try :
61162 fp = open (pn , 'r' )
163+ filename = pn
62164 break
63165 except IOError :
64166 fp = None
65167 if fp == None :
66168 raise error , 'Cannot find forms file ' + filename
67- return fp
169+ return fp , filename
68170
69171#
70172# Internal: parse the fd file header, return number of forms
@@ -107,8 +209,10 @@ class _newobj:
107209 def init (self ):
108210 return self
109211 def add (self , (name , value )):
110- cmd = 'self.' + name + ' = ' + `value` + '\n '
111- exec (cmd )
212+ self .__dict__ [name ] = value
213+ def make (self , dict ):
214+ for name in dict .keys ():
215+ self .add (name , dict [name ])
112216
113217#
114218# Internal parsing routines.
@@ -225,7 +329,8 @@ def merge_full_form(inst, form, (fdata, odatalist)):
225329# External Create_form - Create form from parameters
226330#
227331def create_form (fdata ):
228- return fl .make_form (FL .NO_BOX ,fdata .Width , fdata .Height )
332+ import fl
333+ return fl .make_form (FL .NO_BOX , fdata .Width , fdata .Height )
229334
230335#
231336# External create_object - Create an object. Make sure there are
@@ -292,12 +397,20 @@ def _select_crfunc(fm, cl):
292397
293398
294399def test ():
400+ import time
401+ t0 = time .millitimer ()
295402 if len (sys .argv ) == 2 :
296403 forms = parse_forms (sys .argv [1 ])
297- for i in forms .keys ():
404+ t1 = time .millitimer ()
405+ print 'parse time:' , 0.001 * (t1 - t0 ), 'sec.'
406+ keys = forms .keys ()
407+ keys .sort ()
408+ for i in keys :
298409 _printform (forms [i ])
299410 elif len (sys .argv ) == 3 :
300411 form = parse_form (sys .argv [1 ], sys .argv [2 ])
412+ t1 = time .millitimer ()
413+ print 'parse time:' , 0.001 * (t1 - t0 ), 'sec.'
301414 _printform (form )
302415 else :
303416 print 'Usage: test fdfile [form]'
@@ -312,3 +425,7 @@ def _printform(form):
312425 print ' Label ' , i .Label , ' size/style/col/align ' , i .Size ,i .Style , i .Lcol , i .Alignment
313426 print ' cols ' , i .Colors
314427 print ' cback ' , i .Callback , i .Argument
428+
429+ # Local variables:
430+ # py-indent-offset: 4
431+ # end:
0 commit comments