1 // Copyright ? Corporation for National Research Initiatives
2 package org.python.util;
3
4 import org.python.core;
5 import java.util.zip;
6 import java.io;
7
8 public class jpython
9 {
10 private static String usage =
11 "usage: jpython [options] [-jar jar | -c cmd | file | -] [args]\n"+
12 "Options and arguments:\n"+
13 "-i : inspect interactively after running script, and force\n"+
14 " prompts, even if stdin does not appear to be a terminal\n"+
15 "-S : don't imply `import site' on initialization\n"+
16 "-X : disable class based standard exceptions\n"+
17 "-Dprop=v : Set the property `prop' to value `v'\n"+
18 "-jar jar : program read from __run__.py in jar file\n"+
19 "-c cmd : program passed in as string (terminates option list)\n"+
20 "file : program read from script file\n"+
21 "- : program read from stdin (default; interactive mode if a "+
22 "tty)\n"+
23 "--help : print this usage message and exit\n"+
24 "--version: print JPython version number and exit\n"+
25 "args : arguments passed to program in sys.argv[1:]";
26
27 public static void runJar(String filename) {
28 // TBD: this is kind of gross because a local called `zipfile' just
29 // magically shows up in the module's globals. Either `zipfile'
30 // should be called `__zipfile__' or (preferrably, IMO), __run__.py
31 // should be imported and a main() function extracted. This
32 // function should be called passing zipfile in as an argument.
33 //
34 // Probably have to keep this code around for backwards
35 // compatibility (?)
36 try {
37 ZipFile zip = new ZipFile(filename);
38
39 ZipEntry runit = zip.getEntry("__run__.py");
40 if (runit == null)
41 throw Py.ValueError("jar file missing '__run__.py'");
42
43 PyStringMap locals = new PyStringMap();
44 locals.__setitem__("__name__", new PyString(filename));
45 locals.__setitem__("zipfile", Py.java2py(zip));
46
47 InputStream file = zip.getInputStream(runit);
48 PyCode code;
49 try {
50 code = Py.compile(file, "__run__", "exec");
51 } finally {
52 file.close();
53 }
54 Py.runCode(code, locals, locals);
55 } catch (java.io.IOException e) {
56 throw Py.IOError(e);
57 }
58 }
59
60 public static void main(String[] args) {
61 // Parse the command line options
62 CommandLineOptions opts = new CommandLineOptions();
63 if (!opts.parse(args)) {
64 if (opts.version) {
65 System.err.println(InteractiveConsole.getDefaultBanner());
66 System.exit(0);
67 }
68 System.err.println(usage);
69 int exitcode = opts.help ? 0 : -1;
70 System.exit(exitcode);
71 }
72
73 // Setup the basic python system state from these options
74 PySystemState.initialize(System.getProperties(),
75 opts.properties, opts.argv);
76
77 if (opts.notice) {
78 System.err.println(InteractiveConsole.getDefaultBanner());
79 }
80
81 // Now create an interpreter
82 InteractiveConsole interp = null;
83 try {
84 interp = (InteractiveConsole) Class.forName(
85 PySystemState.registry.getProperty("python.console",
86 "org.python.util.InteractiveConsole")).newInstance();
87 } catch (Exception e) {
88 interp = new InteractiveConsole();
89 }
90 //System.err.println("interp");
91 PyModule mod = imp.addModule("__main__");
92 interp.setLocals(mod.__dict__);
93 //System.err.println("imp");
94
95 if (Options.importSite) {
96 try {
97 imp.load("site");
98 } catch (PyException pye) {
99 if (!Py.matchException(pye, Py.ImportError)) {
100 System.err.println("error importing site");
101 Py.printException(pye);
102 System.exit(-1);
103 }
104 }
105 }
106
107 if (opts.command != null) {
108 try {
109 interp.exec(opts.command);
110 } catch (Throwable t) {
111 Py.printException(t);
112 }
113 }
114
115 // was there a filename on the command line?
116 if (opts.filename != null) {
117 String path = new java.io.File(opts.filename).getParent();
118 if (path == null)
119 path = "";
120 Py.getSystemState().path.insert(0, new PyString(path));
121 if (opts.jar) {
122 runJar(opts.filename);
123 } else if (opts.filename.equals("-")) {
124 try {
125 interp.execfile(System.in, "<stdin>");
126 } catch (Throwable t) {
127 Py.printException(t);
128 }
129 } else {
130 try {
131 interp.execfile(opts.filename);
132 } catch (Throwable t) {
133 Py.printException(t);
134 }
135 }
136 }
137 else {
138 // if there was no file name on the command line, then "" is
139 // the first element on sys.path. This is here because if
140 // there /was/ a filename on the c.l., and say the -i option
141 // was given, sys.path[0] will have gotten filled in with the
142 // dir of the argument filename.
143 Py.getSystemState().path.insert(0, new PyString(""));
144 }
145
146 if (opts.interactive) {
147 try {
148 interp.interact(null);
149 } catch (Throwable t) {
150 Py.printException(t);
151 }
152 }
153 }
154 }
155
156
157
158 class CommandLineOptions
159 {
160 public String filename;
161 public boolean jar, interactive, notice;
162 private boolean fixInteractive;
163 public boolean help, version;
164 public String[] argv;
165 public java.util.Properties properties;
166 public String command;
167
168 public CommandLineOptions() {
169 filename = null;
170 jar = fixInteractive = false;
171 interactive = notice = true;
172 properties = new java.util.Properties();
173 help = version = false;
174 }
175
176 public void setProperty(String key, String value) {
177 properties.put(key, value);
178 // This only works for Java 1.2. There appears to be no portable
179 // way to support this under Java 1.1
180 // try {
181 // System.setProperty(key, value);
182 // }
183 // catch (SecurityException e) {}
184 }
185
186 public boolean parse(String[] args) {
187 int index=0;
188 while (index < args.length && args[index].startsWith("-")) {
189 String arg = args[index];
190 if (arg.equals("--help")) {
191 help = true;
192 return false;
193 }
194 else if (arg.equals("--version")) {
195 version = true;
196 return false;
197 }
198 else if (arg.equals("-")) {
199 if (!fixInteractive)
200 interactive = false;
201 filename = "-";
202 }
203 else if (arg.equals("-i")) {
204 fixInteractive = true;
205 interactive = true;
206 }
207 else if (arg.equals("-jar")) {
208 jar = true;
209 if (!fixInteractive)
210 interactive = false;
211 }
212 else if (arg.equals("-X")) {
213 Options.classBasedExceptions = false;
214 }
215 else if (arg.equals("-S")) {
216 Options.importSite = false;
217 }
218 else if (arg.equals("-c")) {
219 command = args[++index];
220 if (!fixInteractive) interactive = false;
221 break;
222 }
223 else if (arg.startsWith("-D")) {
224 String key = null;
225 String value = null;
226 int equals = arg.indexOf("=");
227 if (equals == -1) {
228 String arg2 = args[++index];
229 key = arg.substring(2, arg.length());
230 value = arg2;
231 }
232 else {
233 key = arg.substring(2, equals);
234 value = arg.substring(equals+1, arg.length());
235 }
236 setProperty(key, value);
237 }
238 else {
239 String opt = args[index];
240 if (opt.startsWith("--"))
241 opt = opt.substring(2);
242 else if (opt.startsWith("-"))
243 opt = opt.substring(1);
244 System.err.println("jpython: illegal option -- " + opt);
245 return false;
246 }
247 index += 1;
248 }
249 notice = interactive;
250 if (filename == null && index < args.length && command == null) {
251 filename = args[index++];
252 if (!fixInteractive)
253 interactive = false;
254 notice = false;
255 }
256 if (command != null)
257 notice = false;
258
259 int n = args.length-index+1;
260 argv = new String[n];
261 //new String[args.length-index+1];
262 if (filename != null)
263 argv[0] = filename;
264 else argv[0] = "";
265
266 for(int i=1; i<n; i++, index++) {
267 argv[i] = args[index];
268 }
269
270 return true;
271 }
272 }