PageRenderTime 142ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/lib-python/2.7/plat-irix5/flp.py

https://bitbucket.org/kkris/pypy
Python | 455 lines | 382 code | 19 blank | 54 comment | 43 complexity | c6efa6754cd783c43776048b6e46c7c7 MD5 | raw file
  1. #
  2. # flp - Module to load fl forms from fd files
  3. #
  4. # Jack Jansen, December 1991
  5. #
  6. from warnings import warnpy3k
  7. warnpy3k("the flp module has been removed in Python 3.0", stacklevel=2)
  8. del warnpy3k
  9. import string
  10. import os
  11. import sys
  12. import FL
  13. SPLITLINE = '--------------------'
  14. FORMLINE = '=============== FORM ==============='
  15. ENDLINE = '=============================='
  16. class error(Exception):
  17. pass
  18. ##################################################################
  19. # Part 1 - The parsing routines #
  20. ##################################################################
  21. #
  22. # Externally visible function. Load form.
  23. #
  24. def parse_form(filename, formname):
  25. forms = checkcache(filename)
  26. if forms is None:
  27. forms = parse_forms(filename)
  28. if forms.has_key(formname):
  29. return forms[formname]
  30. else:
  31. raise error, 'No such form in fd file'
  32. #
  33. # Externally visible function. Load all forms.
  34. #
  35. def parse_forms(filename):
  36. forms = checkcache(filename)
  37. if forms is not None: return forms
  38. fp = _open_formfile(filename)
  39. nforms = _parse_fd_header(fp)
  40. forms = {}
  41. for i in range(nforms):
  42. form = _parse_fd_form(fp, None)
  43. forms[form[0].Name] = form
  44. writecache(filename, forms)
  45. return forms
  46. #
  47. # Internal: see if a cached version of the file exists
  48. #
  49. MAGIC = '.fdc'
  50. _internal_cache = {} # Used by frozen scripts only
  51. def checkcache(filename):
  52. if _internal_cache.has_key(filename):
  53. altforms = _internal_cache[filename]
  54. return _unpack_cache(altforms)
  55. import marshal
  56. fp, filename = _open_formfile2(filename)
  57. fp.close()
  58. cachename = filename + 'c'
  59. try:
  60. fp = open(cachename, 'r')
  61. except IOError:
  62. #print 'flp: no cache file', cachename
  63. return None
  64. try:
  65. if fp.read(4) != MAGIC:
  66. print 'flp: bad magic word in cache file', cachename
  67. return None
  68. cache_mtime = rdlong(fp)
  69. file_mtime = getmtime(filename)
  70. if cache_mtime != file_mtime:
  71. #print 'flp: outdated cache file', cachename
  72. return None
  73. #print 'flp: valid cache file', cachename
  74. altforms = marshal.load(fp)
  75. return _unpack_cache(altforms)
  76. finally:
  77. fp.close()
  78. def _unpack_cache(altforms):
  79. forms = {}
  80. for name in altforms.keys():
  81. altobj, altlist = altforms[name]
  82. obj = _newobj()
  83. obj.make(altobj)
  84. list = []
  85. for altobj in altlist:
  86. nobj = _newobj()
  87. nobj.make(altobj)
  88. list.append(nobj)
  89. forms[name] = obj, list
  90. return forms
  91. def rdlong(fp):
  92. s = fp.read(4)
  93. if len(s) != 4: return None
  94. a, b, c, d = s[0], s[1], s[2], s[3]
  95. return ord(a)<<24 | ord(b)<<16 | ord(c)<<8 | ord(d)
  96. def wrlong(fp, x):
  97. a, b, c, d = (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff
  98. fp.write(chr(a) + chr(b) + chr(c) + chr(d))
  99. def getmtime(filename):
  100. import os
  101. from stat import ST_MTIME
  102. try:
  103. return os.stat(filename)[ST_MTIME]
  104. except os.error:
  105. return None
  106. #
  107. # Internal: write cached version of the form (parsing is too slow!)
  108. #
  109. def writecache(filename, forms):
  110. import marshal
  111. fp, filename = _open_formfile2(filename)
  112. fp.close()
  113. cachename = filename + 'c'
  114. try:
  115. fp = open(cachename, 'w')
  116. except IOError:
  117. print 'flp: can\'t create cache file', cachename
  118. return # Never mind
  119. fp.write('\0\0\0\0') # Seek back and write MAGIC when done
  120. wrlong(fp, getmtime(filename))
  121. altforms = _pack_cache(forms)
  122. marshal.dump(altforms, fp)
  123. fp.seek(0)
  124. fp.write(MAGIC)
  125. fp.close()
  126. #print 'flp: wrote cache file', cachename
  127. #
  128. # External: print some statements that set up the internal cache.
  129. # This is for use with the "freeze" script. You should call
  130. # flp.freeze(filename) for all forms used by the script, and collect
  131. # the output on a file in a module file named "frozenforms.py". Then
  132. # in the main program of the script import frozenforms.
  133. # (Don't forget to take this out when using the unfrozen version of
  134. # the script!)
  135. #
  136. def freeze(filename):
  137. forms = parse_forms(filename)
  138. altforms = _pack_cache(forms)
  139. print 'import flp'
  140. print 'flp._internal_cache[', repr(filename), '] =', altforms
  141. #
  142. # Internal: create the data structure to be placed in the cache
  143. #
  144. def _pack_cache(forms):
  145. altforms = {}
  146. for name in forms.keys():
  147. obj, list = forms[name]
  148. altobj = obj.__dict__
  149. altlist = []
  150. for obj in list: altlist.append(obj.__dict__)
  151. altforms[name] = altobj, altlist
  152. return altforms
  153. #
  154. # Internal: Locate form file (using PYTHONPATH) and open file
  155. #
  156. def _open_formfile(filename):
  157. return _open_formfile2(filename)[0]
  158. def _open_formfile2(filename):
  159. if filename[-3:] != '.fd':
  160. filename = filename + '.fd'
  161. if filename[0] == '/':
  162. try:
  163. fp = open(filename,'r')
  164. except IOError:
  165. fp = None
  166. else:
  167. for pc in sys.path:
  168. pn = os.path.join(pc, filename)
  169. try:
  170. fp = open(pn, 'r')
  171. filename = pn
  172. break
  173. except IOError:
  174. fp = None
  175. if fp is None:
  176. raise error, 'Cannot find forms file ' + filename
  177. return fp, filename
  178. #
  179. # Internal: parse the fd file header, return number of forms
  180. #
  181. def _parse_fd_header(file):
  182. # First read the magic header line
  183. datum = _parse_1_line(file)
  184. if datum != ('Magic', 12321):
  185. raise error, 'Not a forms definition file'
  186. # Now skip until we know number of forms
  187. while 1:
  188. datum = _parse_1_line(file)
  189. if type(datum) == type(()) and datum[0] == 'Numberofforms':
  190. break
  191. return datum[1]
  192. #
  193. # Internal: parse fd form, or skip if name doesn't match.
  194. # the special value None means 'always parse it'.
  195. #
  196. def _parse_fd_form(file, name):
  197. datum = _parse_1_line(file)
  198. if datum != FORMLINE:
  199. raise error, 'Missing === FORM === line'
  200. form = _parse_object(file)
  201. if form.Name == name or name is None:
  202. objs = []
  203. for j in range(form.Numberofobjects):
  204. obj = _parse_object(file)
  205. objs.append(obj)
  206. return (form, objs)
  207. else:
  208. for j in range(form.Numberofobjects):
  209. _skip_object(file)
  210. return None
  211. #
  212. # Internal class: a convenient place to store object info fields
  213. #
  214. class _newobj:
  215. def add(self, name, value):
  216. self.__dict__[name] = value
  217. def make(self, dict):
  218. for name in dict.keys():
  219. self.add(name, dict[name])
  220. #
  221. # Internal parsing routines.
  222. #
  223. def _parse_string(str):
  224. if '\\' in str:
  225. s = '\'' + str + '\''
  226. try:
  227. return eval(s)
  228. except:
  229. pass
  230. return str
  231. def _parse_num(str):
  232. return eval(str)
  233. def _parse_numlist(str):
  234. slist = string.split(str)
  235. nlist = []
  236. for i in slist:
  237. nlist.append(_parse_num(i))
  238. return nlist
  239. # This dictionary maps item names to parsing routines.
  240. # If no routine is given '_parse_num' is default.
  241. _parse_func = { \
  242. 'Name': _parse_string, \
  243. 'Box': _parse_numlist, \
  244. 'Colors': _parse_numlist, \
  245. 'Label': _parse_string, \
  246. 'Name': _parse_string, \
  247. 'Callback': _parse_string, \
  248. 'Argument': _parse_string }
  249. # This function parses a line, and returns either
  250. # a string or a tuple (name,value)
  251. import re
  252. prog = re.compile('^([^:]*): *(.*)')
  253. def _parse_line(line):
  254. match = prog.match(line)
  255. if not match:
  256. return line
  257. name, value = match.group(1, 2)
  258. if name[0] == 'N':
  259. name = string.join(string.split(name),'')
  260. name = string.lower(name)
  261. name = string.capitalize(name)
  262. try:
  263. pf = _parse_func[name]
  264. except KeyError:
  265. pf = _parse_num
  266. value = pf(value)
  267. return (name, value)
  268. def _readline(file):
  269. line = file.readline()
  270. if not line:
  271. raise EOFError
  272. return line[:-1]
  273. def _parse_1_line(file):
  274. line = _readline(file)
  275. while line == '':
  276. line = _readline(file)
  277. return _parse_line(line)
  278. def _skip_object(file):
  279. line = ''
  280. while not line in (SPLITLINE, FORMLINE, ENDLINE):
  281. pos = file.tell()
  282. line = _readline(file)
  283. if line == FORMLINE:
  284. file.seek(pos)
  285. def _parse_object(file):
  286. obj = _newobj()
  287. while 1:
  288. pos = file.tell()
  289. datum = _parse_1_line(file)
  290. if datum in (SPLITLINE, FORMLINE, ENDLINE):
  291. if datum == FORMLINE:
  292. file.seek(pos)
  293. return obj
  294. if type(datum) is not type(()) or len(datum) != 2:
  295. raise error, 'Parse error, illegal line in object: '+datum
  296. obj.add(datum[0], datum[1])
  297. #################################################################
  298. # Part 2 - High-level object/form creation routines #
  299. #################################################################
  300. #
  301. # External - Create a form an link to an instance variable.
  302. #
  303. def create_full_form(inst, (fdata, odatalist)):
  304. form = create_form(fdata)
  305. exec 'inst.'+fdata.Name+' = form\n'
  306. for odata in odatalist:
  307. create_object_instance(inst, form, odata)
  308. #
  309. # External - Merge a form into an existing form in an instance
  310. # variable.
  311. #
  312. def merge_full_form(inst, form, (fdata, odatalist)):
  313. exec 'inst.'+fdata.Name+' = form\n'
  314. if odatalist[0].Class != FL.BOX:
  315. raise error, 'merge_full_form() expects FL.BOX as first obj'
  316. for odata in odatalist[1:]:
  317. create_object_instance(inst, form, odata)
  318. #################################################################
  319. # Part 3 - Low-level object/form creation routines #
  320. #################################################################
  321. #
  322. # External Create_form - Create form from parameters
  323. #
  324. def create_form(fdata):
  325. import fl
  326. return fl.make_form(FL.NO_BOX, fdata.Width, fdata.Height)
  327. #
  328. # External create_object - Create an object. Make sure there are
  329. # no callbacks. Returns the object created.
  330. #
  331. def create_object(form, odata):
  332. obj = _create_object(form, odata)
  333. if odata.Callback:
  334. raise error, 'Creating free object with callback'
  335. return obj
  336. #
  337. # External create_object_instance - Create object in an instance.
  338. #
  339. def create_object_instance(inst, form, odata):
  340. obj = _create_object(form, odata)
  341. if odata.Callback:
  342. cbfunc = eval('inst.'+odata.Callback)
  343. obj.set_call_back(cbfunc, odata.Argument)
  344. if odata.Name:
  345. exec 'inst.' + odata.Name + ' = obj\n'
  346. #
  347. # Internal _create_object: Create the object and fill options
  348. #
  349. def _create_object(form, odata):
  350. crfunc = _select_crfunc(form, odata.Class)
  351. obj = crfunc(odata.Type, odata.Box[0], odata.Box[1], odata.Box[2], \
  352. odata.Box[3], odata.Label)
  353. if not odata.Class in (FL.BEGIN_GROUP, FL.END_GROUP):
  354. obj.boxtype = odata.Boxtype
  355. obj.col1 = odata.Colors[0]
  356. obj.col2 = odata.Colors[1]
  357. obj.align = odata.Alignment
  358. obj.lstyle = odata.Style
  359. obj.lsize = odata.Size
  360. obj.lcol = odata.Lcol
  361. return obj
  362. #
  363. # Internal crfunc: helper function that returns correct create function
  364. #
  365. def _select_crfunc(fm, cl):
  366. if cl == FL.BEGIN_GROUP: return fm.bgn_group
  367. elif cl == FL.END_GROUP: return fm.end_group
  368. elif cl == FL.BITMAP: return fm.add_bitmap
  369. elif cl == FL.BOX: return fm.add_box
  370. elif cl == FL.BROWSER: return fm.add_browser
  371. elif cl == FL.BUTTON: return fm.add_button
  372. elif cl == FL.CHART: return fm.add_chart
  373. elif cl == FL.CHOICE: return fm.add_choice
  374. elif cl == FL.CLOCK: return fm.add_clock
  375. elif cl == FL.COUNTER: return fm.add_counter
  376. elif cl == FL.DIAL: return fm.add_dial
  377. elif cl == FL.FREE: return fm.add_free
  378. elif cl == FL.INPUT: return fm.add_input
  379. elif cl == FL.LIGHTBUTTON: return fm.add_lightbutton
  380. elif cl == FL.MENU: return fm.add_menu
  381. elif cl == FL.POSITIONER: return fm.add_positioner
  382. elif cl == FL.ROUNDBUTTON: return fm.add_roundbutton
  383. elif cl == FL.SLIDER: return fm.add_slider
  384. elif cl == FL.VALSLIDER: return fm.add_valslider
  385. elif cl == FL.TEXT: return fm.add_text
  386. elif cl == FL.TIMER: return fm.add_timer
  387. else:
  388. raise error, 'Unknown object type: %r' % (cl,)
  389. def test():
  390. import time
  391. t0 = time.time()
  392. if len(sys.argv) == 2:
  393. forms = parse_forms(sys.argv[1])
  394. t1 = time.time()
  395. print 'parse time:', 0.001*(t1-t0), 'sec.'
  396. keys = forms.keys()
  397. keys.sort()
  398. for i in keys:
  399. _printform(forms[i])
  400. elif len(sys.argv) == 3:
  401. form = parse_form(sys.argv[1], sys.argv[2])
  402. t1 = time.time()
  403. print 'parse time:', round(t1-t0, 3), 'sec.'
  404. _printform(form)
  405. else:
  406. print 'Usage: test fdfile [form]'
  407. def _printform(form):
  408. f = form[0]
  409. objs = form[1]
  410. print 'Form ', f.Name, ', size: ', f.Width, f.Height, ' Nobj ', f.Numberofobjects
  411. for i in objs:
  412. print ' Obj ', i.Name, ' type ', i.Class, i.Type
  413. print ' Box ', i.Box, ' btype ', i.Boxtype
  414. print ' Label ', i.Label, ' size/style/col/align ', i.Size,i.Style, i.Lcol, i.Alignment
  415. print ' cols ', i.Colors
  416. print ' cback ', i.Callback, i.Argument