Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.executable/library/eclipse.c')
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipse.c890
1 files changed, 890 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipse.c b/bundles/org.eclipse.equinox.executable/library/eclipse.c
new file mode 100644
index 000000000..24ec891a3
--- /dev/null
+++ b/bundles/org.eclipse.equinox.executable/library/eclipse.c
@@ -0,0 +1,890 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Kevin Cornell (Rational Software Corporation)
+ *******************************************************************************/
+
+/* Eclipse Program Launcher
+ *
+ * This program performs the launching of the java VM used to
+ * start the Eclipse or RCP java application.
+ * As an implementation detail, this program serves two other
+ * purposes: display a splash window and write to a segment
+ * of shared memory.
+ *
+ * The java application receives the following arguments.
+ * -launcher <launcher absolute name. e.g. d:\eclipse\eclipse.exe>
+ * -name <application name. e.g. Eclipse>
+ * If the splash window is to be displayed, the java application
+ * will receive two extra arguments:
+ * -showsplash <splash time out in seconds e.g. 600>
+ *
+ * When the Java program starts, it should determine the location of
+ * the splash bitmap to be used. The Java program initiates the
+ * displaying of the splash window by executing the splash command
+ * as follows:
+ *
+ * Process splashProcess = Runtime.getRuntime().exec( array );
+ * Where array stores String arguments in the following order:
+ * 0. <launcher absolute name. e.g. d:\eclipse\eclipse.exe>
+ * 1. -name
+ * 2. <application name. e.g. Eclipse>
+ * 3. -showsplash
+ * 4. <splash time out in seconds e.g. 600>
+ * 5. <absolute path of the splash screen e.g. d:\eclipse\splash.bmp>
+ *
+ * When the Java program initialization is complete, the splash window
+ * is brought down by destroying the splash process as follows:
+ *
+ * splashProcess.destroy();
+ *
+ * Therefore, when the splash window is visible, there are actually three
+ * processes running:
+ * 1) the main launcher process
+ * 2) the Java VM process (Eclipse or RCP application)
+ * 3) the splash window process.
+ *
+ * The splash screen process can also show progress information. The
+ * communication between the Java VM process and the splash screen
+ * process is done through the standard input pipe. Messages sent to
+ * the splash screen process have this format:
+ *
+ * <key>=<value><LF>
+ *
+ * and the recognized messages are:
+ *
+ * value=50\n (changes the current progress value)
+ * maximum=100\n (changes the maximum progress value. Default is 100)
+ * message=starting...\n (changes the displayed message. Any char except LF is allowed)
+ * foreground=RRGGBB\n (changes the foreground color of the message, i.e. cyan=(0 << 16 | 255 << 8 | 255 << 0))
+ * messageRect=10,10,100,20\n (changes the rectangle(x,y,width,height) where the message is displayed)
+ * progressRect=10,30,100,15\n (changes the rectangle(x,y,width,height) where the progress is displayed)
+ *
+ * Similarly, the Java application will receive two other arguments:
+ * -exitdata <shared memory id>
+ *
+ * The exitdata command can be used by the Java application
+ * to provide specific exit data to the main launcher process. The
+ * following causes another instance of the launcher to write to the
+ * segment of shared memory previously created by the
+ * main launcher.
+ *
+ * Process exitDataProcess = Runtime.getRuntime().exec( array );
+ * exitDataProcess.waitFor();
+ * Where array stores String arguments in the following order:
+ * 0. <launcher absolute name. e.g. d:\eclipse\eclipse.exe>
+ * 1. -name
+ * 2. <application name. e.g. Eclipse>
+ * 3. -exitdata
+ * 4. <shared memory id e.g. c60_7b4>
+ * 5. <exit data that either contain a series of characters>
+ *
+ * The exit data size must not exceed MAX_SHARED_LENGTH which is
+ * 16Kb. The exit data process will exit with an exit code
+ * different than 0 if that happens. The interpretation of the
+ * exit data is dependent on the exit value of the java application.
+ *
+ * The main launcher recognizes the following exit codes from the
+ * Java application:
+ *
+ * 0
+ * - Exit normally.
+ * RESTART_LAST_EC = 23
+ * - restart the java VM again with the same arguments as the previous one.
+ * RESTART_NEW_EC = 24
+ * - restart the java VM again with the arguments taken from the exit data.
+ * The exit data format is a list of arguments separated by '\n'. The Java
+ * application should build this list using the arguments passed to it on
+ * startup. See below.
+ *
+ * Additionally, if the Java application exits with an exit code other than the
+ * ones above, the main launcher will display an error message with the contents
+ * of the exit data. If the exit data is empty, a generic error message is
+ * displayed. The generic error message shows the exit code and the arguments
+ * passed to the Java application.
+ *
+ * The options that can be specified by the user to the launcher are:
+ * -vm <javaVM> the Java VM to be used
+ * -os <opSys> the operating system being run on
+ * -arch <osArch> the hardware architecture of the OS: x86, sparc, hp9000
+ * -ws <gui> the window system to be used: win32, motif, gtk, ...
+ * -nosplash do not display the splash screen. The java application will
+ * not receive the -showsplash command.
+ * -name <name> application name displayed in error message dialogs and
+ * splash screen window. Default value is computed from the
+ * name of the executable - with the first letter capitalized
+ * if possible. e.g. eclipse.exe defaults to the name Eclipse.
+ * -startup the startup jar to execute. The argument is first assumed to be
+ * relative to the path of the launcher. If such a file does not
+ * exist, the argument is then treated as an absolute path.
+ * The default is to execute a jar called startup.jar in the folder
+ * where the launcher is located.
+ * The jar must be an executable jar.
+ * e.g. -startup myfolder/myJar.jar will cause the launcher to start
+ * the application: java -jar <launcher folder>/myfolder/myJar.jar
+ * <userArgs> arguments that are passed along to the Java application
+ * (i.e, -data <path>, -debug, -console, -consoleLog, etc)
+ * -vmargs <userVMargs> ... a list of arguments for the VM itself
+ *
+ * The -vmargs option and all user specified VM arguments must appear
+ * at the end of the command line, after all arguments that are
+ * being passed to Java application.
+ *
+ * The argument order for the new Java VM process is as follows:
+ *
+ * <javaVM> <all VM args>
+ * -os <user or default OS value>
+ * -ws <user or default WS value>
+ * -arch <user or default ARCH value>
+ * -launcher <absolute launcher name>
+ * -name <application name>
+ * [-showsplash <splash time out>]
+ * [-exitdata <shared memory id>]
+ * <userArgs>
+ * -vm <javaVM>
+ * -vmargs <all VM args>
+ *
+ * where:
+ * <all VM args> =
+ * [<defaultVMargs | <userVMargs>]
+ * -jar
+ * <startup jar full path>
+ *
+ * The startup jar must be an executable jar.
+ *
+ *
+ * See "Main.java" for a simple implementation of the Java
+ * application.
+ *
+ * Configuration file
+ * The launcher gets arguments from the command line and/or from a configuration file.
+ * The configuration file must have the same name and location as the launcher executable
+ * and the extension .ini. For example, the eclipse.ini configuration file must be
+ * in the same folder as the eclipse.exe or eclipse executable.
+ * The format of the ini file matches that of the command line arguments - one
+ * argument per line.
+ * In general, the settings of the config file are expected to be overriden by the
+ * command line.
+ * - launcher arguments (-os, -arch...) set in the config file are overriden by the command line
+ * - the -vmargs from the command line replaces in its entirety the -vmargs from the config file.
+ * - user arguments from the config file are prepended to the user arguments defined in the
+ * config file. This is consistent with the java behaviour in the following case:
+ * java -Dtest="one" -Dtest="two" ... : test is set to the value "two"
+ */
+
+#include "eclipseOS.h"
+#include "eclipseJNI.h"
+#include "eclipseConfig.h"
+#include "eclipseCommon.h"
+
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <strings.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <ctype.h>
+
+#define MAX_PATH_LENGTH 2000
+#define MAX_SHARED_LENGTH (16 * 1024)
+
+/* Global Data */
+static _TCHAR* program = NULL; /* full pathname of the program */
+static _TCHAR* programDir = NULL; /* directory where program resides */
+static _TCHAR* javaVM = NULL; /* full pathname of the Java VM to run */
+static _TCHAR* jarFile = NULL; /* full pathname of the startup jar file to run */
+
+_TCHAR* exitData = NULL; /* exit data set from Java */
+int initialArgc;
+_TCHAR** initialArgv;
+
+
+/* Define the special exit codes returned from Eclipse. */
+#define RESTART_LAST_EC 23
+#define RESTART_NEW_EC 24
+
+/* Define error messages. (non-NLS) */
+static _TCHAR* exitMsg = _T_ECLIPSE("JVM terminated. Exit code=%d\n%s");
+static _TCHAR* goVMMsg = _T_ECLIPSE("Start VM: %s\n");
+static _TCHAR* pathMsg = _T_ECLIPSE("%s\n'%s' in your current PATH");
+static _TCHAR* shareMsg = _T_ECLIPSE("No exit data available.");
+static _TCHAR* noVMMsg =
+_T_ECLIPSE("A Java Runtime Environment (JRE) or Java Development Kit (JDK)\n\
+must be available in order to run %s. No Java virtual machine\n\
+was found after searching the following locations:\n\
+%s");
+static _TCHAR* startupMsg =
+_T_ECLIPSE("The %s executable launcher was unable to locate its \n\
+companion startup jar file.");
+
+static _TCHAR* homeMsg =
+_T_ECLIPSE("The %s executable launcher was unable to locate its \n\
+companion startup.jar file (in the same directory as the executable).");
+
+#define DEFAULT_EQUINOX_STARTUP _T_ECLIPSE("org.eclipse.equinox.startup")
+#define DEFAULT_STARTUP _T_ECLIPSE("startup.jar")
+#define CLASSPATH_PREFIX _T_ECLIPSE("-Djava.class.path=")
+
+/* Define constants for the options recognized by the launcher. */
+#define CONSOLE _T_ECLIPSE("-console")
+#define CONSOLELOG _T_ECLIPSE("-consoleLog")
+#define DEBUG _T_ECLIPSE("-debug")
+#define OS _T_ECLIPSE("-os")
+#define OSARCH _T_ECLIPSE("-arch")
+#define NOSPLASH _T_ECLIPSE("-nosplash")
+#define LAUNCHER _T_ECLIPSE("-launcher")
+#define SHOWSPLASH _T_ECLIPSE("-showsplash")
+#define STARTUP _T_ECLIPSE("-startup")
+#define VM _T_ECLIPSE("-vm")
+#define WS _T_ECLIPSE("-ws")
+#define NAME _T_ECLIPSE("-name")
+#define VMARGS _T_ECLIPSE("-vmargs") /* special option processing required */
+#define CP _T_ECLIPSE("-cp")
+#define CLASSPATH _T_ECLIPSE("-classpath")
+
+#define JAR _T_ECLIPSE("-jar")
+
+/* Define the variables to receive the option values. */
+static int needConsole = 0; /* True: user wants a console */
+static int debug = 0; /* True: output debugging info */
+static int noSplash = 0; /* True: do not show splash win */
+static _TCHAR* osArg = _T_ECLIPSE(DEFAULT_OS);
+static _TCHAR* osArchArg = _T_ECLIPSE(DEFAULT_OS_ARCH);
+static _TCHAR* showSplashArg = NULL; /* showsplash data (main launcher window) */
+static _TCHAR * startupArg = NULL; /* path of the startup.jar the user wants to run relative to the program path */
+static _TCHAR* vmName = NULL; /* Java VM that the user wants to run */
+static _TCHAR* wsArg = _T_ECLIPSE(DEFAULT_WS); /* the SWT supported GUI to be used */
+static _TCHAR* name = NULL; /* program name */
+
+/* Define a table for processing command line options. */
+typedef struct
+{
+ _TCHAR* name; /* the option recognized by the launcher */
+ _TCHAR** value; /* the variable where the option value is saved */
+ int* flag; /* the variable that is set if the option is defined */
+ int remove; /* the number of argments to remove from the list */
+} Option;
+static Option options[] = {
+ { CONSOLE, NULL, &needConsole, 0 },
+ { CONSOLELOG, NULL, &needConsole, 0 },
+ { DEBUG, NULL, &debug, 0 },
+ { NOSPLASH, NULL, &noSplash, 1 },
+ { OS, &osArg, NULL, 2 },
+ { OSARCH, &osArchArg, NULL, 2 },
+ { SHOWSPLASH, &showSplashArg, NULL, 2 },
+ { STARTUP, &startupArg, NULL, 2 },
+ { VM, &vmName, NULL, 2 },
+ { NAME, &name, NULL, 2 },
+ { WS, &wsArg, NULL, 2 } };
+static int optionsSize = (sizeof(options) / sizeof(options[0]));
+
+/* Define the required VM arguments (all platforms). */
+static _TCHAR* cp = NULL;
+static _TCHAR** reqVMarg[] = { &cp, NULL }; /* required VM args */
+static _TCHAR** userVMarg = NULL; /* user specific args for the Java VM */
+
+/* Local methods */
+static void parseArgs( int* argc, _TCHAR* argv[] );
+static _TCHAR** parseArgList( _TCHAR *data );
+static void freeArgList( _TCHAR** data );
+static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] );
+static _TCHAR* formatVmCommandMsg( _TCHAR* args[] );
+ _TCHAR* getProgramDir();
+static _TCHAR* getDefaultOfficialName();
+static _TCHAR* findStartupJar();
+static _TCHAR ** getRelaunchCommand( _TCHAR **vmCommand );
+
+
+/* Record the arguments that were used to start the original executable */
+JNIEXPORT void setInitialArgs(int argc, _TCHAR** argv) {
+ initialArgc = argc;
+ initialArgv = argv;
+}
+
+/* this method must match the RunMethod typedef in eclipseMain.c */
+/* vmArgs must be NULL terminated */
+JNIEXPORT int run(int argc, _TCHAR* argv[], _TCHAR* vmArgs[])
+{
+ _TCHAR* shippedVM = NULL;
+ _TCHAR* vmSearchPath = NULL;
+ _TCHAR** vmCommand = NULL;
+ _TCHAR** vmCommandList = NULL;
+ _TCHAR** vmCommandArgs = NULL;
+ _TCHAR** progCommandArgs = NULL;
+ _TCHAR* vmCommandMsg = NULL;
+ _TCHAR** relaunchCommand = NULL;
+ _TCHAR* errorMsg;
+ int exitCode;
+
+ /* arg[0] should be the full pathname of this program. */
+ program = _tcsdup( argv[0] );
+
+ /* Parse command line arguments (looking for the VM to use). */
+ /* Override configuration file arguments */
+ parseArgs( &argc, argv );
+
+ /* Initialize official program name */
+ officialName = name != NULL ? _tcsdup( name ) : getDefaultOfficialName();
+
+ /* Initialize the window system. */
+ initWindowSystem( &argc, argv, !noSplash );
+
+ /* Find the directory where the Eclipse program is installed. */
+ programDir = getProgramDir();
+ if (programDir == NULL)
+ {
+ errorMsg = malloc( (_tcslen(homeMsg) + _tcslen(officialName) + 10) * sizeof(_TCHAR) );
+ _stprintf( errorMsg, homeMsg, officialName );
+ displayMessage( officialName, errorMsg );
+ free( errorMsg );
+ exit( 1 );
+ }
+
+ /* If the user did not specify a VM to be used */
+ if (vmName == NULL)
+ {
+ /* Determine which type of VM should be used. */
+ vmName = ((debug || needConsole) ? consoleVM : defaultVM);
+
+ /* Try to find the VM shipped with eclipse. */
+ shippedVM = malloc( (_tcslen( programDir ) + _tcslen( shippedVMDir ) + _tcslen( vmName ) + 10) * sizeof(_TCHAR) );
+ _stprintf( shippedVM, _T_ECLIPSE("%s%s%s"), programDir, shippedVMDir, vmName );
+ javaVM = findCommand( shippedVM );
+
+ /* Format a message to indicate the default VM search path. */
+ vmSearchPath = malloc( (_tcslen( pathMsg ) + _tcslen( shippedVM ) + _tcslen( vmName ) + 10) * sizeof(_TCHAR) );
+ _stprintf( vmSearchPath, pathMsg, shippedVM, vmName );
+ free( shippedVM );
+ shippedVM = NULL;
+ }
+
+ /* If a Java VM has not been found yet */
+ if (javaVM == NULL)
+ {
+ /* Either verify the VM specified by the user or
+ attempt to find the VM in the user's PATH. */
+ javaVM = findCommand( vmName );
+ }
+
+ javaVM = findVMLibrary( javaVM );
+ /* If the VM was not found, display a message and exit. */
+ if (javaVM == NULL)
+ {
+ if (vmSearchPath != NULL) vmName = vmSearchPath; /* used default VM searching */
+ errorMsg = malloc( (_tcslen(noVMMsg) + _tcslen(officialName) + _tcslen(vmName) + 10) * sizeof(_TCHAR) );
+ _stprintf( errorMsg, noVMMsg, officialName, vmName );
+ displayMessage( officialName, errorMsg );
+ free( errorMsg );
+ exit(1);
+ }
+
+ /* Find the startup.jar */
+ jarFile = findStartupJar();
+ if(jarFile == NULL) {
+ errorMsg = malloc( (_tcslen(startupMsg) + _tcslen(officialName) + 10) * sizeof(_TCHAR) );
+ _stprintf( errorMsg, startupMsg, officialName );
+ displayMessage( officialName, errorMsg );
+ free( errorMsg );
+ exit( 1 );
+ }
+
+ /* If the showsplash option was given */
+ if (!noSplash && showSplashArg)
+ {
+ showSplash(showSplashArg);
+ }
+
+ /* the startup jarFile goes on the classpath */
+ cp = malloc((_tcslen(CLASSPATH_PREFIX) + _tcslen(jarFile) + 1) * sizeof(_TCHAR));
+ cp = _tcscpy(cp, CLASSPATH_PREFIX);
+ _tcscat(cp, jarFile);
+
+ /* Get the command to start the Java VM. */
+ userVMarg = vmArgs;
+ getVMCommand( argc, argv, &vmCommandArgs, &progCommandArgs );
+
+ /* While the Java VM should be restarted */
+ vmCommand = vmCommandArgs;
+ vmCommandMsg = formatVmCommandMsg( vmCommand );
+ if (debug) _tprintf( goVMMsg, vmCommandMsg );
+ exitCode = startJavaVM(javaVM, vmCommandArgs, progCommandArgs );
+ switch( exitCode ) {
+ case 0: /* normal exit */
+ break;
+ case RESTART_LAST_EC:
+ relaunchCommand = getRelaunchCommand(initialArgv);
+ break;
+ case RESTART_NEW_EC:
+ if (exitData != 0) {
+ if (vmCommandList != NULL) freeArgList( vmCommandList );
+ vmCommandList = parseArgList( exitData );
+ relaunchCommand = getRelaunchCommand(vmCommandList);
+ } else {
+ if (debug) displayMessage( officialName, shareMsg );
+ }
+ break;
+ default: {
+ _TCHAR *title = _tcsdup(officialName);
+ vmCommand = NULL;
+ errorMsg = NULL;
+ if (exitData != 0) {
+ errorMsg = exitData;
+ if (_tcslen( errorMsg ) == 0) {
+ free( errorMsg );
+ errorMsg = NULL;
+ } else {
+ _TCHAR *str;
+ if (_tcsncmp(errorMsg, _T_ECLIPSE("<title>"), _tcslen(_T_ECLIPSE("<title>"))) == 0) {
+ str = _tcsstr(errorMsg, _T_ECLIPSE("</title>"));
+ if (str != NULL) {
+ free( title );
+ str[0] = _T_ECLIPSE('\0');
+ title = _tcsdup( errorMsg + _tcslen(_T_ECLIPSE("<title>")) );
+ str = _tcsdup( str + _tcslen(_T_ECLIPSE("</title>")) );
+ free( errorMsg );
+ errorMsg = str;
+ }
+ }
+ }
+ } else {
+ if (debug) displayMessage( title, shareMsg );
+ }
+ if (errorMsg == NULL) {
+ errorMsg = malloc( (_tcslen(exitMsg) + _tcslen(vmCommandMsg) + 10) * sizeof(_TCHAR) );
+ _stprintf( errorMsg, exitMsg, exitCode, vmCommandMsg );
+ }
+ displayMessage( title, errorMsg );
+ free( title );
+ free( errorMsg );
+ break;
+ }
+ }
+
+ if(relaunchCommand != NULL)
+ restartLauncher(program, relaunchCommand);
+
+ /* Cleanup time. */
+ free( vmCommandMsg );
+ free( jarFile );
+ free( cp );
+ free( programDir );
+ free( program );
+ if ( vmSearchPath != NULL ) free( vmSearchPath );
+ if ( vmCommandList != NULL ) freeArgList( vmCommandList );
+ free( officialName );
+
+ return 0;
+}
+
+/*
+ * Parse arguments of the command.
+ */
+static void parseArgs( int* pArgc, _TCHAR* argv[] )
+{
+ Option* option;
+ int remArgs;
+ int index;
+ int i;
+
+ /* Ensure the list of user argument is NULL terminated. */
+ /*argv[ *pArgc ] = NULL;*/
+
+ /* For each user defined argument (excluding the program) */
+ for (index = 1; index < *pArgc; index++){
+ remArgs = 0;
+
+ /* Find the corresponding argument is a option supported by the launcher */
+ option = NULL;
+ for (i = 0; option == NULL && i < optionsSize; i++)
+ {
+ if (_tcsicmp( argv[ index ], options[ i ].name ) == 0)
+ option = &options[ i ];
+ }
+
+ /* If the option is recognized by the launcher */
+ if (option != NULL)
+ {
+ /* If the option requires a value and there is one, extract the value. */
+ if (option->value != NULL && (index+1) < *pArgc)
+ *option->value = argv[ index+1 ];
+
+ /* If the option requires a flag to be set, set it. */
+ if (option->flag != NULL)
+ *option->flag = 1;
+ remArgs = option->remove;
+ }
+
+ /* Remove any matched arguments from the list. */
+ if (remArgs > 0)
+ {
+ for (i = (index + remArgs); i <= *pArgc; i++)
+ {
+ argv[ i - remArgs ] = argv[ i ];
+ }
+ index--;
+ *pArgc -= remArgs;
+ }
+ }
+}
+
+/*
+ * Free the memory allocated by parseArgList().
+ */
+static void freeArgList( _TCHAR** data ) {
+ if (data == NULL) return;
+ free( data [0] );
+ free( data );
+}
+
+/*
+ * Parse the data into a list of arguments separated by \n.
+ *
+ * The list of strings returned by this function must be freed with
+ * freeArgList().
+ */
+static _TCHAR** parseArgList( _TCHAR* data ) {
+ int totalArgs = 0, dst = 0, length;
+ _TCHAR *ch1, *ch2, **execArg;
+ length = _tcslen( data );
+ ch1 = ch2 = data;
+ while ((ch2 = _tcschr( ch1, _T_ECLIPSE('\n') )) != NULL) {
+ totalArgs++;
+ ch1 = ch2 + 1;
+ }
+ if (ch1 != data + length) totalArgs++;
+ execArg = malloc( (totalArgs + 1) * sizeof( _TCHAR* ) );
+ ch1 = ch2 = data;
+ while ((ch2 = _tcschr( ch1, _T_ECLIPSE('\n') )) != NULL) {
+ execArg[ dst++ ] = ch1;
+ ch2[ 0 ] = _T_ECLIPSE('\0');
+ ch1 = ch2 + 1;
+ }
+ if (ch1 != data + length) execArg[ dst++ ] = ch1;
+ execArg[ dst++ ] = NULL;
+ return execArg;
+}
+
+/*
+ * Get the command and arguments to start the Java VM.
+ *
+ * Memory allocated by this function is assumed to be
+ * deallocated when the program terminates.
+ *
+ * Some of the arguments returned by this function were
+ * passed directly from the main( argv ) array so they
+ * should not be deallocated.
+ *
+ * Arguments are split into 2: vm arguments and program arguments
+ */
+static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] )
+{
+ _TCHAR** vmArg;
+ int nReqVMarg = 0;
+ int nVMarg = 0;
+ int totalVMArgs;
+ int totalProgArgs;
+ int src;
+ int dst;
+
+ /* If the user specified "-vmargs", add them instead of the default VM args. */
+ vmArg = (userVMarg != NULL) ? userVMarg : getArgVM( javaVM );
+
+ /* Calculate the number of VM arguments. */
+ while (vmArg[ nVMarg ] != NULL)
+ nVMarg++;
+
+ /* Calculate the number of required VM arguments. */
+ while (reqVMarg[ nReqVMarg ] != NULL)
+ nReqVMarg++;
+
+ /* VM argument list */
+ totalVMArgs = nVMarg + nReqVMarg + 1;
+ *vmArgv = malloc( totalVMArgs * sizeof(_TCHAR*) );
+
+ dst = 0;
+ for (src = 0; src < nVMarg; src++){
+ /*if the user specified a classpath, skip it */
+ if(_tcscmp(vmArg[src], cp) == 0){
+ src++;
+ continue;
+ }
+ (*vmArgv)[ dst++ ] = vmArg[ src ];
+ }
+
+ /* For each required VM arg */
+ for (src = 0; src < nReqVMarg; src++)
+ (*vmArgv)[ dst++ ] = *(reqVMarg[ src ]);
+
+ (*vmArgv)[dst] = NULL;
+
+ /* Program arguments */
+ /* OS <os> + WS <ws> + ARCH <arch> + LAUNCHER <launcher> + NAME <officialName> +
+ * + SHOWSPLASH <cmd> + argv[] + VM + <vm> + VMARGS + vmArg + requiredVMargs
+ * + NULL)
+ */
+ totalProgArgs = 2 + 2 + 2 + 2 + 2 + 2 + argc + 2 + 1 + nVMarg + nReqVMarg + 1;
+ *progArgv = malloc( totalProgArgs * sizeof( _TCHAR* ) );
+ dst = 0;
+
+ /* Append the required options. */
+ (*progArgv)[ dst++ ] = OS;
+ (*progArgv)[ dst++ ] = osArg;
+ (*progArgv)[ dst++ ] = WS;
+ (*progArgv)[ dst++ ] = wsArg;
+ if (_tcslen(osArchArg) > 0) {
+ (*progArgv)[ dst++ ] = OSARCH;
+ (*progArgv)[ dst++ ] = osArchArg;
+ }
+
+ /* Append the launcher command */
+ (*progArgv)[ dst++ ] = LAUNCHER;
+ (*progArgv)[ dst++ ] = program;
+
+ /* Append the name command */
+ (*progArgv)[ dst++ ] = NAME;
+ (*progArgv)[ dst++ ] = officialName;
+
+ /* Append the show splash window command, if defined. */
+ if (!noSplash)
+ {
+ (*progArgv)[ dst++ ] = SHOWSPLASH;
+ }
+
+ /* Append the remaining user defined arguments. */
+ for (src = 1; src < argc; src++)
+ {
+ (*progArgv)[ dst++ ] = argv[ src ];
+ }
+
+ /* Append VM and VMARGS to be able to relaunch using exit data. */
+ (*progArgv)[ dst++ ] = VM;
+ (*progArgv)[ dst++ ] = javaVM;
+ (*progArgv)[ dst++ ] = VMARGS;
+
+ for (src = 0; src < nVMarg; src++)
+ (*progArgv)[ dst++ ] = vmArg[ src ];
+
+ /* For each required VM arg */
+ for (src = 0; src < nReqVMarg; src++)
+ (*progArgv)[ dst++ ] = *(reqVMarg[ src ]);
+
+ (*progArgv)[ dst++ ] = NULL;
+
+ }
+
+ /* Format the JVM start command for error messages
+ *
+ * This method formats a string with the JVM start command (and all arguments)
+ * that can be used in displaying error messages. The string returned from this
+ * method is probably not NLS compliant and must be deallocated by the caller.
+ */
+static _TCHAR* formatVmCommandMsg( _TCHAR* args[] )
+{
+ int index;
+ int length;
+ _TCHAR* ch;
+ _TCHAR* message;
+
+ /* Determine the length of the message buffer. */
+ length = 0;
+ for (index = 0; args[index] != NULL; index++)
+ {
+ length += _tcslen(args[index]) + 1;
+ }
+ message = malloc( (length + 5) * sizeof(_TCHAR) );
+
+ /* Format the message such that options (args starting with '-') begin
+ on a new line. Otherwise, the Motif MessageBox does not automatically wrap
+ the messages and the message window can extend beyond both sides of the display. */
+ ch = message;
+ for (index = 0; args[index] != NULL; index++)
+ {
+ if (args[index][0] == _T_ECLIPSE('-') && *(ch-1) == _T_ECLIPSE(' '))
+ *(ch-1) = _T_ECLIPSE('\n');
+ _tcscpy( ch, args[index] );
+ ch += _tcslen( args[index] );
+ *ch++ = _T_ECLIPSE(' ');
+ }
+ *ch = _T_ECLIPSE('\0');
+
+ return message;
+}
+
+/*
+ * Determine the default official application name
+ *
+ * This function provides the default application name that appears in a variety of
+ * places such as: title of message dialog, title of splash screen window
+ * that shows up in Windows task bar.
+ * It is computed from the name of the launcher executable and
+ * by capitalizing the first letter. e.g. "c:/ide/eclipse.exe" provides
+ * a default name of "Eclipse".
+ */
+static _TCHAR* getDefaultOfficialName()
+{
+ _TCHAR *ch = NULL;
+
+ /* Skip the directory part */
+ ch = _tcsrchr( program, dirSeparator );
+ if (ch == NULL) ch = program;
+ else ch++;
+
+ ch = _tcsdup( ch );
+#ifdef _WIN32
+ {
+ /* Search for the extension .exe and cut it */
+ _TCHAR *extension = _tcsrchr(ch, _T_ECLIPSE('.'));
+ if (extension != NULL)
+ {
+ *extension = _T_ECLIPSE('\0');
+ }
+ }
+#endif
+ /* Upper case the first character */
+#ifndef LINUX
+ {
+ *ch = _totupper(*ch);
+ }
+#else
+ {
+ if (*ch >= 'a' && *ch <= 'z')
+ {
+ *ch -= 32;
+ }
+ }
+#endif
+ return ch;
+}
+
+/* Determine the Program Directory
+ *
+ * This function takes the directory where program executable resides and
+ * determines the installation directory.
+ */
+_TCHAR* getProgramDir( )
+{
+ _TCHAR* ch;
+ _TCHAR* programDir;
+
+ programDir = malloc( (_tcslen( program ) + 1) * sizeof(_TCHAR) );
+ _tcscpy( programDir, program );
+ ch = _tcsrchr( programDir, dirSeparator );
+ if (ch != NULL)
+ {
+ *(ch+1) = _T_ECLIPSE('\0');
+ return programDir;
+ }
+
+ free( programDir );
+ return NULL;
+}
+
+static _TCHAR* findStartupJar(){
+ _TCHAR * file;
+ _TCHAR * pluginsPath;
+ struct _stat stats;
+ int pathLength;
+
+ if( startupArg != NULL ) {
+ /* startup jar was specified on the command line */
+
+ /* Construct the absolute name of the startup jar */
+ file = malloc( (_tcslen( programDir ) + _tcslen( startupArg ) + 1) * sizeof( _TCHAR ) );
+ file = _tcscpy( file, programDir );
+ file = _tcscat( file, startupArg );
+
+ /* If the file does not exist, treat the argument as an absolute path */
+ if (_tstat( file, &stats ) != 0)
+ {
+ free( file );
+ file = malloc( (_tcslen( startupArg ) + 1) * sizeof( _TCHAR ) );
+ file = _tcscpy( file, startupArg );
+
+ /* still doesn't exit? */
+ if (_tstat( file, &stats ) != 0) {
+ file = NULL;
+ }
+ }
+ /* TODO What should the policy here be, if we didn't find what they
+ * specified? (Its harder to specify equinox.startup on the mac.) */
+ if(file != NULL)
+ return file;
+ }
+
+ pathLength = _tcslen(programDir);
+#ifdef MACOSX
+ pathLength += 9;
+#endif
+ pluginsPath = malloc( (pathLength + 1 + 7) * sizeof(char));
+ _tcscpy(pluginsPath, programDir);
+ if(pluginsPath[pathLength - 1] != dirSeparator) {
+ pluginsPath[pathLength] = dirSeparator;
+ pluginsPath[pathLength + 1] = 0;
+ }
+#ifdef MACOSX
+ _tcscat(pluginsPath, _T_ECLIPSE("../../../"));
+#endif
+ _tcscat(pluginsPath, _T_ECLIPSE("plugins"));
+
+ /* equinox startup jar? */
+ file = findFile(pluginsPath, _T_ECLIPSE("org.eclipse.equinox.startup"));
+ if(file != NULL)
+ return file;
+
+ file = malloc( (_tcslen( DEFAULT_STARTUP ) + 1) * sizeof( _TCHAR ) );
+ file = _tcscpy( file, DEFAULT_STARTUP );
+ return file;
+}
+
+/*
+ * Return the portion of the vmCommand that should be used for relaunching
+ *
+ * The memory allocated for the command array must be freed
+ */
+static _TCHAR ** getRelaunchCommand( _TCHAR **vmCommand )
+{
+ int i = -1, req = 0, begin = -1;
+ int idx = 0;
+ _TCHAR ** relaunch;
+
+ if (vmCommand == NULL) return NULL;
+ while(vmCommand[++i] != NULL){
+ if ( begin == -1 && _tcsicmp( vmCommand[i], *reqVMarg[req] ) == 0) {
+ if(reqVMarg[++req] == NULL){
+ begin = i + 1;
+ }
+ }
+ }
+
+ relaunch = malloc((i + 1) * sizeof(_TCHAR *));
+ for (i = begin; vmCommand[i] != NULL; i++){
+ if (_tcsicmp(vmCommand[i], SHOWSPLASH) == 0) {
+ /* remove if the next argument is not the bitmap to show */
+ if(vmCommand[i + 1] != NULL && vmCommand[i + 1][0] == _T_ECLIPSE('-')) {
+ i++;
+ continue;
+ }
+ } else if(_tcsicmp(vmCommand[i], JAR) == 0 ) {
+ /* skip -jar */
+ i++;
+ continue;
+ }
+ relaunch[idx++] = vmCommand[i];
+ }
+ relaunch[idx] = NULL;
+ return relaunch;
+}

Back to the top