2014-08-26 14:03:17 +02:00
package processing.app.helpers ;
import processing.app.BaseNoGui ;
import processing.app.I18n ;
import processing.app.PreferencesData ;
import processing.app.debug.TargetBoard ;
import processing.app.debug.TargetPackage ;
import processing.app.debug.TargetPlatform ;
import processing.app.legacy.PApplet ;
2015-04-08 13:59:29 +02:00
import java.io.File ;
2015-06-05 17:18:50 +02:00
import java.util.* ;
2015-04-08 13:59:29 +02:00
2015-08-05 09:04:53 +02:00
import static processing.app.I18n.tr ;
2015-04-08 13:59:29 +02:00
2014-08-26 14:03:17 +02:00
public class CommandlineParser {
2015-04-08 13:59:29 +02:00
private enum ACTION {
2015-04-09 13:03:41 +02:00
GUI , NOOP , VERIFY ( " --verify " ) , UPLOAD ( " --upload " ) , GET_PREF ( " --get-pref " ) , INSTALL_BOARD ( " --install-boards " ) , INSTALL_LIBRARY ( " --install-library " ) ;
2015-04-08 13:59:29 +02:00
2016-09-29 20:01:10 +02:00
final String value ;
2015-04-08 13:59:29 +02:00
ACTION ( ) {
this . value = null ;
}
ACTION ( String value ) {
this . value = value ;
}
}
2014-08-26 14:03:17 +02:00
2015-06-05 17:18:50 +02:00
private final String [ ] args ;
private final Map < String , ACTION > actions ;
2014-08-26 14:03:17 +02:00
private ACTION action = ACTION . GUI ;
private boolean doVerboseBuild = false ;
private boolean doVerboseUpload = false ;
2014-09-19 16:51:47 +02:00
private boolean doUseProgrammer = false ;
2015-04-15 11:00:01 +02:00
private boolean preserveTempFiles ;
2014-09-19 16:51:47 +02:00
private boolean noUploadPort = false ;
2014-08-26 14:03:17 +02:00
private boolean forceSavePrefs = false ;
2015-04-08 13:59:29 +02:00
private String getPref ;
private String boardToInstall ;
private String libraryToInstall ;
2015-06-25 10:40:26 +02:00
private final List < String > filenames = new LinkedList < > ( ) ;
2014-08-26 14:03:17 +02:00
2015-06-05 17:18:50 +02:00
public CommandlineParser ( String [ ] args ) {
this . args = args ;
2015-04-08 13:59:29 +02:00
2015-06-25 10:40:26 +02:00
actions = new HashMap < > ( ) ;
2014-08-26 14:03:17 +02:00
actions . put ( " --verify " , ACTION . VERIFY ) ;
actions . put ( " --upload " , ACTION . UPLOAD ) ;
actions . put ( " --get-pref " , ACTION . GET_PREF ) ;
2015-04-09 13:03:41 +02:00
actions . put ( " --install-boards " , ACTION . INSTALL_BOARD ) ;
2015-04-08 13:59:29 +02:00
actions . put ( " --install-library " , ACTION . INSTALL_LIBRARY ) ;
2015-06-05 17:18:50 +02:00
}
2014-08-26 14:03:17 +02:00
2015-06-05 17:18:50 +02:00
public void parseArgumentsPhase1 ( ) {
2014-08-26 14:03:17 +02:00
for ( int i = 0 ; i < args . length ; i + + ) {
ACTION a = actions . get ( args [ i ] ) ;
if ( a ! = null ) {
if ( action ! = ACTION . GUI & & action ! = ACTION . NOOP ) {
2015-06-05 17:18:50 +02:00
Set < String > strings = actions . keySet ( ) ;
String [ ] valid = strings . toArray ( new String [ strings . size ( ) ] ) ;
2015-08-05 09:04:53 +02:00
String mess = I18n . format ( tr ( " Can only pass one of: {0} " ) , PApplet . join ( valid , " , " ) ) ;
2014-08-26 14:03:17 +02:00
BaseNoGui . showError ( null , mess , 3 ) ;
}
if ( a = = ACTION . GET_PREF ) {
i + + ;
2015-05-29 15:15:08 +02:00
if ( i < args . length ) {
getPref = args [ i ] ;
2015-04-08 13:59:29 +02:00
}
2014-08-26 14:03:17 +02:00
}
2015-04-08 13:59:29 +02:00
if ( a = = ACTION . INSTALL_BOARD ) {
i + + ;
if ( i > = args . length ) {
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " Argument required for {0} " ) , a . value ) , 3 ) ;
2015-04-08 13:59:29 +02:00
}
boardToInstall = args [ i ] ;
}
if ( a = = ACTION . INSTALL_LIBRARY ) {
i + + ;
if ( i > = args . length ) {
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " Argument required for {0} " ) , a . value ) , 3 ) ;
2015-04-08 13:59:29 +02:00
}
libraryToInstall = args [ i ] ;
}
2014-08-26 14:03:17 +02:00
action = a ;
continue ;
}
2015-03-04 11:23:36 +01:00
if ( args [ i ] . startsWith ( " -psn " ) ) {
//discard
continue ;
}
2014-08-26 14:03:17 +02:00
if ( args [ i ] . equals ( " --verbose " ) | | args [ i ] . equals ( " -v " ) ) {
doVerboseBuild = true ;
doVerboseUpload = true ;
if ( action = = ACTION . GUI )
action = ACTION . NOOP ;
continue ;
}
2015-04-15 11:00:01 +02:00
if ( args [ i ] . equals ( " --preserve-temp-files " ) ) {
preserveTempFiles = true ;
if ( action = = ACTION . GUI )
action = ACTION . NOOP ;
continue ;
}
2014-08-26 14:03:17 +02:00
if ( args [ i ] . equals ( " --verbose-build " ) ) {
doVerboseBuild = true ;
if ( action = = ACTION . GUI )
action = ACTION . NOOP ;
continue ;
}
if ( args [ i ] . equals ( " --verbose-upload " ) ) {
doVerboseUpload = true ;
if ( action = = ACTION . GUI )
action = ACTION . NOOP ;
continue ;
}
2014-09-19 16:51:47 +02:00
if ( args [ i ] . equals ( " --useprogrammer " ) ) {
doUseProgrammer = true ;
if ( action = = ACTION . GUI )
action = ACTION . NOOP ;
continue ;
}
if ( args [ i ] . equals ( " --nouploadport " ) ) {
noUploadPort = true ;
if ( action = = ACTION . GUI )
action = ACTION . NOOP ;
continue ;
}
2014-08-26 14:03:17 +02:00
if ( args [ i ] . equals ( " --board " ) ) {
i + + ;
if ( i > = args . length )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , tr ( " Argument required for --board " ) , 3 ) ;
2014-08-26 14:03:17 +02:00
if ( action = = ACTION . GUI )
action = ACTION . NOOP ;
continue ;
}
if ( args [ i ] . equals ( " --port " ) ) {
i + + ;
if ( i > = args . length )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , tr ( " Argument required for --port " ) , 3 ) ;
2014-08-26 14:03:17 +02:00
BaseNoGui . selectSerialPort ( args [ i ] ) ;
if ( action = = ACTION . GUI )
action = ACTION . NOOP ;
continue ;
}
if ( args [ i ] . equals ( " --curdir " ) ) {
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , tr ( " --curdir no longer supported " ) , 3 ) ;
2015-06-29 09:33:34 +02:00
return ;
2014-08-26 14:03:17 +02:00
}
2014-09-19 16:51:47 +02:00
if ( args [ i ] . equals ( " --buildpath " ) ) {
i + + ;
if ( i > = args . length ) {
BaseNoGui . showError ( null , " Argument required for --buildpath " , 3 ) ;
}
File buildFolder = new File ( args [ i ] ) ;
if ( ! buildFolder . exists ( ) ) {
BaseNoGui . showError ( null , " The build path doesn't exist " , 3 ) ;
}
if ( ! buildFolder . isDirectory ( ) ) {
BaseNoGui . showError ( null , " The build path is not a folder " , 3 ) ;
}
2015-09-18 10:47:23 +02:00
PreferencesData . set ( " build.path " , buildFolder . getAbsolutePath ( ) ) ;
2014-09-19 16:51:47 +02:00
continue ;
}
2014-08-26 14:03:17 +02:00
if ( args [ i ] . equals ( " --pref " ) ) {
i + + ;
if ( i > = args . length )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , tr ( " Argument required for --pref " ) , 3 ) ;
2014-08-26 14:03:17 +02:00
processPrefArgument ( args [ i ] ) ;
if ( action = = ACTION . GUI )
action = ACTION . NOOP ;
continue ;
}
if ( args [ i ] . equals ( " --save-prefs " ) ) {
forceSavePrefs = true ;
continue ;
}
if ( args [ i ] . equals ( " --preferences-file " ) ) {
i + + ;
if ( i > = args . length )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , tr ( " Argument required for --preferences-file " ) , 3 ) ;
2014-08-26 14:03:17 +02:00
// Argument should be already processed by Base.main(...)
continue ;
}
if ( args [ i ] . startsWith ( " -- " ) )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " unknown option: {0} " ) , args [ i ] ) , 3 ) ;
2014-08-26 14:03:17 +02:00
filenames . add ( args [ i ] ) ;
}
2015-06-05 17:18:50 +02:00
checkAction ( ) ;
}
public void parseArgumentsPhase2 ( ) {
for ( int i = 0 ; i < args . length ; i + + ) {
if ( args [ i ] . equals ( " --board " ) ) {
i + + ;
if ( i > = args . length ) {
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , tr ( " Argument required for --board " ) , 3 ) ;
2015-06-05 17:18:50 +02:00
}
processBoardArgument ( args [ i ] ) ;
if ( action = = ACTION . GUI ) {
action = ACTION . NOOP ;
}
}
}
2014-08-26 14:03:17 +02:00
}
2015-04-08 13:59:29 +02:00
2014-08-26 14:03:17 +02:00
private void checkAction ( ) {
if ( ( action = = ACTION . UPLOAD | | action = = ACTION . VERIFY ) & & filenames . size ( ) ! = 1 )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , tr ( " Must specify exactly one sketch file " ) , 3 ) ;
2014-08-26 14:03:17 +02:00
if ( ( action = = ACTION . NOOP | | action = = ACTION . GET_PREF ) & & filenames . size ( ) ! = 0 )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , tr ( " Cannot specify any sketch files " ) , 3 ) ;
2014-08-26 14:03:17 +02:00
if ( ( action ! = ACTION . UPLOAD & & action ! = ACTION . VERIFY ) & & ( doVerboseBuild | | doVerboseUpload ) )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , tr ( " --verbose, --verbose-upload and --verbose-build can only be used together with --verify or --upload " ) , 3 ) ;
2014-08-26 14:03:17 +02:00
}
private void processBoardArgument ( String selectBoard ) {
// No board selected? Nothing to do
if ( selectBoard = = null )
2015-04-08 13:59:29 +02:00
return ;
2014-08-26 14:03:17 +02:00
String [ ] split = selectBoard . split ( " : " , 4 ) ;
if ( split . length < 3 ) {
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " {0}: Invalid board name, it should be of the form \" package:arch:board \" or \" package:arch:board:options \" " ) , selectBoard ) , 3 ) ;
2014-08-26 14:03:17 +02:00
}
TargetPackage targetPackage = BaseNoGui . getTargetPackage ( split [ 0 ] ) ;
if ( targetPackage = = null ) {
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " {0}: Unknown package " ) , split [ 0 ] ) , 3 ) ;
2015-06-25 10:40:26 +02:00
return ;
2014-08-26 14:03:17 +02:00
}
TargetPlatform targetPlatform = targetPackage . get ( split [ 1 ] ) ;
if ( targetPlatform = = null ) {
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " {0}: Unknown architecture " ) , split [ 1 ] ) , 3 ) ;
2015-06-25 10:40:26 +02:00
return ;
2014-08-26 14:03:17 +02:00
}
TargetBoard targetBoard = targetPlatform . getBoard ( split [ 2 ] ) ;
2015-06-25 10:35:06 +02:00
if ( targetBoard = = null | | ! targetBoard . getId ( ) . equals ( split [ 2 ] ) ) {
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " {0}: Unknown board " ) , split [ 2 ] ) , 3 ) ;
2015-06-25 10:40:26 +02:00
return ;
2014-08-26 14:03:17 +02:00
}
BaseNoGui . selectBoard ( targetBoard ) ;
2015-09-01 18:08:12 -04:00
BaseNoGui . onBoardOrPortChange ( ) ;
2014-08-26 14:03:17 +02:00
if ( split . length > 3 ) {
String [ ] options = split [ 3 ] . split ( " , " ) ;
for ( String option : options ) {
String [ ] keyValue = option . split ( " = " , 2 ) ;
if ( keyValue . length ! = 2 )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " {0}: Invalid option, should be of the form \" name=value \" " ) , option , targetBoard . getId ( ) ) , 3 ) ;
2014-08-26 14:03:17 +02:00
String key = keyValue [ 0 ] . trim ( ) ;
String value = keyValue [ 1 ] . trim ( ) ;
if ( ! targetBoard . hasMenu ( key ) )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " {0}: Invalid option for board \" {1} \" " ) , key , targetBoard . getId ( ) ) , 3 ) ;
2014-08-26 14:03:17 +02:00
if ( targetBoard . getMenuLabel ( key , value ) = = null )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " {0}: Invalid option for \" {1} \" option for board \" {2} \" " ) , value , key , targetBoard . getId ( ) ) , 3 ) ;
2014-08-26 14:03:17 +02:00
PreferencesData . set ( " custom_ " + key , targetBoard . getId ( ) + " _ " + value ) ;
}
}
}
private void processPrefArgument ( String arg ) {
String [ ] split = arg . split ( " = " , 2 ) ;
if ( split . length ! = 2 | | split [ 0 ] . isEmpty ( ) )
2015-08-05 09:04:53 +02:00
BaseNoGui . showError ( null , I18n . format ( tr ( " {0}: Invalid argument to --pref, should be of the form \" pref=value \" " ) , arg ) , 3 ) ;
2014-08-26 14:03:17 +02:00
PreferencesData . set ( split [ 0 ] , split [ 1 ] ) ;
2016-04-13 09:03:03 -04:00
PreferencesData . set ( " runtime.build_properties_custom. " + split [ 0 ] , split [ 1 ] ) ;
2014-08-26 14:03:17 +02:00
}
public boolean isDoVerboseBuild ( ) {
return doVerboseBuild ;
}
public boolean isDoVerboseUpload ( ) {
return doVerboseUpload ;
}
public boolean isForceSavePrefs ( ) {
return forceSavePrefs ;
}
public String getGetPref ( ) {
return getPref ;
}
public List < String > getFilenames ( ) {
return filenames ;
}
2015-04-08 13:59:29 +02:00
2014-08-26 14:03:17 +02:00
public boolean isGetPrefMode ( ) {
return action = = ACTION . GET_PREF ;
}
2015-04-08 13:59:29 +02:00
2014-08-26 14:03:17 +02:00
public boolean isGuiMode ( ) {
return action = = ACTION . GUI ;
}
2015-04-08 13:59:29 +02:00
2014-08-26 14:03:17 +02:00
public boolean isNoOpMode ( ) {
return action = = ACTION . NOOP ;
}
2015-04-08 13:59:29 +02:00
2014-08-26 14:03:17 +02:00
public boolean isUploadMode ( ) {
return action = = ACTION . UPLOAD ;
}
2015-04-08 13:59:29 +02:00
2015-06-25 10:40:26 +02:00
private boolean isVerifyMode ( ) {
2014-08-26 14:03:17 +02:00
return action = = ACTION . VERIFY ;
}
2015-04-08 13:59:29 +02:00
2014-08-26 14:03:17 +02:00
public boolean isVerifyOrUploadMode ( ) {
return isVerifyMode ( ) | | isUploadMode ( ) ;
}
2014-09-19 16:51:47 +02:00
public boolean isDoUseProgrammer ( ) {
return doUseProgrammer ;
}
public boolean isNoUploadPort ( ) {
return noUploadPort ;
}
2015-04-08 13:59:29 +02:00
public boolean isInstallBoard ( ) {
return action = = ACTION . INSTALL_BOARD ;
}
public boolean isInstallLibrary ( ) {
return action = = ACTION . INSTALL_LIBRARY ;
}
public String getBoardToInstall ( ) {
return this . boardToInstall ;
}
public String getLibraryToInstall ( ) {
return libraryToInstall ;
}
2015-04-15 11:00:01 +02:00
public boolean isPreserveTempFiles ( ) {
return preserveTempFiles ;
}
2014-08-26 14:03:17 +02:00
}