### Eclipse Workspace Patch 1.0 #P org.eclipse.equinox.executable Index: library/eclipse.c =================================================================== RCS file: /cvsroot/rt/org.eclipse.equinox/framework/bundles/org.eclipse.equinox.executable/library/eclipse.c,v retrieving revision 1.72.2.1 diff -u -r1.72.2.1 eclipse.c --- library/eclipse.c 10 Aug 2010 19:43:00 -0000 1.72.2.1 +++ library/eclipse.c 24 Aug 2010 18:57:47 -0000 @@ -9,6 +9,7 @@ * IBM Corporation - initial API and implementation * Kevin Cornell (Rational Software Corporation) * Markus Schorn (Wind River Systems), bug 193340 + * Martin Oberhuber (Wind River) - [149994] Add --launcher.appendVmargs *******************************************************************************/ /* Eclipse Program Launcher @@ -233,6 +234,8 @@ #define LIBRARY _T_ECLIPSE("--launcher.library") #define SUPRESSERRORS _T_ECLIPSE("--launcher.suppressErrors") #define INI _T_ECLIPSE("--launcher.ini") +#define APPEND_VMARGS _T_ECLIPSE("--launcher.appendVmargs") +#define OVERRIDE_VMARGS _T_ECLIPSE("--launcher.overrideVmargs") #define SECOND_THREAD _T_ECLIPSE("--launcher.secondThread") #define PERM_GEN _T_ECLIPSE("--launcher.XXMaxPermSize") @@ -254,6 +257,7 @@ static int noSplash = 0; /* True: do not show splash win */ static int suppressErrors = 0; /* True: do not display errors dialogs */ int secondThread = 0; /* True: start the VM on a second thread */ +static int appendVmargs = 0; /* True: append cmdline vmargs to launcher.ini vmargs */ static _TCHAR* showSplashArg = NULL; /* showsplash data (main launcher window) */ static _TCHAR* splashBitmap = NULL; /* the actual splash bitmap */ @@ -264,6 +268,7 @@ static _TCHAR** filePath = NULL; /* list of files to open */ static _TCHAR* timeoutString = NULL; /* timeout value for opening a file */ static _TCHAR* defaultAction = NULL; /* default action for non '-' command line arguments */ +static _TCHAR* iniFile = NULL; /* the launcher.ini file set if --launcher.ini was specified */ /* variables for ee options */ static _TCHAR* eeExecutable = NULL; @@ -289,6 +294,7 @@ /* don't assign it and only remove (remove - 1) arguments */ #define ADJUST_PATH 4 /* value is a path, do processing on relative paths to try and make them absolute */ #define VALUE_IS_LIST 8 /* value is a pointer to a tokenized _TCHAR* string for EE files, or a _TCHAR** list for the command line */ +#define INVERT_FLAG 16 /* invert the meaning of a flag, i.e. reset it */ static Option options[] = { { CONSOLE, &needConsole, VALUE_IS_FLAG, 0 }, @@ -297,8 +303,10 @@ { NOSPLASH, &noSplash, VALUE_IS_FLAG, 1 }, { SUPRESSERRORS, &suppressErrors, VALUE_IS_FLAG, 1}, { SECOND_THREAD, &secondThread, VALUE_IS_FLAG, 1 }, + { APPEND_VMARGS, &appendVmargs, VALUE_IS_FLAG, 1 }, + { OVERRIDE_VMARGS, &appendVmargs, VALUE_IS_FLAG | INVERT_FLAG, 1 }, { LIBRARY, NULL, 0, 2 }, /* library was parsed by exe, just remove it */ - { INI, NULL, 0, 2 }, /* same with ini */ + { INI, &iniFile, 0, 2 }, /* same with ini */ { OS, &osArg, 0, 2 }, { OSARCH, &osArchArg, 0, 2 }, { SHOWSPLASH, &showSplashArg, OPTIONAL_VALUE, 2 }, @@ -331,6 +339,7 @@ /* Local methods */ static void parseArgs( int* argc, _TCHAR* argv[] ); static void processDefaultAction(int argc, _TCHAR* argv[]); +static void mergeUserVMArgs( _TCHAR **vmArgs[] ); static void getVMCommand( int launchMode, int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] ); static int determineVM(_TCHAR** msg); static int vmEEProps(_TCHAR* eeFile, _TCHAR** msg); @@ -422,8 +431,13 @@ exit( 1 ); } - /* platform specific processing of user's vmargs */ - processVMArgs(&vmArgs); + if (vmArgs != NULL) { + /* reconcile VM Args from commandline with launcher.ini (append or override), + * this always allocate new memory */ + mergeUserVMArgs(&vmArgs); + /* platform specific processing of user's vmargs */ + processVMArgs(&vmArgs); + } launchMode = determineVM(&msg); if (launchMode == -1) { /* problem */ @@ -641,6 +655,7 @@ if ( cpValue != NULL) free( cpValue ); if ( exitData != NULL ) free( exitData ); if ( splashBitmap != NULL ) free( splashBitmap ); + if (vmArgs != NULL) free(vmArgs); if (javaResults == NULL) return -1; @@ -720,7 +735,7 @@ /* If the option requires a value and there is one, extract the value. */ if (option->value != NULL) { if (option->flag & VALUE_IS_FLAG) - *((int *) option->value) = 1; + *((int *) option->value) = (option->flag & INVERT_FLAG) ? 0 : 1; else { int count = 1; if (option->flag & VALUE_IS_LIST) { @@ -796,9 +811,47 @@ return execArg; } +/* Return the list of args from the launcher ini file (if it exists). Caller is responsible to free(). */ +static _TCHAR** getConfigArgs() { + _TCHAR** configArgv = NULL; + _TCHAR * configFile = NULL; + int configArgc = 0; + int ret = 0; + + configFile = (iniFile != NULL) ? iniFile : getIniFile(program, consoleLauncher); + ret = readConfigFile(configFile, &configArgc, &configArgv); + if (ret == 0) + return configArgv; + return NULL; +} + +/** Append Commandline VM Args to VM Args that came from the launcher.ini + * Always returns new memory even if no new arguments were appended */ +static void mergeUserVMArgs(_TCHAR **vmArgs[]) { + _TCHAR** configVMArgs = NULL; + _TCHAR** configArgs = NULL; + + if (appendVmargs != 0 && indexOf(VMARGS, initialArgv) > 0) { + /* Get vmargs from the launcher.ini, if any */ + configArgs = getConfigArgs(); + if (configArgs != NULL) { + int vmArg = indexOf(VMARGS, configArgs); + if (vmArg >= 0) + configVMArgs = configArgs + vmArg + 1; + } + } + + /* This always allocates new memory so we don't need to guess if it is safe + * to free later */ + *vmArgs = concatArgs(configVMArgs, *vmArgs); + if (configArgs != NULL) + free(configArgs); +} + static void adjustVMArgs( _TCHAR *javaVM, _TCHAR *jniLib, _TCHAR **vmArgv[] ) { /* Sun VMs need some extra perm gen space */ - if (permGen != NULL && isSunVM(javaVM, jniLib)) { + /* Detecting Sun VM is expensive - only do so if necessary */ + if (permGen != NULL) { int specified = 0, i = -1; /* first check to see if it is already specified */ @@ -809,7 +862,7 @@ } } - if (!specified) { + if (!specified && isSunVM(javaVM, jniLib)) { _TCHAR ** oldArgs = *vmArgv; _TCHAR *newArg = malloc((_tcslen(XXPERMGEN) + _tcslen(permGen) + 1) * sizeof(_TCHAR)); _stprintf(newArg, _T_ECLIPSE("%s%s"), XXPERMGEN, permGen); @@ -884,11 +937,11 @@ /* Program arguments */ /* OS + WS + ARCH + LAUNCHER + NAME + - * + LIBRARY + SHOWSPLASH + EXITDATA + STARTUP + argv[] + VM + + + * + LIBRARY + SHOWSPLASH + EXITDATA + STARTUP + OVERRIDE/APPEND + argv[] + VM + + * VMARGS + vmArg + requiredVMargs * + NULL) */ - totalProgArgs = 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + argc + 2 + 1 + nVMarg + nEEargs + nReqVMarg + 1; + totalProgArgs = 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + argc + 2 + 1 + nVMarg + nEEargs + nReqVMarg + 1; *progArgv = malloc( totalProgArgs * sizeof( _TCHAR* ) ); dst = 0; @@ -928,6 +981,9 @@ (*progArgv)[ dst++ ] = STARTUP; (*progArgv)[ dst++ ] = jarFile; + /* override or append vm args */ + (*progArgv)[ dst++ ] = appendVmargs ? APPEND_VMARGS : OVERRIDE_VMARGS; + /* Append the exit data command. */ if (sharedID) { (*progArgv)[ dst++ ] = EXITDATA; Index: library/eclipseConfig.c =================================================================== RCS file: /cvsroot/rt/org.eclipse.equinox/framework/bundles/org.eclipse.equinox.executable/library/eclipseConfig.c,v retrieving revision 1.12.6.1 diff -u -r1.12.6.1 eclipseConfig.c --- library/eclipseConfig.c 10 Aug 2010 19:50:06 -0000 1.12.6.1 +++ library/eclipseConfig.c 24 Aug 2010 18:57:47 -0000 @@ -38,6 +38,20 @@ int result; if (program == NULL || argc == NULL || argv == NULL) return -1; + +#if defined(_WIN32) && defined(_WIN32_CONSOLE) + config_file = getIniFile(program, 1); +#else + config_file = getIniFile(program, 0); +#endif + + result = readConfigFile(config_file, argc, argv); + free(config_file); + return result; +} + +_TCHAR* getIniFile(_TCHAR* program, int consoleLauncher){ + _TCHAR* config_file = NULL; /* Get a copy with room for .ini at the end */ config_file = malloc( (_tcslen(program) + 5) * sizeof(_TCHAR)); @@ -53,8 +67,7 @@ extension = config_file + _tcslen(config_file); } _tcscpy(extension, _T_ECLIPSE(".ini")); -#ifdef _WIN32_CONSOLE - { + if(consoleLauncher){ /* We are the console version, if the ini file does not exist, try * removing the 'c' from the end of the program name */ struct _stat stats; @@ -62,16 +75,12 @@ _tcscpy(extension - 1, extension); } } -#endif } #else /* Append the extension */ strcat(config_file, ".ini"); #endif - - result = readConfigFile(config_file, argc, argv); - free(config_file); - return result; + return config_file; } int readConfigFile( _TCHAR * config_file, int *argc, _TCHAR ***argv ) Index: library/eclipseConfig.h =================================================================== RCS file: /cvsroot/rt/org.eclipse.equinox/framework/bundles/org.eclipse.equinox.executable/library/eclipseConfig.h,v retrieving revision 1.3 diff -u -r1.3 eclipseConfig.h --- library/eclipseConfig.h 6 Oct 2009 18:42:49 -0000 1.3 +++ library/eclipseConfig.h 24 Aug 2010 18:57:47 -0000 @@ -24,11 +24,24 @@ * * This method will call readConfigFile to read the actual ini file * + * This method will use getIniFile with a value for consoleLauncher that + * is determined at compile time. Clients who are not the actual + * win32 console executable should instead use getIniFile and readConfigFile. + * * Returns 0 if success. */ extern int readIniFile(_TCHAR* program, int *argc, _TCHAR ***argv); /** + * Return the path to the launcher ini file for the corresponding program + * argument. On win32, an "eclipsec.exe' console launcher can use the "eclipse.ini" + * ini file. + * consoleLauncher : whether or not we are using the win32 "eclipsec" console launcher + * has no affect on other platforms + */ +extern _TCHAR* getIniFile(_TCHAR* program, int consoleLauncher); + +/** * Reads the given configuration file * The argument argv refers to a newly allocated array of strings. * The first entry is the program name to mimic the expectations Index: library/eclipseUtil.c =================================================================== RCS file: /cvsroot/rt/org.eclipse.equinox/framework/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c,v retrieving revision 1.13 diff -u -r1.13 eclipseUtil.c --- library/eclipseUtil.c 8 Feb 2010 20:58:29 -0000 1.13 +++ library/eclipseUtil.c 24 Aug 2010 18:57:47 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2005 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Kevin Cornell (Rational Software Corporation) + * Martin Oberhuber (Wind River) - [149994] Add --launcher.appendVmargs *******************************************************************************/ /* Eclipse Launcher Utility Methods */ @@ -159,6 +160,48 @@ } /* + * Concatenates two NULL-terminated arrays of Strings, + * returning a new NULL-terminated array. + * The returned array must be freed with the regular free(). + */ +_TCHAR** concatArgs(_TCHAR** l1, _TCHAR** l2) { + _TCHAR** newArray = NULL; + int size1 = 0; + int size2 = 0; + + if (l1 != NULL) + while (l1[size1] != NULL) size1++; + if (l2 != NULL) + while (l2[size2] != NULL) size2++; + + newArray = (_TCHAR **) malloc((size1 + size2 + 1) * sizeof(_TCHAR *)); + if (size1 > 0) { + memcpy(newArray, l1, size1 * sizeof(_TCHAR *)); + } + if (size2 > 0) { + memcpy(newArray + size1, l2, size2 * sizeof(_TCHAR *)); + } + newArray[size1 + size2] = NULL; + return newArray; +} + +/* + * returns the relative position of arg in the NULL-terminated list of args, + * or -1 if args does not contain arg. + */ +int indexOf(_TCHAR *arg, _TCHAR **args) { + int i = -1; + if (arg != NULL && args != NULL) { + while (args[++i] != NULL) { + if (_tcsicmp(arg, args[i]) == 0) { + return i; + } + } + } + return -1; +} + +/* * buffer contains a pathSeparator separated list of paths, check * that it contains all the paths given. Each path is expected to be * terminated with a pathSeparator character. Index: library/eclipseUtil.h =================================================================== RCS file: /cvsroot/rt/org.eclipse.equinox/framework/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h,v retrieving revision 1.8 diff -u -r1.8 eclipseUtil.h --- library/eclipseUtil.h 8 Feb 2010 20:58:28 -0000 1.8 +++ library/eclipseUtil.h 24 Aug 2010 18:57:47 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2005 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Kevin Cornell (Rational Software Corporation) + * Martin Oberhuber (Wind River) - [149994] Add --launcher.appendVmargs *******************************************************************************/ #ifndef ECLIPSE_UTIL_H @@ -37,6 +38,12 @@ /* take a NULL terminated array of strings and concatenate them together into one string */ extern _TCHAR * concatStrings(_TCHAR** strs); +/* Concatenates two NULL-terminated arrays of strings into a new array of strings */ +extern _TCHAR** concatArgs(_TCHAR** l1, _TCHAR** l2); + +/* Returns the relative position of arg in the NULL-terminated list of args, or -1 */ +extern int indexOf(_TCHAR *arg, _TCHAR **args); + /* take a NULL terminated array of strings and concatenate them together using the give pathSeparator */ extern _TCHAR* concatPaths(_TCHAR** paths, _TCHAR pathSeparator); #P org.eclipse.equinox.launcher Index: src/org/eclipse/equinox/launcher/Main.java =================================================================== RCS file: /cvsroot/rt/org.eclipse.equinox/framework/bundles/org.eclipse.equinox.launcher/src/org/eclipse/equinox/launcher/Main.java,v retrieving revision 1.60 diff -u -r1.60 Main.java --- src/org/eclipse/equinox/launcher/Main.java 17 Mar 2010 20:25:23 -0000 1.60 +++ src/org/eclipse/equinox/launcher/Main.java 24 Aug 2010 18:57:48 -0000 @@ -138,6 +138,8 @@ private static final String NAME = "-name"; //$NON-NLS-1$ private static final String LAUNCHER = "-launcher"; //$NON-NLS-1$ private static final String LIBRARY = "--launcher.library"; //$NON-NLS-1$ + private static final String APPEND_VMARGS = "--launcher.appendVmargs"; //$NON-NLS-1$ + private static final String OVERRIDE_VMARGS = "--launcher.overrideVmargs"; //$NON-NLS-1$ private static final String NL = "-nl"; //$NON-NLS-1$ private static final String ENDSPLASH = "-endsplash"; //$NON-NLS-1$ private static final String SPLASH_IMAGE = "splash.bmp"; //$NON-NLS-1$ @@ -1490,6 +1492,11 @@ found = true; } + //just consume the --launcher.overrideVmargs and --launcher.appendVmargs + if (args[i].equalsIgnoreCase(APPEND_VMARGS) || args[i].equalsIgnoreCase(OVERRIDE_VMARGS)) { + found = true; + } + // check if this is initialization pass if (args[i].equalsIgnoreCase(INITIALIZE)) { initialize = true;