/buildtime/py/pde2py.py
Python | 126 lines | 105 code | 16 blank | 5 comment | 14 complexity | a04ff6894d9d66ebe58224c43269120c MD5 | raw file
Possible License(s): LGPL-3.0
1#!/usr/bin/python 2""" 3 Utility to do whatever mechanical work can be done in converting 4 PDE examples to Python ones. 5""" 6from __future__ import with_statement 7 8from optparse import OptionParser 9import os 10import re 11import shutil 12import sys 13 14 15def usage(): 16 print >> sys.stderr, 'Usage: pde2py [-f|--force] srcdir destdir' 17 sys.exit(1) 18 19parser = OptionParser() 20parser.add_option("-f", "--force", 21 action="store_true", dest="force", default=False, 22 help="overwrite existing files") 23 24(opts, args) = parser.parse_args() 25 26if len(args) < 2: 27 usage() 28 29src, dest = args 30if not (os.path.exists(src) and os.path.isdir(src)): 31 usage() 32if not os.path.exists(dest): 33 os.makedirs(dest) 34 35 36def copy_dir(s, d): 37 if not os.path.exists(d): 38 os.mkdir(d) 39 for f in os.listdir(s): 40 if f[0] == '.': 41 continue 42 copy(os.path.join(s, f), os.path.join(d, f)) 43 44 45def copy_file(s, d, xform=None): 46 with open(s, 'rb') as f: 47 text = f.read() 48 if xform: 49 (d, text) = xform(d, text) 50 if os.path.exists(d): 51 if opts.force: 52 print >> sys.stderr, 'Overwriting %s.' % d 53 else: 54 print >> sys.stderr, 'Not overwriting %s.' % d 55 return 56 else: 57 print >> sys.stderr, 'Writing %s.' % d 58 59 with open(d, 'wb') as f: 60 f.write(text) 61 62 63def to_python_case(name): 64 s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) 65 return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() 66 67 68def xform_py(d, text): 69 text = re.sub('(?<!:)//', '#', text) 70 text = text.replace(' ', ' ') 71 text = re.sub(r'for *\((?: *int *)?(\w+) *= *0 *; * \1 *< *([^;]+); *\1\+\+ *\)', r'for \1 in range(\2):', text) 72 text = re.sub(r'for *\((?: *int *)?(\w+) *= *(\d+) *; * \1 *< *([^;]+); *\1\+\+ *\)', r'for \1 in range(\2, \3):', text) 73 text = re.sub(r'for *\((?: *int *)?(\w+) *= *(\d+) *; * \1 *< *([^;]+); *\1 *\+= *([^\)]+)\)', r'for \1 in range(\2, \3, \4):', text) 74 text = re.sub(r'(?m)^(\s*)(?:public *)?(?:void|int|float|String)\s+([a-zA-Z0-9]+)\s*\(([^\)]*)\)', 75 r'\1def \2(\3):', 76 text) 77 text = re.sub(r'(?:int|float|String|double|Object)\s+([a-zA-Z0-9]+)\s*([,\)])', 78 r'\1\2', 79 text) 80 text = re.sub(r'(?:int|float|String|double|Object)\s+([a-zA-Z0-9]+)\s*=', 81 r'\1 =', 82 text) 83 text = re.sub( 84 r'(?:abstract +)?class +(\w+)', r'class \1(object):', text) 85 text = re.sub( 86 r'(?m)^\s*(?:abstract\s+)?class\s+(\S+)\s*extends\s*(\S+)\s*$', r'class \1(\2):', text) 87 text = re.sub(r'(?m)^(\s*)(?:void|int|float|String)\s+', r'\1', text) 88 text = re.sub(r'[{};] *', '', text) 89 text = re.sub(r'\n\n+', '\n', text) 90 text = re.sub(r'(?m)^(\s*)if\s*\((.+?)\)\s*$', r'\1if \2:', text) 91 text = re.sub(r'(?m)^(\s*)else\s+if\s*\((.+?)\)\s*$', r'\1elif \2:', text) 92 text = re.sub(r'(?m)^(\s*)else\s*$', r'\1else:', text) 93 text = re.sub(r'/\*+| *\*+/', '"""', text) 94 text = re.sub(r'(?m)^ *\* *', '', text) 95 text = text.replace('new ', '') 96 text = text.replace('true', 'True') 97 text = text.replace('false', 'False') 98 text = text.replace('this.', 'self.') 99 text = text.replace('||', 'or') 100 text = text.replace('&&', 'and') 101 text = re.sub(r'(\w+)\+\+', r'\1 += 1', text) 102 text = re.sub(r'(\w+)--', r'\1 -= 1', text) 103 text = re.sub(r'(\w+)\.length\b', r'len(\1)', text) 104 105 parent = os.path.dirname(d) 106 parent_name = os.path.basename(parent) 107 name, ext = os.path.splitext(os.path.basename(d)) 108 if name == parent_name: 109 newext = '.pyde' 110 else: 111 newext = '.py' 112 name = to_python_case(name) 113 114 d = parent + '/' + name + newext 115 return (d, text) 116 117 118def copy(s, d): 119 if os.path.isdir(s): 120 copy_dir(s, d) 121 elif s.endswith(".pde"): 122 copy_file(s, d, xform_py) 123 else: 124 copy_file(s, d) 125 126copy(src, dest)