@@ -7,9 +7,9 @@ a file, translate it, and write it out.
77
88"""
99import sys
10+ from argparse import ArgumentParser , ArgumentTypeError
1011from collections import defaultdict
1112from logging import _levelNames as logLevels , exception , warning , info , basicConfig
12- from optparse import Option , OptionParser , OptionValueError
1313from os import path
1414from time import time
1515
@@ -21,51 +21,34 @@ from java2python.lib import escapes
2121version = '0.5'
2222
2323
24- def isWindows ():
25- """ True if running on Windows. """
26- return sys .platform .startswith ('win' )
27-
28-
29- def badLogLevel (name , value ):
30- """ Raise an error indicating a bad log level. """
31- msg = 'option %s: invalid loglevel: %r'
32- raise OptionValueError (msg % (name , value ))
33-
34-
35- def checkLogLevel (option , opt , value ):
36- """ Option type checker (see LocalOption class) to verify a log level. """
24+ def logLevel (value ):
25+ """ Returns a valid logging level or raises and exception. """
26+ msg = 'invalid loglevel: %r'
3727 try :
3828 lvl = int (value )
3929 except (ValueError , ):
4030 name = value .upper ()
4131 if name not in logLevels :
42- badLogLevel ( opt , value )
32+ raise ArgumentTypeError ( msg % value )
4333 lvl = logLevels [name ]
4434 else :
4535 if lvl not in logLevels :
46- badLogLevel ( opt , value )
36+ raise ArgumentTypeError ( msg % value )
4737 return lvl
4838
4939
50- class LocalOption (Option ):
51- """ Supplements the Option class with our log level checker. """
52- TYPES = Option .TYPES + ('loglevel' , )
53- TYPE_CHECKER = Option .TYPE_CHECKER .copy ()
54- TYPE_CHECKER ['loglevel' ] = checkLogLevel
55-
56-
5740def profileMain (options ):
5841 """ Runs our main function with profiling if indicated by options. """
5942 if options .profile :
60- import cProfile , pstats
61- prof = cProfile .Profile ()
62- prof .runcall (main , options )
63- stats = pstats .Stats (prof , stream = sys .stderr )
64- stats .strip_dirs ().sort_stats ('cumulative' )
65- stats .print_stats ().print_callers ()
66- return 0
43+ import cProfile , pstats
44+ prof = cProfile .Profile ()
45+ prof .runcall (main , options )
46+ stats = pstats .Stats (prof , stream = sys .stderr )
47+ stats .strip_dirs ().sort_stats ('cumulative' )
48+ stats .print_stats ().print_callers ()
49+ return 0
6750 else :
68- return main (options )
51+ return main (options )
6952
7053
7154def configFromDir (inname , dirname ):
@@ -81,33 +64,33 @@ def main(options):
8164
8265 filein = fileout = filedefault = '-'
8366 if options .inputfile and not isinstance (options .inputfile , file ):
84- filein = options .inputfile
67+ filein = options .inputfile
8568 if options .outputfile and not isinstance (options .outputfile , file ):
86- fileout = path .basename (options .outputfile )
69+ fileout = path .basename (options .outputfile )
8770 elif fileout != filedefault :
88- fileout = '%s.py' % (path .splitext (filein )[0 ])
71+ fileout = '%s.py' % (path .splitext (filein )[0 ])
8972
9073 configs = options .configs
9174 if options .configdir and not isinstance (filein , file ):
92- dirconfigname = configFromDir (filein , options .configdir )
93- if path .exists (dirconfigname ):
94- configs .insert (0 , dirconfigname )
75+ dirconfigname = configFromDir (filein , options .configdir )
76+ if path .exists (dirconfigname ):
77+ configs .insert (0 , dirconfigname )
9578 if options .includedefaults :
9679 configs .insert (0 , 'java2python.config.default' )
9780
9881 try :
99- if filein != '-' :
100- source = open (filein ).read ()
101- else :
102- source = sys .stdin .read ()
82+ if filein != '-' :
83+ source = open (filein ).read ()
84+ else :
85+ source = sys .stdin .read ()
10386 except (IOError , ), exc :
10487 code , msg = exc .args [0 :2 ]
10588 print 'IOError: %s.' % (msg , )
10689 return code
10790
10891 timed ['comp' ]
10992 try :
110- tree = buildAST (source )
93+ tree = buildAST (source )
11194 except (Exception , ), exc :
11295 exception ('exception while parsing' )
11396 return 1
@@ -133,23 +116,23 @@ def main(options):
133116 if options .lexertokens :
134117 for idx , tok in enumerate (tree .parser .input .tokens ):
135118 print >> sys .stderr , '{0} {1}' .format (idx , tok )
136- print >> sys .stderr
119+ print >> sys .stderr
137120
138121 if options .javaast :
139- tree .dump (sys .stderr )
140- print >> sys .stderr
122+ tree .dump (sys .stderr )
123+ print >> sys .stderr
141124
142125 if options .pytree :
143- module .dumpRepr (sys .stderr )
144- print >> sys .stderr
126+ module .dumpRepr (sys .stderr )
127+ print >> sys .stderr
145128
146129 if not options .skipsource :
147- if fileout == filedefault :
148- output = sys .stdout
149- else :
150- output = open (fileout , 'w' )
151- module .name = path .splitext (filein )[0 ] if filein != '-' else '<stdin>'
152- print >> output , source
130+ if fileout == filedefault :
131+ output = sys .stdout
132+ else :
133+ output = open (fileout , 'w' )
134+ module .name = path .splitext (filein )[0 ] if filein != '-' else '<stdin>'
135+ print >> output , source
153136
154137 if not options .skipcompile :
155138 try :
@@ -167,69 +150,83 @@ def main(options):
167150 return 0
168151
169152
153+ def isWindows ():
154+ """ True if running on Windows. """
155+ return sys .platform .startswith ('win' )
156+
157+
158+ def configLogging (loglevel ):
159+ """ Configure the logging package. """
160+ fmt = '# %(levelname)s %(funcName)s: %(message)s'
161+ basicConfig (level = loglevel , format = fmt )
162+
163+
164+ def configColors (nocolor ):
165+ """ Configure the color escapes. """
166+ if isWindows () or nocolor :
167+ escapes .clear ()
168+
169+
170170def config (argv ):
171171 """ Return an options object from the given argument sequence. """
172- parser = OptionParser (option_class = LocalOption , version = '%prog ' + version )
173- addopt = parser .add_option
174- addopt ('-i' , '--input' , dest = 'inputfile' ,
175- help = 'Read from INPUTFILE. May use - for stdin.' ,
176- metavar = 'INPUTFILE' , default = None )
177- addopt ('-o' , '--output' , dest = 'outputfile' ,
178- help = 'Write to OUTPUTFILE. May use - for stdout.' ,
179- metavar = 'OUTPUTFILE' , default = None )
180- addopt ('-c' , '--config' , dest = 'configs' ,
181- help = 'Use CONFIG file or module. May be repeated.' ,
182- metavar = 'CONFIG' , default = [],
183- action = 'append' )
184- addopt ('-d' , '--configdir' , dest = 'configdir' ,
185- help = 'Use DIR to match input filename with config filename.' ,
186- metavar = 'DIR' , default = None )
187- addopt ('-f' , '--profile' , dest = 'profile' ,
188- help = 'Profile execution and print results to stderr.' ,
189- default = False , action = 'store_true' )
190- addopt ('-j' , '--java-ast' , dest = 'javaast' ,
191- help = 'Print java source AST tree to stderr.' ,
192- default = False , action = 'store_true' )
193- addopt ('-k' , '--skip-compile' , dest = 'skipcompile' ,
194- help = 'Skip compile check on translated source.' ,
195- default = False , action = 'store_true' )
196- addopt ('-l' , '--loglevel' , dest = 'loglevel' ,
197- help = 'Set log level by name or value.' ,
198- default = 'WARN' , type = 'loglevel' )
199- addopt ('-n' , '--nodefaults' , dest = 'includedefaults' ,
200- help = 'Ignore default configuration module.' ,
201- default = True , action = 'store_false' )
202- addopt ('-p' , '--python-tree' , dest = 'pytree' ,
203- help = 'Print python object tree to stderr.' ,
204- default = False , action = 'store_true' )
205- addopt ('-r' , '--nocolor' , dest = 'nocolor' ,
206- help = 'Disable color output.' + \
207- (' No effect on Win OS.' if isWindows () else '' ),
208- default = False , action = 'store_true' )
209- addopt ('-s' , '--skip-source' , dest = 'skipsource' ,
210- help = 'Skip writing translated source; useful when printing trees' ,
211- default = False , action = 'store_true' )
212- addopt ('-t' , '--lexer-tokens' , dest = 'lexertokens' ,
213- help = 'Print lexer tokens to stderr.' ,
214- default = False , action = 'store_true' )
215-
216- options , args = parser .parse_args (argv )
217- if len (args ) > 2 :
218- parser .error ('Only one input file supported.' )
219- elif len (args ) == 2 :
220- options .inputfile = args [1 ]
221- if options .inputfile == '-' :
222- options .inputfile = sys .stdin
223- if options .outputfile == '-' :
224- options .outputfile = sys .stdout
225- ## these next statements don't belong here, but this is as good a
226- ## place as any.
227- if isWindows () or options .nocolor :
228- escapes .clear ()
229- fmt = '# %(levelname)s %(funcName)s: %(message)s'
230- basicConfig (level = options .loglevel , format = fmt )
231- return options
172+ parser = ArgumentParser (
173+ description = 'Translate Java source code to Python.' ,
174+ epilog = 'Refer to https://github.com/natural/java2python for docs and support.'
175+ )
176+
177+ add = parser .add_argument
178+ add (dest = 'inputfile' , nargs = '?' ,
179+ help = 'Read from INPUTFILE. May use - for stdin (default).' ,
180+ metavar = 'INPUTFILE' , default = None )
181+ add (dest = 'outputfile' , nargs = '?' ,
182+ help = 'Write to OUTPUTFILE. May use - for stdout (default).' ,
183+ metavar = 'OUTPUTFILE' , default = None )
184+ add ('-c' , '--config' , dest = 'configs' ,
185+ help = 'Use CONFIG file or module. May be repeated.' ,
186+ metavar = 'CONFIG' , default = [],
187+ action = 'append' )
188+ add ('-d' , '--configdir' , dest = 'configdir' ,
189+ help = 'Use DIR to match input filename with config filename.' ,
190+ metavar = 'DIR' , default = None )
191+ add ('-f' , '--profile' , dest = 'profile' ,
192+ help = 'Profile execution and print results to stderr.' ,
193+ default = False , action = 'store_true' )
194+ add ('-j' , '--java-ast' , dest = 'javaast' ,
195+ help = 'Print java source AST tree to stderr.' ,
196+ default = False , action = 'store_true' )
197+ add ('-k' , '--skip-compile' , dest = 'skipcompile' ,
198+ help = 'Skip compile check on translated source.' ,
199+ default = False , action = 'store_true' )
200+ add ('-l' , '--loglevel' , dest = 'loglevel' ,
201+ help = 'Set log level by name or value.' ,
202+ default = 'WARN' , type = logLevel )
203+ add ('-n' , '--nodefaults' , dest = 'includedefaults' ,
204+ help = 'Ignore default configuration module.' ,
205+ default = True , action = 'store_false' )
206+ add ('-p' , '--python-tree' , dest = 'pytree' ,
207+ help = 'Print python object tree to stderr.' ,
208+ default = False , action = 'store_true' )
209+ add ('-r' , '--nocolor' , dest = 'nocolor' ,
210+ help = 'Disable color output.' + \
211+ (' No effect on Win OS.' if isWindows () else '' ),
212+ default = False , action = 'store_true' )
213+ add ('-s' , '--skip-source' , dest = 'skipsource' ,
214+ help = 'Skip writing translated source; useful when printing trees' ,
215+ default = False , action = 'store_true' )
216+ add ('-t' , '--lexer-tokens' , dest = 'lexertokens' ,
217+ help = 'Print lexer tokens to stderr.' ,
218+ default = False , action = 'store_true' )
219+ add ('-v' , '--version' , action = 'version' , version = '%(prog)s ' + version )
220+
221+ ns = parser .parse_args (argv )
222+ if ns .inputfile == '-' :
223+ ns .inputfile = sys .stdin
224+ if ns .outputfile == '-' :
225+ ns .outputfile = sys .stdout
226+ configColors (ns .nocolor )
227+ configLogging (ns .loglevel )
228+ return ns
232229
233230
234231if __name__ == '__main__' :
235- sys .exit (profileMain (config (sys .argv )))
232+ sys .exit (profileMain (config (sys .argv [ 1 :] )))
0 commit comments