PageRenderTime 50ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/src/templates/gexpose.py

http://github.com/nriley/jython
Python | 644 lines | 595 code | 36 blank | 13 comment | 32 complexity | d748c87dc965a480fa1150fa3926a249 MD5 | raw file
  1. # copyright 2004-2005 Samuele Pedroni
  2. import sys
  3. import os
  4. import re
  5. scriptdir = os.path.dirname(__file__)
  6. import directives
  7. import java_parser
  8. import java_templating
  9. from java_templating import JavaTemplate,jast_make,jast, make_id, make_literal
  10. # Some examples for modif_re
  11. # (one)two -> group 1 = "one"
  12. # group 2 = "two"
  13. # (one,two,three)four -> group 1 = "one,two,three"
  14. # group 2 = "four"
  15. # hello -> group 1 = None
  16. # group 2 = "hello"
  17. modif_re = re.compile(r"(?:\(([\w,]+)\))?(\w+)")
  18. # Explanation of named groups in regular expression ktg_re:
  19. # k = one character key ("o","i" and "s" in "ois")
  20. # opt = optional (the "?" in "o?")
  21. # dfl = default for optional (the "blah" in o?(blah) )
  22. # tg = descriptive argument name (the "I'm anything but a curly brace in o{I'm anything but a curly brace} )
  23. ktg_re = re.compile("(?P<k>\w)(?P<opt>\?(:?\((?P<dfl>[^)]*)\))?)?(?:\{(?P<tg>[^}]*)\})?")
  24. def make_name(n):
  25. return JavaTemplate(jast_make(jast.QualifiedIdentifier,[java_parser.make_id(n)]))
  26. class Gen:
  27. priority_order = ['require','define',
  28. 'type_as',
  29. 'type_name','type_class','type_base_class',
  30. 'incl',
  31. 'expose_getset',
  32. 'expose_unary','expose_binary',
  33. 'expose_vanilla_cmp','expose_vanilla_pow',
  34. 'expose_key_getitem',
  35. 'expose_index_getitem',
  36. 'expose_cmeth',
  37. 'expose_meth',
  38. 'expose_wide_meth',
  39. 'expose_new_mutable',
  40. 'expose_new_immutable',
  41. 'rest']
  42. def __init__(self,bindings=None,priority_order=None):
  43. if bindings is None:
  44. self.global_bindings = { 'csub': java_templating.csub,
  45. 'concat': java_templating.concat,
  46. 'strfy': java_templating.strfy }
  47. else:
  48. self.global_bindings = bindings
  49. if priority_order:
  50. self.priority_order = priority_order
  51. self.call_meths_cache = {}
  52. self.auxiliary = None
  53. self.no_setup = False
  54. self.statements = []
  55. def debug(self,bindings):
  56. for name,val in bindings.items():
  57. if isinstance(val,JavaTemplate):
  58. print "%s:" % name
  59. print val.texpand({})
  60. def invalid(self,dire,value):
  61. raise Exception,"invalid '%s': %s" % (dire,value)
  62. def get_aux(self,name):
  63. if self.auxiliary is None:
  64. aux_gen = Gen(priority_order=['require','define'])
  65. directives.execute(directives.load(os.path.join(scriptdir,'gexpose-defs')),aux_gen)
  66. self.auxiliary = aux_gen.global_bindings
  67. return self.auxiliary[name]
  68. def dire_require(self,name,parm,body):
  69. if body is not None:
  70. self.invalid('require','non-empty body')
  71. sub_gen = Gen(bindings=self.global_bindings, priority__order=['require','define'])
  72. directives.execute(directives.load(parm.strip()),sub_gen)
  73. def dire_define(self,name,parm,body):
  74. parms = parm.split()
  75. if not parms:
  76. self.invalid('define',parm)
  77. parsed_name = modif_re.match(parms[0])
  78. if not parsed_name:
  79. self.invalid('define',parm)
  80. templ_kind = parsed_name.group(1)
  81. templ_name = parsed_name.group(2)
  82. naked = False
  83. if templ_kind is None:
  84. templ_kind = 'Fragment'
  85. templ = JavaTemplate(body,
  86. parms=':'.join(parms[1:]),
  87. bindings = self.global_bindings,
  88. start = templ_kind)
  89. self.global_bindings[templ_name] = templ
  90. def dire_type_as(self,name,parm,body):
  91. if body is not None:
  92. self.invalid(name,'non-empty body')
  93. parms = parm.split()
  94. if len(parms) not in (1,2):
  95. self.invalid(name,parm)
  96. self.type_as = JavaTemplate(parms[0])
  97. if len(parms) == 2:
  98. if parms[1] == 'no-setup':
  99. self.no_setup = True
  100. else:
  101. self.invalid(name,parm)
  102. def dire_type_name(self,name,parm,body):
  103. if body is not None:
  104. self.invalid(name,'non-empty body')
  105. self.type_name_plain = parm.strip()
  106. self.type_name = make_name(self.type_name_plain)
  107. self.global_bindings['typname'] = self.type_name
  108. def dire_type_class(self,name,parm,body):
  109. if body is not None:
  110. self.invalid(name,'non-empty body')
  111. self.type_class = JavaTemplate(parm.strip())
  112. self.global_bindings['typ'] = self.type_class
  113. def dire_type_base_class(self,name,parm,body):
  114. if body is not None:
  115. self.invalid(name,'non-empty body')
  116. self.type_base_class = JavaTemplate(parm.strip())
  117. def dire_incl(self,name,parm,body):
  118. if body is not None:
  119. self.invalid(name,'non-empty body')
  120. directives.execute(directives.load(parm.strip()+'.expose'),self)
  121. def dire_expose_getset(self,name,parm,body):
  122. if body is not None:
  123. self.invalid(name,'non-empty body')
  124. parms = parm.strip().split()
  125. if len(parms) not in (2,3,4):
  126. self.invalid(name, parm)
  127. name = parms[0]
  128. get = '"%s"' % parms[1]
  129. if len(parms) >= 3:
  130. set = '"%s"' % parms[2]
  131. else:
  132. set = "null"
  133. if len(parms) == 4:
  134. del_meth = '"%s"' % parms[3]
  135. else:
  136. del_meth = "null"
  137. getset_bindings = self.global_bindings.copy()
  138. getset_bindings['name'] = JavaTemplate(make_id(name))
  139. getset_bindings['get'] = JavaTemplate(make_literal(get))
  140. getset_bindings['set'] = JavaTemplate(make_literal(set))
  141. getset_bindings['del'] = JavaTemplate(make_literal(del_meth))
  142. getset = self.get_aux('getset')
  143. self.statements.append(getset.tbind(getset_bindings))
  144. NOARGS = JavaTemplate("void()")
  145. EMPTYALL = JavaTemplate(jast_make(jast.Expressions))
  146. def parse_sig(self,name,sig):
  147. argspecs = []
  148. some_opt = 0
  149. for m in ktg_re.finditer(sig):
  150. k = m.group('k')
  151. opt = m.group('opt') and 1 or 0
  152. if opt:
  153. some_opt = 1
  154. if opt != some_opt:
  155. self.invalid(name,"cannot interleave opt and non-opt arguments")
  156. dfl = m.group('dfl')
  157. if opt and dfl is None:
  158. dfl = ''
  159. tg = m.group('tg')
  160. argspecs.append((k,opt,dfl,tg))
  161. everything = [(k,tg) for k,opt,dfl,tg in argspecs]
  162. dfls = [ dfl for k,opt,dfl,tg in argspecs if opt]
  163. return everything,dfls
  164. def arg_i(self, argj, j, tg):
  165. if tg:
  166. err = "%s must be an integer" % tg
  167. else:
  168. err = "expected an integer"
  169. return JavaTemplate("%s.asInt(%s)" % (argj, j)), err # !!!
  170. def arg_l(self, argj, j, tg):
  171. if tg:
  172. err = "%s must be a long" % tg
  173. else:
  174. err = "expected a long"
  175. return JavaTemplate("%s.asLong(%s)" % (argj, j)), err # !!!
  176. def arg_b(self, argj, j, tg):
  177. return JavaTemplate("%s.__nonzero__()" % (argj)),None
  178. def arg_o(self,argj,j,tg):
  179. return JavaTemplate(argj),None
  180. def arg_S(self,argj,j,tg):
  181. if tg:
  182. err = "%s must be a string or None" % tg
  183. else:
  184. err = "expected a string or None"
  185. return JavaTemplate("%s.asStringOrNull(%s)" % (argj,j)),err # !!!
  186. def arg_s(self,argj,j,tg):
  187. if tg:
  188. err = "%s must be a string" % tg
  189. else:
  190. err = "expected a string"
  191. return JavaTemplate("%s.asString(%s)" % (argj,j)),err # !!!
  192. def arg_n(self,argj,j,tg):
  193. if tg:
  194. err = "%s must be a string" % tg
  195. else:
  196. err = "expected a string"
  197. return JavaTemplate("%s.asName(%s)" % (argj,j)),err # !!!
  198. def make_call_meths(self,n,bindings):
  199. try:
  200. return self.call_meths_cache[n].tbind(bindings)
  201. except KeyError:
  202. templ = "`call_meths`(`args%d,`body%d);"
  203. defs = []
  204. for i in range(n):
  205. defs.append(templ % (i,i))
  206. defs = '\n'.join(defs)
  207. jtempl = JavaTemplate(defs,start='ClassBodyDeclarations')
  208. self.call_meths_cache[n] = jtempl
  209. return jtempl.tbind(bindings)
  210. def handle_expose_meth_sig(self,sig,call_meths_bindings,body,body_bindings):
  211. proto_body_jt = JavaTemplate(body)
  212. everything,dfls = self.parse_sig('expose_meth',sig)
  213. dfls = map(JavaTemplate,dfls)
  214. tot = len(everything)
  215. rng = len(dfls)+1
  216. for dflc in range(rng):
  217. new_body_bindings = body_bindings.copy()
  218. args = self.NOARGS
  219. all = self.EMPTYALL
  220. j = 0
  221. conv_errors = {}
  222. for k,tg in everything[:tot-dflc]:
  223. argj = "arg%d" % j
  224. args += JavaTemplate("void(PyObject %s)" % argj)
  225. new_body_bindings[argj],err = getattr(self,'arg_%s' % k)(argj,j,tg)
  226. all += JavaTemplate(jast_make(jast.Expressions,[new_body_bindings[argj].fragment]))
  227. if err:
  228. conv_errors.setdefault(err,[]).append(j)
  229. j += 1
  230. new_body_bindings['all'] = all
  231. for dv in dfls[rng-1-dflc:]:
  232. new_body_bindings["arg%d" % j] = dv
  233. j += 1
  234. for deleg_templ_name in ('void','deleg','vdeleg','rdeleg','ideleg','ldeleg','bdeleg','sdeleg', 'udeleg'):
  235. deleg_templ = self.get_aux(deleg_templ_name)
  236. new_body_bindings[deleg_templ_name] = deleg_templ.tbind(new_body_bindings)
  237. body_jt = proto_body_jt.tbind(new_body_bindings)
  238. if conv_errors:
  239. cases = JavaTemplate(jast_make(jast.SwitchBlockStatementGroups))
  240. for err,indexes in conv_errors.items():
  241. suite = JavaTemplate('msg = "%s"; break; ' % err).fragment.BlockStatements
  242. cases += java_templating.switchgroup(indexes,suite)
  243. bindings = {'cases': cases, 'unsafe_body': body_jt }
  244. body_jt = self.get_aux('conv_error_handling').tbind(bindings)
  245. call_meths_bindings['body%d' % dflc] = body_jt
  246. call_meths_bindings['args%d' % dflc] = args
  247. inst_call_meths = self.make_call_meths(rng,call_meths_bindings)
  248. return inst_call_meths,tot-rng+1,tot
  249. def expose_meth_body(self, name, parm, body):
  250. parm = parm.strip()
  251. if parm.find('>') != -1:
  252. prefix, parm = parm.split('>', 1)
  253. parm = parm.strip()
  254. else:
  255. prefix = self.type_name_plain+'_'
  256. if body is not None:
  257. return parm, prefix, body
  258. if parm.startswith(':'):
  259. retk,rest = parm.split(None,1)
  260. body = {
  261. ":i" : "`ideleg;",
  262. ":l" : "`ldeleg;",
  263. ":b" : "`bdeleg;",
  264. ":s" : "`sdeleg;",
  265. ":u" : "`udeleg;",
  266. ":-" : "`vdeleg; `void; ",
  267. ":o" : "`rdeleg;"
  268. }.get(retk, None)
  269. if not body:
  270. self.invalid(name,retk)
  271. return rest, prefix, body
  272. else:
  273. return parm, prefix, "`rdeleg;"
  274. def dire_expose_meth(self,name,parm,body): # !!!
  275. parm, prefix, body = self.expose_meth_body(name, parm, body)
  276. expose = self.get_aux('expose_narrow_meth')
  277. type_class = getattr(self,'type_class',None)
  278. type_name = getattr(self,'type_name',None)
  279. if type_class is None or type_name is None:
  280. raise Exception,"type_class or type_name not defined"
  281. parms = parm.strip().split(None,1)
  282. if len(parms) not in (1,2):
  283. self.invalid(name,parm)
  284. if len(parms) == 1:
  285. parms.append('')
  286. expose_bindings = {}
  287. expose_bindings['typ'] = type_class
  288. expose_bindings['name'] = JavaTemplate(parms[0])
  289. expose_bindings['deleg_prefix'] = make_name(prefix)
  290. # !!!
  291. call_meths_bindings = expose_bindings.copy()
  292. body_bindings = self.global_bindings.copy()
  293. body_bindings.update(expose_bindings)
  294. call_meths_bindings['call_meths'] = self.get_aux('call_meths').tbind({'typ': type_class})
  295. inst_call_meths,minargs,maxargs = self.handle_expose_meth_sig(parms[1],call_meths_bindings,body,body_bindings)
  296. expose_bindings['call_meths'] = inst_call_meths
  297. expose_bindings['minargs'] = JavaTemplate(str(minargs))
  298. expose_bindings['maxargs'] = JavaTemplate(str(maxargs))
  299. self.statements.append(expose.tbind(expose_bindings))
  300. def dire_expose_cmeth(self,name,parm,body):
  301. if body is None:
  302. body = 'return `concat`(`deleg_prefix,`name)((PyType)getSelf(),`all);'
  303. parm, prefix, body = self.expose_meth_body(name, parm, body)
  304. expose = self.get_aux('expose_narrow_cmeth')
  305. type_class = getattr(self, 'type_class', None)
  306. parms = parm.strip().split(None,1)
  307. if len(parms) not in (1,2):
  308. self.invalid(name,parm)
  309. if len(parms) == 1:
  310. parms.append('')
  311. expose_bindings = {}
  312. expose_bindings['typ'] = type_class
  313. expose_bindings['name'] = JavaTemplate(parms[0])
  314. expose_bindings['deleg_prefix'] = make_name(prefix)
  315. # !!!
  316. call_meths_bindings = expose_bindings.copy()
  317. body_bindings = self.global_bindings.copy()
  318. body_bindings.update(expose_bindings)
  319. call_meths_bindings['call_meths'] = self.get_aux('call_cmeths').tbind({'typ': type_class})
  320. inst_call_meths,minargs,maxargs = self.handle_expose_meth_sig(parms[1],call_meths_bindings,body,body_bindings)
  321. expose_bindings['call_meths'] = inst_call_meths
  322. expose_bindings['minargs'] = JavaTemplate(str(minargs))
  323. expose_bindings['maxargs'] = JavaTemplate(str(maxargs))
  324. self.statements.append(expose.tbind(expose_bindings))
  325. def dire_expose_unary(self,name,parm,body):
  326. if body is not None:
  327. self.invalid(name,'non-empty body')
  328. meth_names = parm.split()
  329. if meth_names[0].endswith('>'):
  330. meth_names = ["%s %s" % (meth_names[0], n) for n in meth_names[1:]]
  331. unary_body = self.get_aux('unary').fragment
  332. for meth_name in meth_names:
  333. self.dire_expose_meth('expose_unary_1',meth_name,unary_body)
  334. def dire_expose_binary(self,name,parm,body):
  335. if body is not None:
  336. self.invalid(name,'non-empty body')
  337. meth_names = parm.split()
  338. if meth_names[0].endswith('>'):
  339. meth_names = ["%s %s" % (meth_names[0], n) for n in meth_names[1:]]
  340. binary_body = self.get_aux('binary').fragment
  341. for meth_name in meth_names:
  342. self.dire_expose_meth('expose_binary_1',"%s o" % meth_name,binary_body)
  343. def dire_expose_key_getitem(self,name,parm,body):
  344. if body is not None:
  345. self.invalid(name,'non-empty body')
  346. prefix = ""
  347. if parm.endswith('>'):
  348. prefix = parm
  349. key_getitem_body = self.get_aux('key_getitem').fragment
  350. self.dire_expose_meth('expose_key_getitem',"%s __getitem__ o" % prefix,key_getitem_body)
  351. def dire_expose_index_getitem(self,name,parm,body):
  352. if body is not None:
  353. self.invalid(name,'non-empty body')
  354. prefix = ""
  355. if parm.endswith('>'):
  356. prefix = parm
  357. index_getitem_body = self.get_aux('index_getitem').fragment
  358. self.dire_expose_meth('expose_index_getitem',"%s __getitem__ o" % prefix,index_getitem_body)
  359. def dire_expose_vanilla_cmp(self,name,parm,body):
  360. if body is not None:
  361. self.invalid(name,'non-empty body')
  362. prefix = ""
  363. if parm.endswith('>'):
  364. prefix = parm
  365. vanilla_cmp_body = self.get_aux('vanilla_cmp').fragment
  366. self.dire_expose_meth('expose_vanilla_cmp',"%s __cmp__ o" % prefix,vanilla_cmp_body)
  367. def dire_expose_vanilla_pow(self,name,parm,body):
  368. if body is not None:
  369. self.invalid(name,'non-empty body')
  370. prefix = ""
  371. if parm.endswith('>'):
  372. prefix = parm
  373. vanilla_pow_body = self.get_aux('vanilla_pow').fragment
  374. self.dire_expose_meth('expose_vanilla_pow',"%s __pow__ oo?(null)" % prefix,vanilla_pow_body)
  375. def dire_expose_wide_meth(self,name,parm,body): # !!!
  376. parm, prefix, body = self.expose_meth_body(name, parm, body)
  377. parms = parm.split()
  378. args = JavaTemplate("void(PyObject[] args,String[] keywords)")
  379. all = JavaTemplate("args, keywords",start='Expressions')
  380. bindings = self.global_bindings.copy()
  381. if len(parms) not in (1,3):
  382. self.invalid(name,parm)
  383. bindings['name'] = JavaTemplate(parms[0])
  384. bindings['deleg_prefix'] = make_name(prefix)
  385. bindings['all'] = all
  386. bindings['args'] = args
  387. for deleg_templ_name in ('void','deleg','vdeleg','rdeleg'):
  388. deleg_templ = self.get_aux(deleg_templ_name)
  389. bindings[deleg_templ_name] = deleg_templ.tbind(bindings)
  390. body = JavaTemplate(body).tbind(bindings)
  391. bindings['body'] = body
  392. call_meths = self.get_aux('call_meths').tbind(bindings)
  393. bindings['call_meths'] = call_meths
  394. parms = (parms+[-1,-1])[1:3]
  395. bindings['minargs'] = JavaTemplate(parms[0])
  396. bindings['maxargs'] = JavaTemplate(parms[1])
  397. expose = self.get_aux('expose_wide_meth').tbind(bindings)
  398. self.statements.append(expose)
  399. def dire_expose_new_mutable(self,name,parm,body):
  400. expose_new = self.get_aux('expose_new')
  401. parms = parm.split()
  402. body_bindings = self.global_bindings.copy()
  403. if body is None:
  404. body = self.get_aux('mutable_new_body')
  405. else:
  406. body = JavaTemplate(body)
  407. if not parms:
  408. parms = ['-1','-1']
  409. else:
  410. if len(parms) != 2:
  411. self.invalid(name,parm)
  412. body_bindings['minargs'] = JavaTemplate(parms[0])
  413. body_bindings['maxargs'] = JavaTemplate(parms[1])
  414. body = body.tbind(body_bindings)
  415. templ = expose_new.tbind(body_bindings)
  416. self.statements.append(templ.tbind({'body': body}))
  417. def dire_expose_new_immutable(self,name,parm,body):
  418. expose_new = self.get_aux('expose_new')
  419. parms = parm.split()
  420. body_bindings = self.global_bindings.copy()
  421. if body is not None:
  422. self.invalid(name,"non-empty body")
  423. body = self.get_aux('immutable_new_body')
  424. if not parms:
  425. parms = ['-1','-1']
  426. else:
  427. if len(parms) != 2:
  428. self.invalid(name,parm)
  429. body_bindings['minargs'] = JavaTemplate(parms[0])
  430. body_bindings['maxargs'] = JavaTemplate(parms[1])
  431. body = body.tbind(body_bindings)
  432. templ = expose_new.tbind(body_bindings)
  433. self.statements.append(templ.tbind({'body': body}))
  434. def dire_rest(self,name,parm,body):
  435. if parm:
  436. self.invalid(name,'non-empty parm')
  437. if body is None:
  438. return
  439. self.statements.append(JavaTemplate(body,start='BlockStatements'))
  440. def generate(self):
  441. typeinfo0 = self.get_aux('typeinfo0')
  442. basic = JavaTemplate("",start='ClassBodyDeclarations')
  443. bindings = self.global_bindings.copy()
  444. if hasattr(self,'type_as'):
  445. basic = (basic +
  446. JavaTemplate("public static final Class exposed_as = `as.class;",
  447. start = 'ClassBodyDeclarations'))
  448. bindings['as'] = self.type_as
  449. else:
  450. basic = (basic +
  451. JavaTemplate(
  452. "public static final String exposed_name = `strfy`(`name);",
  453. start='ClassBodyDeclarations'))
  454. bindings['name'] = self.type_name
  455. if hasattr(self,'type_base_class'):
  456. basic = (basic +
  457. JavaTemplate(
  458. "public static final Class exposed_base = `base.class;",
  459. start='ClassBodyDeclarations'))
  460. bindings['base'] = self.type_base_class
  461. typeinfo = typeinfo0
  462. setup = JavaTemplate("",start='BlockStatements')
  463. if not self.no_setup:
  464. typeinfo1 = self.get_aux('typeinfo1')
  465. pair = self.get_aux('pair')
  466. for statement in self.statements:
  467. setup = pair.tbind({'trailer': setup, 'last': statement})
  468. typeinfo = typeinfo.tfree() + typeinfo1.tfree()
  469. return typeinfo.tnaked().texpand({'basic': basic.tbind(bindings),
  470. 'setup': setup},nindent=1)
  471. def process(fn, mergefile=None, lazy=False):
  472. if lazy and mergefile and os.stat(fn).st_mtime < os.stat(mergefile).st_mtime:
  473. return
  474. print mergefile
  475. gen = Gen()
  476. directives.execute(directives.load(fn),gen)
  477. result = gen.generate()
  478. if mergefile is None:
  479. print result
  480. else:
  481. print 'Merging %s into %s' % (fn, mergefile)
  482. result = merge(mergefile, result)
  483. #gen.debug()
  484. def merge(filename, generated):
  485. in_generated = False
  486. start_found = False
  487. end_found = False
  488. start_pattern = ' //~ BEGIN GENERATED REGION -- DO NOT EDIT SEE gexpose.py'
  489. end_pattern = ' //~ END GENERATED REGION -- DO NOT EDIT SEE gexpose.py'
  490. output = []
  491. f = file(filename, 'r')
  492. for line in f:
  493. if line.startswith(start_pattern):
  494. in_generated = True
  495. start_found = True
  496. elif line.startswith(end_pattern):
  497. in_generated = False
  498. end_found = True
  499. output.append('%s\n%s\n%s\n' % (start_pattern, generated, end_pattern))
  500. elif in_generated:
  501. continue
  502. else:
  503. output.append(line)
  504. f.close()
  505. if not start_found:
  506. raise 'pattern [%s] not found in %s' % (start_pattern, filename)
  507. if not end_found:
  508. raise 'pattern [%s] not found in %s' % (end_pattern, filename)
  509. f = file(filename, 'w')
  510. f.write("".join(output))
  511. f.close()
  512. def load_mappings():
  513. scriptdir = os.path.dirname(os.path.abspath(__file__))
  514. srcdir = os.path.dirname(scriptdir)
  515. mappings = {}
  516. for line in open(os.path.join(scriptdir, 'mappings')):
  517. if line.strip() is '' or line.startswith('#'):
  518. continue
  519. tmpl, klass = line.strip().split(':')
  520. mappings[tmpl] = (os.path.join(scriptdir, tmpl),
  521. os.path.join(srcdir, *klass.split('.')) + '.java')
  522. return mappings
  523. def usage():
  524. print """Usage: python %s [--lazy|--help] <template> <outfile>
  525. If lazy is given, a template is only processed if its modtime is
  526. greater than outfile. If outfile isn't specified, the outfile from
  527. mappings for the given template is used. If template isn't given, all
  528. templates from mappings are processed.""" % sys.argv[0]
  529. if __name__ == '__main__':
  530. lazy = False
  531. if len(sys.argv) > 4:
  532. usage()
  533. sys.exit(1)
  534. if len(sys.argv) >= 2:
  535. if '--help' in sys.argv:
  536. usage()
  537. sys.exit(0)
  538. elif '--lazy' in sys.argv:
  539. lazy = True
  540. sys.argv.remove('--lazy')
  541. mappings = load_mappings()
  542. if len(sys.argv) == 1:
  543. for template, mapping in mappings.items():
  544. if template.endswith('expose'):
  545. process(mapping[0], mapping[1], lazy)
  546. elif len(sys.argv) == 2:
  547. mapping = mappings[sys.argv[1]]
  548. process(mapping[0], mapping[1], lazy)
  549. else:
  550. process(sys.argv[1], sys.argv[2], lazy)