2525
2626import static processing .app .I18n ._ ;
2727
28- import java .io .BufferedReader ;
29- import java .io .File ;
30- import java .io .FileNotFoundException ;
31- import java .io .FileOutputStream ;
32- import java .io .FileReader ;
33- import java .io .IOException ;
34- import java .io .PrintWriter ;
28+ import java .io .*;
3529import java .util .ArrayList ;
3630import java .util .Arrays ;
3731import java .util .Collections ;
4539import cc .arduino .packages .Uploader ;
4640import cc .arduino .packages .UploaderFactory ;
4741
42+ import org .apache .commons .exec .CommandLine ;
43+ import org .apache .commons .exec .DefaultExecutor ;
44+ import org .apache .commons .exec .ExecuteStreamHandler ;
4845import processing .app .BaseNoGui ;
4946import processing .app .I18n ;
5047import processing .app .PreferencesData ;
@@ -696,38 +693,64 @@ private void execAsynchronously(String[] command) throws RunnerException {
696693 command = stringList .toArray (new String [stringList .size ()]);
697694 if (command .length == 0 )
698695 return ;
699- int result = 0 ;
700696
701697 if (verbose ) {
702698 for (String c : command )
703699 System .out .print (c + " " );
704700 System .out .println ();
705701 }
706702
707- Process process ;
703+ DefaultExecutor executor = new DefaultExecutor ();
704+ executor .setStreamHandler (new ExecuteStreamHandler () {
705+ @ Override
706+ public void setProcessInputStream (OutputStream os ) throws IOException {
707+
708+ }
709+
710+ @ Override
711+ public void setProcessErrorStream (InputStream is ) throws IOException {
712+ forwardToMessage (is );
713+ }
714+
715+ @ Override
716+ public void setProcessOutputStream (InputStream is ) throws IOException {
717+ forwardToMessage (is );
718+ }
719+
720+ private void forwardToMessage (InputStream is ) throws IOException {
721+ BufferedReader reader = new BufferedReader (new InputStreamReader (is ));
722+ String line ;
723+ while ((line = reader .readLine ()) != null ) {
724+ message (line + "\n " );
725+ }
726+ }
727+
728+ @ Override
729+ public void start () throws IOException {
730+
731+ }
732+
733+ @ Override
734+ public void stop () {
735+
736+ }
737+ });
738+
739+ CommandLine commandLine = new CommandLine (command [0 ]);
740+ for (int i = 1 ; i < command .length ; i ++) {
741+ commandLine .addArgument (command [i ]);
742+ }
743+
744+ int result ;
745+ executor .setExitValues (null );
708746 try {
709- process = ProcessUtils . exec ( command );
747+ result = executor . execute ( commandLine );
710748 } catch (IOException e ) {
711749 RunnerException re = new RunnerException (e .getMessage ());
712750 re .hideStackTrace ();
713751 throw re ;
714752 }
715-
716- MessageSiphon in = new MessageSiphon (process .getInputStream (), this );
717- MessageSiphon err = new MessageSiphon (process .getErrorStream (), this );
718-
719- // wait for the process to finish. if interrupted
720- // before waitFor returns, continue waiting
721- boolean compiling = true ;
722- while (compiling ) {
723- try {
724- in .join ();
725- err .join ();
726- result = process .waitFor ();
727- //System.out.println("result is " + result);
728- compiling = false ;
729- } catch (InterruptedException ignored ) { }
730- }
753+ executor .setExitValues (new int [0 ]);
731754
732755 // an error was queued up by message(), barf this back to compile(),
733756 // which will barf it back to Editor. if you're having trouble
@@ -769,10 +792,10 @@ public void message(String s) {
769792 s = s .substring (0 , i ) + s .substring (i + (buildPath + File .separator ).length ());
770793 }
771794 }
772-
795+
773796 // look for error line, which contains file name, line number,
774797 // and at least the first line of the error message
775- String errorFormat = "([ \\ w \\ d_]+ .\\ w+):(\\ d+):\\ s*error:\\ s*(.*)\\ s*" ;
798+ String errorFormat = "(.+ \\ .\\ w+):(\\ d+)(: \\ d+)* :\\ s*error:\\ s*(.*)\\ s*" ;
776799 String [] pieces = PApplet .match (s , errorFormat );
777800
778801// if (pieces != null && exception == null) {
@@ -781,56 +804,56 @@ public void message(String s) {
781804// }
782805
783806 if (pieces != null ) {
784- String error = pieces [3 ], msg = "" ;
807+ String error = pieces [pieces . length - 1 ], msg = "" ;
785808
786- if (pieces [ 3 ] .trim ().equals ("SPI.h: No such file or directory" )) {
809+ if (error .trim ().equals ("SPI.h: No such file or directory" )) {
787810 error = _ ("Please import the SPI library from the Sketch > Import Library menu." );
788811 msg = _ ("\n As of Arduino 0019, the Ethernet library depends on the SPI library." +
789812 "\n You appear to be using it or another library that depends on the SPI library.\n \n " );
790813 }
791814
792- if (pieces [ 3 ] .trim ().equals ("'BYTE' was not declared in this scope" )) {
815+ if (error .trim ().equals ("'BYTE' was not declared in this scope" )) {
793816 error = _ ("The 'BYTE' keyword is no longer supported." );
794817 msg = _ ("\n As of Arduino 1.0, the 'BYTE' keyword is no longer supported." +
795818 "\n Please use Serial.write() instead.\n \n " );
796819 }
797820
798- if (pieces [ 3 ] .trim ().equals ("no matching function for call to 'Server::Server(int)'" )) {
821+ if (error .trim ().equals ("no matching function for call to 'Server::Server(int)'" )) {
799822 error = _ ("The Server class has been renamed EthernetServer." );
800823 msg = _ ("\n As of Arduino 1.0, the Server class in the Ethernet library " +
801824 "has been renamed to EthernetServer.\n \n " );
802825 }
803826
804- if (pieces [ 3 ] .trim ().equals ("no matching function for call to 'Client::Client(byte [4], int)'" )) {
827+ if (error .trim ().equals ("no matching function for call to 'Client::Client(byte [4], int)'" )) {
805828 error = _ ("The Client class has been renamed EthernetClient." );
806829 msg = _ ("\n As of Arduino 1.0, the Client class in the Ethernet library " +
807830 "has been renamed to EthernetClient.\n \n " );
808831 }
809832
810- if (pieces [ 3 ] .trim ().equals ("'Udp' was not declared in this scope" )) {
833+ if (error .trim ().equals ("'Udp' was not declared in this scope" )) {
811834 error = _ ("The Udp class has been renamed EthernetUdp." );
812835 msg = _ ("\n As of Arduino 1.0, the Udp class in the Ethernet library " +
813836 "has been renamed to EthernetUdp.\n \n " );
814837 }
815838
816- if (pieces [ 3 ] .trim ().equals ("'class TwoWire' has no member named 'send'" )) {
839+ if (error .trim ().equals ("'class TwoWire' has no member named 'send'" )) {
817840 error = _ ("Wire.send() has been renamed Wire.write()." );
818841 msg = _ ("\n As of Arduino 1.0, the Wire.send() function was renamed " +
819842 "to Wire.write() for consistency with other libraries.\n \n " );
820843 }
821844
822- if (pieces [ 3 ] .trim ().equals ("'class TwoWire' has no member named 'receive'" )) {
845+ if (error .trim ().equals ("'class TwoWire' has no member named 'receive'" )) {
823846 error = _ ("Wire.receive() has been renamed Wire.read()." );
824847 msg = _ ("\n As of Arduino 1.0, the Wire.receive() function was renamed " +
825848 "to Wire.read() for consistency with other libraries.\n \n " );
826849 }
827850
828- if (pieces [ 3 ] .trim ().equals ("'Mouse' was not declared in this scope" )) {
851+ if (error .trim ().equals ("'Mouse' was not declared in this scope" )) {
829852 error = _ ("'Mouse' only supported on the Arduino Leonardo" );
830853 //msg = _("\nThe 'Mouse' class is only supported on the Arduino Leonardo.\n\n");
831854 }
832855
833- if (pieces [ 3 ] .trim ().equals ("'Keyboard' was not declared in this scope" )) {
856+ if (error .trim ().equals ("'Keyboard' was not declared in this scope" )) {
834857 error = _ ("'Keyboard' only supported on the Arduino Leonardo" );
835858 //msg = _("\nThe 'Keyboard' class is only supported on the Arduino Leonardo.\n\n");
836859 }
@@ -848,13 +871,15 @@ public void message(String s) {
848871 SketchCode code = sketch .getCode (e .getCodeIndex ());
849872 String fileName = (code .isExtension ("ino" ) || code .isExtension ("pde" )) ? code .getPrettyName () : code .getFileName ();
850873 int lineNum = e .getCodeLine () + 1 ;
851- s = fileName + ":" + lineNum + ": error: " + pieces [3 ] + msg ;
874+ s = fileName + ":" + lineNum + ": error: " + error + msg ;
875+ }
876+
877+ if (e != null ) {
878+ if (exception == null || exception .getMessage ().equals (e .getMessage ())) {
879+ exception = e ;
880+ exception .hideStackTrace ();
881+ }
852882 }
853-
854- if (exception == null && e != null ) {
855- exception = e ;
856- exception .hideStackTrace ();
857- }
858883 }
859884
860885 if (s .contains ("undefined reference to `SPIClass::begin()'" ) &&
0 commit comments