001: // Copyright (c) Corporation for National Research Initiatives
002: package org.python.util;
003:
004: import org.python.core.*;
005: import java.util.zip.*;
006: import java.io.*;
007:
008: public class jython {
009: private static String usage = "usage: jython [options] [-jar jar | -c cmd | file | -] [args]\n"
010: + "Options and arguments:\n"
011: + "-i : inspect interactively after running script, and force\n"
012: + " prompts, even if stdin does not appear to be a "
013: + "terminal\n"
014: + "-S : don't imply `import site' on initialization\n"
015: + "-v : verbose (trace import statements)\n"
016: + "-Dprop=v : Set the property `prop' to value `v'\n"
017: + "-jar jar : program read from __run__.py in jar file\n"
018: + "-c cmd : program passed in as string (terminates option list)\n"
019: + "-W arg : warning control (arg is action:message:category:module:"
020: + "lineno)\n"
021: + "-E codec : Use a different codec the reading from the console.\n"
022: + "-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, "
023: + "-Qnew\n"
024: + "file : program read from script file\n"
025: + "- : program read from stdin (default; interactive mode if a "
026: + "tty)\n"
027: + "--help : print this usage message and exit\n"
028: + "--version: print Jython version number and exit\n"
029: + "args : arguments passed to program in sys.argv[1:]";
030:
031: public static void runJar(String filename) {
032: // TBD: this is kind of gross because a local called `zipfile' just
033: // magically shows up in the module's globals. Either `zipfile'
034: // should be called `__zipfile__' or (preferrably, IMO), __run__.py
035: // should be imported and a main() function extracted. This
036: // function should be called passing zipfile in as an argument.
037: //
038: // Probably have to keep this code around for backwards
039: // compatibility (?)
040: try {
041: ZipFile zip = new ZipFile(filename);
042:
043: ZipEntry runit = zip.getEntry("__run__.py");
044: if (runit == null)
045: throw Py.ValueError("jar file missing '__run__.py'");
046:
047: PyStringMap locals = new PyStringMap();
048:
049: // Stripping the stuff before the last File.separator fixes Bug
050: // #931129 by keeping illegal characters out of the generated
051: // proxy class name
052: int beginIndex;
053: if ((beginIndex = filename.lastIndexOf(File.separator)) != -1) {
054: filename = filename.substring(beginIndex + 1);
055: }
056:
057: locals.__setitem__("__name__", new PyString(filename));
058: locals.__setitem__("zipfile", Py.java2py(zip));
059:
060: InputStream file = zip.getInputStream(runit);
061: PyCode code;
062: try {
063: code = Py.compile(file, "__run__", "exec");
064: } finally {
065: file.close();
066: }
067: Py.runCode(code, locals, locals);
068: } catch (java.io.IOException e) {
069: throw Py.IOError(e);
070: }
071: }
072:
073: public static void main(String[] args) {
074: // Parse the command line options
075: CommandLineOptions opts = new CommandLineOptions();
076: if (!opts.parse(args)) {
077: if (opts.version) {
078: System.err.println(InteractiveConsole
079: .getDefaultBanner());
080: System.exit(0);
081: }
082: System.err.println(usage);
083: int exitcode = opts.help ? 0 : -1;
084: System.exit(exitcode);
085: }
086:
087: // Setup the basic python system state from these options
088: PySystemState.initialize(PySystemState.getBaseProperties(),
089: opts.properties, opts.argv);
090:
091: if (opts.notice) {
092: System.err.println(InteractiveConsole.getDefaultBanner());
093: }
094:
095: // Now create an interpreter
096: InteractiveConsole interp = null;
097: try {
098: String interpClass = PySystemState.registry.getProperty(
099: "python.console",
100: "org.python.util.InteractiveConsole");
101: interp = (InteractiveConsole) Class.forName(interpClass)
102: .newInstance();
103: } catch (Exception e) {
104: interp = new InteractiveConsole();
105: }
106:
107: //System.err.println("interp");
108: PyModule mod = imp.addModule("__main__");
109: interp.setLocals(mod.__dict__);
110: //System.err.println("imp");
111:
112: for (int i = 0; i < opts.warnoptions.size(); i++) {
113: String wopt = (String) opts.warnoptions.elementAt(i);
114: PySystemState.warnoptions.append(new PyString(wopt));
115: }
116:
117: String msg = "";
118: if (Options.importSite) {
119: try {
120: imp.load("site");
121:
122: if (opts.notice) {
123: PyObject builtins = Py.getSystemState().builtins;
124: boolean copyright = builtins
125: .__finditem__("copyright") != null;
126: boolean credits = builtins.__finditem__("credits") != null;
127: boolean license = builtins.__finditem__("license") != null;
128: if (copyright) {
129: msg += "\"copyright\"";
130: if (credits && license)
131: msg += ", ";
132: else if (credits || license)
133: msg += " or ";
134: }
135: if (credits) {
136: msg += "\"credits\"";
137: if (license)
138: msg += " or ";
139: }
140: if (license)
141: msg += "\"license\"";
142: if (msg.length() > 0)
143: System.err.println("Type " + msg
144: + " for more information.");
145: }
146: } catch (PyException pye) {
147: if (!Py.matchException(pye, Py.ImportError)) {
148: System.err.println("error importing site");
149: Py.printException(pye);
150: System.exit(-1);
151: }
152: }
153: }
154:
155: if (opts.division != null) {
156: if ("old".equals(opts.division))
157: Options.divisionWarning = 0;
158: else if ("warn".equals(opts.division))
159: Options.divisionWarning = 1;
160: else if ("warnall".equals(opts.division))
161: Options.divisionWarning = 2;
162: else if ("new".equals(opts.division)) {
163: Options.Qnew = true;
164: interp.cflags.division = true;
165: }
166: }
167:
168: // was there a filename on the command line?
169: if (opts.filename != null) {
170: String path = new java.io.File(opts.filename).getParent();
171: if (path == null)
172: path = "";
173: Py.getSystemState().path.insert(0, new PyString(path));
174: if (opts.jar) {
175: runJar(opts.filename);
176: } else if (opts.filename.equals("-")) {
177: try {
178: interp.locals.__setitem__(new PyString("__file__"),
179: new PyString("<stdin>"));
180: interp.execfile(System.in, "<stdin>");
181: } catch (Throwable t) {
182: Py.printException(t);
183: }
184: } else {
185: try {
186: interp.locals.__setitem__(new PyString("__file__"),
187: new PyString(opts.filename));
188: interp.execfile(opts.filename);
189: } catch (Throwable t) {
190: Py.printException(t);
191: if (!opts.interactive) {
192: interp.cleanup();
193: System.exit(-1);
194: }
195: }
196: }
197: } else {
198: // if there was no file name on the command line, then "" is
199: // the first element on sys.path. This is here because if
200: // there /was/ a filename on the c.l., and say the -i option
201: // was given, sys.path[0] will have gotten filled in with the
202: // dir of the argument filename.
203: Py.getSystemState().path.insert(0, new PyString(""));
204:
205: if (opts.command != null) {
206: try {
207: interp.exec(opts.command);
208: } catch (Throwable t) {
209: Py.printException(t);
210: }
211: }
212: }
213:
214: if (opts.interactive) {
215: if (opts.encoding == null) {
216: opts.encoding = PySystemState.registry.getProperty(
217: "python.console.encoding", null);
218: }
219: if (opts.encoding != null) {
220: interp.cflags.encoding = opts.encoding;
221: }
222: try {
223: interp.interact(null);
224: } catch (Throwable t) {
225: Py.printException(t);
226: }
227: }
228: interp.cleanup();
229: if (opts.interactive) {
230: System.exit(0);
231: }
232: }
233: }
234:
235: class CommandLineOptions {
236: public String filename;
237: public boolean jar, interactive, notice;
238: private boolean fixInteractive;
239: public boolean help, version;
240: public String[] argv;
241: public java.util.Properties properties;
242: public String command;
243: public java.util.Vector warnoptions = new java.util.Vector();
244: public String encoding;
245: public String division;
246:
247: public CommandLineOptions() {
248: filename = null;
249: jar = fixInteractive = false;
250: interactive = notice = true;
251: properties = new java.util.Properties();
252: help = version = false;
253: }
254:
255: public void setProperty(String key, String value) {
256: properties.put(key, value);
257: try {
258: System.setProperty(key, value);
259: } catch (SecurityException e) {
260: }
261: }
262:
263: public boolean parse(String[] args) {
264: int index = 0;
265: while (index < args.length && args[index].startsWith("-")) {
266: String arg = args[index];
267: if (arg.equals("--help")) {
268: help = true;
269: return false;
270: } else if (arg.equals("--version")) {
271: version = true;
272: return false;
273: } else if (arg.equals("-")) {
274: if (!fixInteractive)
275: interactive = false;
276: filename = "-";
277: } else if (arg.equals("-i")) {
278: fixInteractive = true;
279: interactive = true;
280: } else if (arg.equals("-jar")) {
281: jar = true;
282: if (!fixInteractive)
283: interactive = false;
284: } else if (arg.equals("-v")) {
285: Options.verbose++;
286: } else if (arg.equals("-vv")) {
287: Options.verbose += 2;
288: } else if (arg.equals("-vvv")) {
289: Options.verbose += 3;
290: } else if (arg.equals("-S")) {
291: Options.importSite = false;
292: } else if (arg.equals("-c")) {
293: command = args[++index];
294: if (!fixInteractive)
295: interactive = false;
296: index++;
297: break;
298: } else if (arg.equals("-W")) {
299: warnoptions.addElement(args[++index]);
300: } else if (arg.equals("-E")) {
301: encoding = args[++index];
302: } else if (arg.startsWith("-D")) {
303: String key = null;
304: String value = null;
305: int equals = arg.indexOf("=");
306: if (equals == -1) {
307: String arg2 = args[++index];
308: key = arg.substring(2, arg.length());
309: value = arg2;
310: } else {
311: key = arg.substring(2, equals);
312: value = arg.substring(equals + 1, arg.length());
313: }
314: setProperty(key, value);
315: } else if (arg.startsWith("-Q")) {
316: if (arg.length() > 2)
317: division = arg.substring(2);
318: else
319: division = args[++index];
320: } else {
321: String opt = args[index];
322: if (opt.startsWith("--"))
323: opt = opt.substring(2);
324: else if (opt.startsWith("-"))
325: opt = opt.substring(1);
326: System.err.println("jython: illegal option -- " + opt);
327: return false;
328: }
329: index += 1;
330: }
331: notice = interactive;
332: if (filename == null && index < args.length && command == null) {
333: filename = args[index++];
334: if (!fixInteractive)
335: interactive = false;
336: notice = false;
337: }
338: if (command != null)
339: notice = false;
340:
341: int n = args.length - index + 1;
342: argv = new String[n];
343: //new String[args.length-index+1];
344: if (filename != null)
345: argv[0] = filename;
346: else if (command != null)
347: argv[0] = "-c";
348: else
349: argv[0] = "";
350:
351: for (int i = 1; i < n; i++, index++) {
352: argv[i] = args[index];
353: }
354:
355: return true;
356: }
357: }
|