public static int doMain( String[] args, String[] env, boolean initial, InputStream inStream, OutputStream outStream) { RCmdOptions options = RCmdOptions.parseArguments(RCmdOptions.Client.R, args, false); options.printHelpAndVersion(); PolyglotEngine vm = createPolyglotEngineFromCommandLine(options, false, initial, inStream, outStream, env); return readEvalPrint(vm); }
static PolyglotEngine createPolyglotEngineFromCommandLine( RCmdOptions options, boolean embedded, boolean initial, InputStream inStream, OutputStream outStream, String[] env) { RStartParams rsp = new RStartParams(options, embedded); String fileArg = options.getString(FILE); if (fileArg != null) { if (options.getStringList(EXPR) != null) { Utils.rSuicide("cannot use -e with -f or --file"); } if (!rsp.getSlave()) { rsp.setSaveAction(SA_TYPE.NOSAVE); } if (fileArg.equals("-")) { // means stdin, but still implies NO_SAVE fileArg = null; } else { fileArg = unescapeSpace(fileArg); } // cf GNU R rsp.setInteractive(false); } /* * Outputting the welcome message here has the virtue that the VM initialization delay * occurs later. However, it does not work in embedded mode as console redirects have not * been installed at this point. So we do it later in REmbedded. */ if (!rsp.getQuiet() && !embedded) { System.out.println(RRuntime.WELCOME_MESSAGE); } /* * Whether the input is from stdin, a file (-f), or an expression on the command line (-e) * it goes through the console. N.B. -f and -e can't be used together and this is already * checked. */ ConsoleHandler consoleHandler; if (fileArg != null) { List<String> lines; String filePath; try { /* * If initial==false, ~ expansion will not have been done and the open will fail. * It's harmless to always do it. */ File file = new File(Utils.tildeExpand(fileArg)); lines = Files.readAllLines(file.toPath()); filePath = file.getCanonicalPath(); } catch (IOException e) { if (initial) { throw Utils.rSuicide(String.format(RError.Message.NO_SUCH_FILE.message, fileArg)); } else { throw RError.error(RError.NO_CALLER, RError.Message.NO_SUCH_FILE, fileArg); } } consoleHandler = new StringConsoleHandler(lines, outStream, filePath); } else if (options.getStringList(EXPR) != null) { List<String> exprs = options.getStringList(EXPR); for (int i = 0; i < exprs.size(); i++) { exprs.set(i, unescapeSpace(exprs.get(i))); } if (!rsp.getSlave()) { rsp.setSaveAction(SA_TYPE.NOSAVE); } // cf GNU R rsp.setInteractive(false); consoleHandler = new StringConsoleHandler(exprs, outStream, RSource.Internal.EXPRESSION_INPUT.string); } else { /* * GnuR behavior differs from the manual entry for {@code interactive} in that {@code * --interactive} never applies to {@code -e/-f}, only to console input that has been * redirected from a pipe/file etc. * * If we are in embedded mode, the creation of ConsoleReader and the ConsoleHandler * should be lazy, as these may not be necessary and can cause hangs if stdin has been * redirected. */ Console sysConsole = System.console(); // TODO fix for context sessions boolean isInteractive = options.getBoolean(INTERACTIVE) || sysConsole != null; if (!isInteractive && rsp.getSaveAction() != SA_TYPE.SAVE && rsp.getSaveAction() != SA_TYPE.NOSAVE) { String msg = "you must specify '--save', '--no-save' or '--vanilla'"; if (initial) { throw Utils.rSuicide(msg); } else { throw RError.error(RError.NO_CALLER, RError.Message.GENERIC, msg); } } if (embedded) { consoleHandler = new EmbeddedConsoleHandler(rsp); } else { boolean useReadLine = !rsp.getNoReadline(); if (useReadLine) { consoleHandler = new JLineConsoleHandler(rsp, inStream, outStream); } else { consoleHandler = new DefaultConsoleHandler(inStream, outStream); } } } return ContextInfo.create( rsp, env, ContextKind.SHARE_NOTHING, initial ? null : RContext.getInstance(), consoleHandler) .createVM(); }