public boolean avrdude(Collection params) throws RunnerException {
    List commandDownloader = new ArrayList();
    commandDownloader.add("avrdude");

    // Point avrdude at its config file since it's in a non-standard location.
    if (Base.isMacOS()) {
      commandDownloader.add("-C" + "hardware/tools/avr/etc/avrdude.conf");
    } else if (Base.isWindows()) {
      String userdir = System.getProperty("user.dir") + File.separator;
      commandDownloader.add("-C" + userdir + "hardware/tools/avr/etc/avrdude.conf");
    } else {
      // ???: is it better to have Linux users install avrdude themselves, in
      // a way that it can find its own configuration file?
      commandDownloader.add("-C" + "hardware/tools/avrdude.conf");
    }

    if (Preferences.getBoolean("upload.verbose")) {
      commandDownloader.add("-v");
      commandDownloader.add("-v");
      commandDownloader.add("-v");
      commandDownloader.add("-v");
    } else {
      commandDownloader.add("-q");
      commandDownloader.add("-q");
    }
    // XXX: quick hack to chop the "atmega" off of "atmega8" and "atmega168",
    // then shove an "m" at the beginning.  won't work for attiny's, etc.
    commandDownloader.add(
        "-pm" + Preferences.get("boards." + Preferences.get("board") + ".build.mcu").substring(6));
    commandDownloader.addAll(params);

    return executeUploadCommand(commandDownloader);
  }
Esempio n. 2
0
  protected Connector findConnector(String connectorName) {
    //    List connectors =
    //      com.sun.jdi.Bootstrap.virtualMachineManager().allConnectors();
    List connectors = org.eclipse.jdi.Bootstrap.virtualMachineManager().allConnectors();

    //    // debug: code to list available connectors
    //    Iterator iter2 = connectors.iterator();
    //    while (iter2.hasNext()) {
    //      Connector connector = (Connector)iter2.next();
    //      System.out.println("connector name is " + connector.name());
    //    }

    for (Object c : connectors) {
      Connector connector = (Connector) c;
      //      System.out.println(connector.name());
      //    }
      //    Iterator iter = connectors.iterator();
      //    while (iter.hasNext()) {
      //      Connector connector = (Connector)iter.next();
      if (connector.name().equals(connectorName)) {
        return connector;
      }
    }
    Base.showError(
        "Compiler Error",
        "findConnector() failed to find " + connectorName + " inside Runner",
        null);
    return null; // Not reachable
  }
  /** Add import statements to the current tab for all of packages inside the specified jar file. */
  public void handleImportLibrary(String jarPath) {
    // make sure the user didn't hide the sketch folder
    sketch.ensureExistence();

    // import statements into the main sketch file (code[0])
    // if the current code is a .java file, insert into current
    // if (current.flavor == PDE) {
    if (mode.isDefaultExtension(sketch.getCurrentCode())) {
      sketch.setCurrentCode(0);
    }

    // could also scan the text in the file to see if each import
    // statement is already in there, but if the user has the import
    // commented out, then this will be a problem.
    String[] list = Base.packageListFromClassPath(jarPath);
    StringBuffer buffer = new StringBuffer();
    for (int i = 0; i < list.length; i++) {
      buffer.append("import ");
      buffer.append(list[i]);
      buffer.append(".*;\n");
    }
    buffer.append('\n');
    buffer.append(getText());
    setText(buffer.toString());
    setSelection(0, 0); // scroll to start
    sketch.setModified(true);
  }
Esempio n. 4
0
  public Runner(JavaBuild build, RunnerListener listener) throws SketchException {
    this.listener = listener;
    //    this.sketch = sketch;
    this.build = build;

    if (listener instanceof Editor) {
      this.editor = (Editor) listener;
      sketchErr = editor.getConsole().getErr();
      sketchOut = editor.getConsole().getOut();
    } else {
      sketchErr = System.err;
      sketchOut = System.out;
    }

    // Make sure all the imported libraries will actually run with this setup.
    int bits = Base.getNativeBits();
    for (Library library : build.getImportedLibraries()) {
      if (!library.supportsArch(PApplet.platform, bits)) {
        sketchErr.println(library.getName() + " does not run in " + bits + "-bit mode.");
        int opposite = (bits == 32) ? 64 : 32;
        if (Base.isMacOS()) {
          // if (library.supportsArch(PConstants.MACOSX, opposite)) {  // should always be true
          throw new SketchException(
              "To use "
                  + library.getName()
                  + ", "
                  + "switch to "
                  + opposite
                  + "-bit mode in Preferences.");
          // }
        } else {
          throw new SketchException(
              library.getName()
                  + " is only compatible "
                  + "with the  "
                  + opposite
                  + "-bit download of Processing.");
          // throw new SketchException(library.getName() + " does not run in " + bits + "-bit
          // mode.");
          // "To use this library, switch to 32-bit mode in Preferences." (OS X)
          //  "To use this library, you must use the 32-bit version of Processing."
        }
      }
    }
  }
Esempio n. 5
0
  public boolean copy_one_to_one(String[] arg) {
    File from = new File(arg[0]);
    File to = new File(arg[1]);
    if (to.exists() && to.isDirectory()) {
      to = new File(to, from.getName());
    }

    Base.copyFile(from, to);
    return true;
  }
  public void init(Editor _editor) {
    this.m_editor = _editor;

    File toolRoot = null;
    try {
      toolRoot =
          new File(
                  SequantoAutomationTool.class
                      .getProtectionDomain()
                      .getCodeSource()
                      .getLocation()
                      .toURI())
              .getParentFile()
              .getParentFile();
    } catch (java.net.URISyntaxException ex) {
      toolRoot =
          new File(
                  SequantoAutomationTool.class
                      .getProtectionDomain()
                      .getCodeSource()
                      .getLocation()
                      .getPath())
              .getParentFile()
              .getParentFile();
    }

    m_generatorPy =
        new File(new File(toolRoot, "generator"), "generate_automation_defines.py")
            .getAbsolutePath();
    m_isWindows = System.getProperty("os.name").toLowerCase().contains("win");
    if (m_isWindows) {
      for (File root : File.listRoots()) {
        File[] files =
            root.listFiles(
                new FileFilter() {
                  public boolean accept(File f) {
                    return f.getName().toLowerCase().startsWith("python");
                  }
                });
        if (files != null) {
          for (File directory : files) {
            m_pythonPath = new File(directory, "python.exe");
            break;
          }
        }
      }
      if (m_pythonPath == null) {
        Base.showMessage(
            "ERROR",
            String.format(
                "Could not python interpreter - Generate Automation tool will not work."));
      }
    }
  }
Esempio n. 7
0
  public long computeSize() throws RunnerException {
    String userdir = System.getProperty("user.dir") + File.separator;
    String avrBasePath;
    if (Base.isMacOS()) {
      avrBasePath = new String("tools/avr/bin/");
    } else if (Base.isLinux()) {
      avrBasePath = new String("");
    } else {
      avrBasePath = new String(userdir + "tools/avr/bin/");
    }
    String commandSize[] = new String[] {avrBasePath + "avr-size", " "};

    commandSize[1] = buildPath + File.separator + sketchName + ".hex";

    try {
      exception = null;
      size = -1;
      firstLine = null;
      Process process = Runtime.getRuntime().exec(commandSize);
      new MessageSiphon(process.getInputStream(), this);
      new MessageSiphon(process.getErrorStream(), this);
      boolean running = true;
      while (running) {
        try {
          process.waitFor();
          running = false;
        } catch (InterruptedException intExc) {
        }
      }
    } catch (Exception e) {
      exception = new RunnerException(e.toString());
    }

    if (exception != null) throw exception;

    if (size == -1) throw new RunnerException(firstLine);

    return size;
  }
  /** Handler for Sketch &rarr; Export Application */
  public void handleExportApplication() {
    toolbar.activate(JavaToolbar.EXPORT);

    if (handleExportCheckModified()) {
      statusNotice("Exporting application...");
      try {
        if (exportApplicationPrompt()) {
          Base.openFolder(sketch.getFolder());
          statusNotice("Done exporting.");
        } else {
          // error message will already be visible
          // or there was no error, in which case it was canceled.
        }
      } catch (Exception e) {
        statusNotice("Error during export.");
        e.printStackTrace();
      }
    }
    toolbar.deactivate(JavaToolbar.EXPORT);
  }
  private Collection getProgrammerCommands(String programmer) {
    List params = new ArrayList();
    params.add("-c" + Preferences.get("programmers." + programmer + ".protocol"));

    if ("usb".equals(Preferences.get("programmers." + programmer + ".communication"))) {
      params.add("-Pusb");
    } else if ("serial".equals(Preferences.get("programmers." + programmer + ".communication"))) {
      params.add("-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port"));
      // XXX: add support for specifying the baud rate for serial programmers.
    }
    // XXX: add support for specifying the port address for parallel
    // programmers, although avrdude has a default that works in most cases.

    if (Preferences.get("programmers." + programmer + ".force") != null
        && Preferences.getBoolean("programmers." + programmer + ".force")) params.add("-F");

    if (Preferences.get("programmers." + programmer + ".delay") != null)
      params.add("-i" + Preferences.get("programmers." + programmer + ".delay"));

    return params;
  }
  private boolean uploadViaBootloader(String buildPath, String className) throws RunnerException {
    List commandDownloader = new ArrayList();
    String protocol = Preferences.get("boards." + Preferences.get("board") + ".upload.protocol");

    // avrdude wants "stk500v1" to distinguish it from stk500v2
    if (protocol.equals("stk500")) protocol = "stk500v1";
    commandDownloader.add("-c" + protocol);
    commandDownloader.add(
        "-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port"));
    commandDownloader.add(
        "-b" + Preferences.getInteger("boards." + Preferences.get("board") + ".upload.speed"));
    commandDownloader.add("-D"); // don't erase
    commandDownloader.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");

    if (Preferences.get("boards." + Preferences.get("board") + ".upload.disable_flushing") == null
        || Preferences.getBoolean("boards." + Preferences.get("board") + ".upload.disable_flushing")
            == false) {
      flushSerialBuffer();
    }

    return avrdude(commandDownloader);
  }
Esempio n. 11
0
  /**
   * Provide more useful explanations of common error messages, perhaps with a short message in the
   * status area, and (if necessary) a longer message in the console.
   *
   * @param exceptionClass Class name causing the error (with full package name)
   * @param message The message from the exception
   * @param listener The Editor or command line interface that's listening for errors
   * @return true if the error was purtified, false otherwise
   */
  public static boolean handleCommonErrors(
      final String exceptionClass, final String message, final RunnerListener listener) {
    if (exceptionClass.equals("java.lang.OutOfMemoryError")) {
      if (message.contains("exceeds VM budget")) {
        // TODO this is a kludge for Android, since there's no memory preference
        listener.statusError(
            "OutOfMemoryError: This code attempts to use more memory than available.");
        System.err.println(
            "An OutOfMemoryError means that your code is either using up too much memory");
        System.err.println(
            "because of a bug (e.g. creating an array that's too large, or unintentionally");
        System.err.println(
            "loading thousands of images), or simply that it's trying to use more memory");
        System.err.println("than what is supported by the current device.");
      } else {
        listener.statusError(
            "OutOfMemoryError: You may need to increase the memory setting in Preferences.");
        System.err.println(
            "An OutOfMemoryError means that your code is either using up too much memory");
        System.err.println(
            "because of a bug (e.g. creating an array that's too large, or unintentionally");
        System.err.println(
            "loading thousands of images), or that your sketch may need more memory to run.");
        System.err.println(
            "If your sketch uses a lot of memory (for instance if it loads a lot of data files)");
        System.err.println(
            "you can increase the memory available to your sketch using the Preferences window.");
      }
    } else if (exceptionClass.equals("java.lang.UnsatisfiedLinkError")) {
      listener.statusError("A library used by this sketch is not installed properly.");
      System.err.println("A library relies on native code that's not available.");
      System.err.println(
          "Or only works properly when the sketch is run as a "
              + ((Base.getNativeBits() == 32) ? "64-bit " : "32-bit ")
              + " application.");

    } else if (exceptionClass.equals("java.lang.StackOverflowError")) {
      listener.statusError("StackOverflowError: This sketch is attempting too much recursion.");
      System.err.println(
          "A StackOverflowError means that you have a bug that's causing a function");
      System.err.println("to be called recursively (it's calling itself and going in circles),");
      System.err.println("or you're intentionally calling a recursive function too much,");
      System.err.println("and your code should be rewritten in a more efficient manner.");

    } else if (exceptionClass.equals("java.lang.UnsupportedClassVersionError")) {
      listener.statusError(
          "UnsupportedClassVersionError: A library is using code compiled with an unsupported version of Java.");
      System.err.println(
          "This version of Processing only supports libraries and JAR files compiled for Java 1.6 or earlier.");
      System.err.println("A library used by this sketch was compiled for Java 1.7 or later, ");
      System.err.println("and needs to be recompiled to be compatible with Java 1.6.");

    } else if (exceptionClass.equals("java.lang.NoSuchMethodError")
        || exceptionClass.equals("java.lang.NoSuchFieldError")) {
      listener.statusError(
          exceptionClass.substring(10)
              + ": "
              + "You may be using a library that's incompatible "
              + "with this version of Processing.");
    } else {
      return false;
    }
    return true;
  }
Esempio n. 12
0
  protected String[] getMachineParams() {
    ArrayList<String> params = new ArrayList<String>();

    // params.add("-Xint"); // interpreted mode
    // params.add("-Xprof");  // profiler
    // params.add("-Xaprof");  // allocation profiler
    // params.add("-Xrunhprof:cpu=samples");  // old-style profiler

    // TODO change this to use run.args = true, run.args.0, run.args.1, etc.
    // so that spaces can be included in the arg names
    String options = Preferences.get("run.options");
    if (options.length() > 0) {
      String pieces[] = PApplet.split(options, ' ');
      for (int i = 0; i < pieces.length; i++) {
        String p = pieces[i].trim();
        if (p.length() > 0) {
          params.add(p);
        }
      }
    }

    //    params.add("-Djava.ext.dirs=nuffing");

    if (Preferences.getBoolean("run.options.memory")) {
      params.add("-Xms" + Preferences.get("run.options.memory.initial") + "m");
      params.add("-Xmx" + Preferences.get("run.options.memory.maximum") + "m");
    }

    if (Base.isMacOS()) {
      params.add("-Xdock:name=" + build.getSketchClassName());
      //      params.add("-Dcom.apple.mrj.application.apple.menu.about.name=" +
      //                 sketch.getMainClassName());
    }
    // sketch.libraryPath might be ""
    // librariesClassPath will always have sep char prepended
    params.add(
        "-Djava.library.path="
            + build.getJavaLibraryPath()
            + File.pathSeparator
            + System.getProperty("java.library.path"));

    params.add("-cp");
    params.add(build.getClassPath());
    //    params.add(sketch.getClassPath() +
    //        File.pathSeparator +
    //        Base.librariesClassPath);

    // enable assertions
    // http://dev.processing.org/bugs/show_bug.cgi?id=1188
    params.add("-ea");
    // PApplet.println(PApplet.split(sketch.classPath, ':'));

    String outgoing[] = new String[params.size()];
    params.toArray(outgoing);

    //    PApplet.println(outgoing);
    //    PApplet.println(PApplet.split(outgoing[0], ":"));
    //    PApplet.println();
    //    PApplet.println("class path");
    //    PApplet.println(PApplet.split(outgoing[2], ":"));

    return outgoing;
    // return (String[]) params.toArray();

    //  System.out.println("sketch class path");
    //  PApplet.println(PApplet.split(sketch.classPath, ';'));
    //  System.out.println();
    //  System.out.println("libraries class path");
    //  PApplet.println(PApplet.split(Base.librariesClassPath, ';'));
    //  System.out.println();
  }
Esempio n. 13
0
  public boolean launchVirtualMachine(boolean presenting) {
    String[] vmParams = getMachineParams();
    String[] sketchParams = getSketchParams(presenting);
    int port = 8000 + (int) (Math.random() * 1000);
    String portStr = String.valueOf(port);

    // Older (Java 1.5 and earlier) version, go figure
    //    String jdwpArg = "-Xrunjdwp:transport=dt_socket,address=" + portStr +
    // ",server=y,suspend=y";
    //    String debugArg = "-Xdebug";
    // Newer (Java 1.5+) version that uses JVMTI
    String jdwpArg =
        "-agentlib:jdwp=transport=dt_socket,address=" + portStr + ",server=y,suspend=y";

    // Everyone works the same under Java 7 (also on OS X)
    String[] commandArgs = new String[] {Base.getJavaPath(), jdwpArg};

    /*
        String[] commandArgs = null;
        if (!Base.isMacOS()) {
          commandArgs = new String[] {
            Base.getJavaPath(),
            jdwpArg
          };
        } else {
          // Decided to just set this to 1.6 only, because otherwise it's gonna
          // be a shitshow if folks are getting Apple's 1.6 with 32-bit and
          // Oracle's 1.7 when run in 64-bit mode. ("Why does my sketch suck in
          // 64-bit? Why is retina broken?)
          // The --request flag will prompt to install Apple's 1.6 JVM if none is
          // available. We're specifying 1.6 so that we can get support for both
          // 32- and 64-bit, because Oracle won't be releasing Java 1.7 in 32-bit.
          // Helpfully, the --request flag is not present on Mac OS X 10.6
          // (luckily it is also not needed, because 1.6 is installed by default)
          // but it requires an additional workaround to not use that flag,
          // otherwise will see an error about an unsupported option. The flag is
          // available with 10.7 and 10.8, the only other supported versions of
          // OS X at this point, because we require 10.6.8 and higher. That also
          // means we don't need to check for any other OS versions, the user is
          // a douchebag and modifies Info.plist to get around the restriction.
          if (false) {
            if (System.getProperty("os.version").startsWith("10.6")) {
              commandArgs = new String[] {
                "/usr/libexec/java_home",
                "--version", "1.6",
                "--exec", "java",
                "-d" + Base.getNativeBits(),
                jdwpArg
              };
            } else {  // for 10.7, 10.8, etc
              commandArgs = new String[] {
                "/usr/libexec/java_home",
                "--request",  // install on-demand
                "--version", "1.6",
                "--exec", "java",
                "-d" + Base.getNativeBits(),
    //          debugArg,
                jdwpArg
              };
            }
          } else {
            // testing jdk-7u40
            commandArgs = new String[] {
              //"/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/bin/java",
              Base.getJavaPath(),
              jdwpArg
            };
          }
        }
        */

    commandArgs = PApplet.concat(commandArgs, vmParams);
    commandArgs = PApplet.concat(commandArgs, sketchParams);
    //  PApplet.println(commandArgs);
    //  commandArg.setValue(commandArgs);
    launchJava(commandArgs);

    AttachingConnector connector = (AttachingConnector) findConnector("com.sun.jdi.SocketAttach");
    // PApplet.println(connector);  // gets the defaults

    Map arguments = connector.defaultArguments();

    //  Connector.Argument addressArg =
    //    (Connector.Argument)arguments.get("address");
    //  addressArg.setValue(addr);
    Connector.Argument portArg = (Connector.Argument) arguments.get("port");
    portArg.setValue(portStr);

    //    Connector.Argument timeoutArg =
    //      (Connector.Argument)arguments.get("timeout");
    //    timeoutArg.setValue("10000");

    // PApplet.println(connector);  // prints the current
    // com.sun.tools.jdi.AbstractLauncher al;
    // com.sun.tools.jdi.RawCommandLineLauncher rcll;

    // System.out.println(PApplet.javaVersion);
    // http://java.sun.com/j2se/1.5.0/docs/guide/jpda/conninv.html#sunlaunch

    try {
      //      boolean available = false;
      //      while (!available) {
      while (true) {
        try {
          vm = connector.attach(arguments);
          //          vm = connector.attach(arguments);
          if (vm != null) {
            //            generateTrace();
            //            available = true;
            return true;
          }
        } catch (IOException e) {
          //          System.out.println("waiting");
          //          e.printStackTrace();
          try {
            Thread.sleep(100);
          } catch (InterruptedException e1) {
            e1.printStackTrace();
          }
        }
      }
      //    } catch (IOException exc) {
      //      throw new Error("Unable to launch target VM: " + exc);
    } catch (IllegalConnectorArgumentsException exc) {
      throw new Error("Internal error: " + exc);
    }
  }
  public JMenu buildHelpMenu() {
    // To deal with a Mac OS X 10.5 bug, add an extra space after the name
    // so that the OS doesn't try to insert its slow help menu.
    JMenu menu = new JMenu("Help ");
    JMenuItem item;

    // macosx already has its own about menu
    if (!Base.isMacOS()) {
      item = new JMenuItem("About Processing");
      item.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              new About(JavaEditor.this);
            }
          });
      menu.add(item);
    }

    item = new JMenuItem("Environment");
    item.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            showReference("environment" + File.separator + "index.html");
          }
        });
    menu.add(item);

    item = new JMenuItem("Reference");
    item.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            showReference("index.html");
          }
        });
    menu.add(item);

    item = Toolkit.newJMenuItemShift("Find in Reference", 'F');
    item.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            if (textarea.isSelectionActive()) {
              handleFindReference();
            }
          }
        });
    menu.add(item);

    menu.addSeparator();
    item = new JMenuItem("Online");
    item.setEnabled(false);
    menu.add(item);

    item = new JMenuItem("Getting Started");
    item.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            Base.openURL("http://processing.org/learning/gettingstarted/");
          }
        });
    menu.add(item);

    item = new JMenuItem("Troubleshooting");
    item.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            Base.openURL("http://wiki.processing.org/w/Troubleshooting");
          }
        });
    menu.add(item);

    item = new JMenuItem("Frequently Asked Questions");
    item.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            Base.openURL("http://wiki.processing.org/w/FAQ");
          }
        });
    menu.add(item);

    item = new JMenuItem("Visit Processing.org");
    item.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            Base.openURL("http://processing.org/");
          }
        });
    menu.add(item);

    return menu;
  }
Esempio n. 15
0
  public boolean launchVirtualMachine(boolean presenting) {
    String[] vmParams = getMachineParams();
    String[] sketchParams = getSketchParams(presenting);
    //    PApplet.printArray(sketchParams);
    int port = 8000 + (int) (Math.random() * 1000);
    String portStr = String.valueOf(port);

    // Older (Java 1.5 and earlier) version, go figure
    //    String jdwpArg = "-Xrunjdwp:transport=dt_socket,address=" + portStr +
    // ",server=y,suspend=y";
    //    String debugArg = "-Xdebug";
    // Newer (Java 1.5+) version that uses JVMTI
    String jdwpArg =
        "-agentlib:jdwp=transport=dt_socket,address=" + portStr + ",server=y,suspend=y";

    // Everyone works the same under Java 7 (also on OS X)
    String[] commandArgs = new String[] {Base.getJavaPath(), jdwpArg};

    commandArgs = PApplet.concat(commandArgs, vmParams);
    commandArgs = PApplet.concat(commandArgs, sketchParams);
    //  PApplet.println(commandArgs);
    //  commandArg.setValue(commandArgs);
    launchJava(commandArgs);

    AttachingConnector connector = (AttachingConnector) findConnector("com.sun.jdi.SocketAttach");
    // PApplet.println(connector);  // gets the defaults

    Map<String, Argument> arguments = connector.defaultArguments();

    //  Connector.Argument addressArg =
    //    (Connector.Argument)arguments.get("address");
    //  addressArg.setValue(addr);
    Connector.Argument portArg = arguments.get("port");
    portArg.setValue(portStr);

    //    Connector.Argument timeoutArg =
    //      (Connector.Argument)arguments.get("timeout");
    //    timeoutArg.setValue("10000");

    // PApplet.println(connector);  // prints the current
    // com.sun.tools.jdi.AbstractLauncher al;
    // com.sun.tools.jdi.RawCommandLineLauncher rcll;

    // System.out.println(PApplet.javaVersion);
    // http://java.sun.com/j2se/1.5.0/docs/guide/jpda/conninv.html#sunlaunch

    try {
      //      boolean available = false;
      //      while (!available) {
      while (true) {
        try {
          vm = connector.attach(arguments);
          //          vm = connector.attach(arguments);
          if (vm != null) {
            //            generateTrace();
            //            available = true;
            return true;
          }
        } catch (IOException e) {
          //          System.out.println("waiting");
          //          e.printStackTrace();
          try {
            Thread.sleep(100);
          } catch (InterruptedException e1) {
            e1.printStackTrace(sketchErr);
          }
        }
      }
      //    } catch (IOException exc) {
      //      throw new Error("Unable to launch target VM: " + exc);
    } catch (IllegalConnectorArgumentsException exc) {
      throw new Error("Internal error: " + exc);
    }
  }
  public void run() {
    if (!new File(m_generatorPy).exists()) {
      Base.showMessage(
          "ERROR", String.format("Could not find generator python script at %s", m_generatorPy));
    }
    Sketch sketch = m_editor.getSketch();
    if (sketch.isModified()) {
      try {
        sketch.save();
      } catch (java.io.IOException ex) {
        // Base.showMessage("ERROR", "Could not save sketch before trying to generate." );
      }
    }

    // String sketchName = sketch.getName();
    // SketchCode codeObject = sketch.getCurrentCode();
    // String code = codeObject.getProgram();
    try {
      String code = m_editor.getCurrentTab().getText();
      // String code = m_editor.getText();
      int start = code.indexOf("BEGIN AUTOMATION");
      if (start != -1) {
        int end = code.indexOf("END AUTOMATION", start);
        if (end != -1) {
          String automationCode = code.substring(start + "BEGIN AUTOMATION".length(), end);
          automationCode = automationCode.replaceAll("\\*\\s+", "");
          // SketchData sketchData = new MySketchData(sketch.getMainFilePath());
          // File buildFolder = BaseNoGui.getBuildFolder(sketchData);
          File buildFolder = getBuildFolder(sketch);
          // File codeFolder = sketchData.getCodeFolder();
          File codeFolder = new File(sketch.getFolder(), "code");
          Files.createDirectories(codeFolder.toPath());
          File automationFileName = new File(buildFolder, "automation.automation");
          FileWriter writer = new FileWriter(automationFileName);
          writer.write("name automation\n");
          writer.write("import " + sketch.getMainFilePath().toString() + "\n");
          writer.write(automationCode);
          writer.close();

          try {
            ProcessBuilder processBuilder = null;
            if (m_isWindows) {
              processBuilder =
                  new ProcessBuilder(
                      m_pythonPath.getAbsolutePath(),
                      m_generatorPy,
                      "-s",
                      "--arduino",
                      automationFileName.getAbsolutePath());
            } else {
              processBuilder =
                  new ProcessBuilder(
                      m_generatorPy, "-s", "--arduino", automationFileName.getAbsolutePath());
            }
            processBuilder.directory(codeFolder);
            processBuilder.redirectErrorStream(true);
            Process process = processBuilder.start();
            inheritIO(process.getInputStream(), System.out);
            int result = process.waitFor();

            String includeLibLine = "#include \"SequantoAutomation.h\"\n";
            if (!code.contains(includeLibLine)) {
              code = includeLibLine + code;
            }

            /*
              File generatedFileName = new File(codeFolder, "automation_automation.c" );
              String includeLine = String.format("#include \"%s\"\n", generatedFileName.getAbsolutePath());
              if ( !code.contains(includeLine) )
              {
              int i = code.indexOf(includeLibLine);
              code = code.substring(0, i + includeLibLine.length()) +
              includeLine +
              code.substring ( i + includeLibLine.length(), code.length() );
              }
            */

            String includeLine = String.format("#include \"code/automation_automation.h\"\n");
            if (!code.contains(includeLine)) {
              int i = code.indexOf(includeLibLine);
              code =
                  code.substring(0, i + includeLibLine.length())
                      + includeLine
                      + code.substring(i + includeLibLine.length(), code.length());
            }

            String includeCodeLine = String.format("\n#include \"code/automation_automation.c\"\n");
            if (!code.contains(includeCodeLine)) {
              code = code + includeCodeLine;
            }

            if (m_editor.getCurrentTab().getText() != code) {
              // System.out.println ( "Setting code to" );
              // System.out.println ( code );
              // System.out.println ( "Current text was" );
              // System.out.println ( m_editor.getText() );
              m_editor.getCurrentTab().setText(code);
            }

            if (result == 0) {
              System.out.println("Sequanto automation code generated successfully!");
            } else {
              System.out.println("ERROR!!!");
            }
          } catch (Exception ex) {
            Base.showMessage("ERROR", String.format("Could not start generator script: %s", ex));
          }
        } else {
          Base.showMessage("ERROR", "Can not find END AUTOMATION.");
        }
      } else {
        Base.showMessage("ERROR", "Can not find BEGIN AUTOMATION.");
      }
    } catch (java.io.IOException ex) {
      Base.showMessage("ERROR", String.format("IO Error: %s.", ex));
    }
  }