Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.executable/library')
-rw-r--r--bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c2
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipse.c181
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipseOS.h2
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipseUtil.c17
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipseUtil.h3
-rw-r--r--bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtk.c11
-rw-r--r--bundles/org.eclipse.equinox.executable/library/make_version.mak2
-rw-r--r--bundles/org.eclipse.equinox.executable/library/motif/eclipseMotif.c2
-rw-r--r--bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c30
-rw-r--r--bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak2
-rw-r--r--bundles/org.eclipse.equinox.executable/library/wpf/eclipseWpf.cpp2
11 files changed, 162 insertions, 92 deletions
diff --git a/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c
index 5253728f0..47739962b 100644
--- a/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c
+++ b/bundles/org.eclipse.equinox.executable/library/carbon/eclipseCarbon.c
@@ -169,7 +169,7 @@ int main() {
void installAppleEventHandler();
-int reuseWorkbench(_TCHAR* filePath, int timeout) {
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
installAppleEventHandler();
return 0;
}
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipse.c b/bundles/org.eclipse.equinox.executable/library/eclipse.c
index 61e99be5c..a216e6e01 100644
--- a/bundles/org.eclipse.equinox.executable/library/eclipse.c
+++ b/bundles/org.eclipse.equinox.executable/library/eclipse.c
@@ -228,6 +228,7 @@ home directory.");
#define JAR _T_ECLIPSE("-jar")
#define OPENFILE _T_ECLIPSE("--launcher.openFile")
+#define DEFAULTACTION _T_ECLIPSE("--launcher.defaultAction")
#define TIMEOUT _T_ECLIPSE("--launcher.timeout")
#define LIBRARY _T_ECLIPSE("--launcher.library")
#define SUPRESSERRORS _T_ECLIPSE("--launcher.suppressErrors")
@@ -236,6 +237,7 @@ home directory.");
#define PERM_GEN _T_ECLIPSE("--launcher.XXMaxPermSize")
#define XXPERMGEN _T_ECLIPSE("-XX:MaxPermSize=")
+#define ACTION_OPENFILE _T_ECLIPSE("openFile")
/* constants for ee options file */
#define EE_EXECUTABLE _T_ECLIPSE("-Dee.executable=")
@@ -259,8 +261,9 @@ static _TCHAR * startupArg = NULL; /* path of the startup.jar the user want
static _TCHAR* vmName = NULL; /* Java VM that the user wants to run */
static _TCHAR* name = NULL; /* program name */
static _TCHAR* permGen = NULL; /* perm gen size for sun */
-static _TCHAR* filePath = NULL; /* file to open */
+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 */
/* variables for ee options */
static _TCHAR* eeExecutable = NULL;
@@ -277,17 +280,15 @@ typedef struct
void* value; /* the variable where the option value is saved */
/* value is a _TCHAR** or int* depending on if VALUE_IS_FLAG is set */
int flag; /* flags */
- int remove; /* the number of argments to remove from the list */
+ int remove; /* the number of argments to remove from the list, -1 can be used with VALUE_IS_LIST */
} Option;
/* flags for the Option struct */
-#define VALUE_IS_FLAG 1 /* value is an int*, if not set, value is a _TCHAR** */
+#define VALUE_IS_FLAG 1 /* value is an int*, if not set, value is a _TCHAR** or _TCHAR*** (VALUE_IS_LIST) */
#define OPTIONAL_VALUE 2 /* value is optional, if next arg does not start with '-', */
/* don't assign it and only remove (remove - 1) arguments */
-
-/* flags being used by EE options */
-#define EE_ADJUST_PATH 4 /* value is a path, do processing on relative paths to try and make them absolute */
-#define EE_PATH_LIST 8 /* value is a list of paths */
+#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 */
static Option options[] = {
{ CONSOLE, &needConsole, VALUE_IS_FLAG, 0 },
@@ -305,16 +306,17 @@ static Option options[] = {
{ VM, &vmName, 0, 2 },
{ NAME, &name, 0, 2 },
{ PERM_GEN, &permGen, 0, 2 },
- { OPENFILE, &filePath, 0, 2 },
+ { OPENFILE, &filePath, ADJUST_PATH | VALUE_IS_LIST, -1 },
{ TIMEOUT, &timeoutString, 0, 2 },
+ { DEFAULTACTION,&defaultAction, 0, 2 },
{ WS, &wsArg, 0, 2 } };
static int optionsSize = (sizeof(options) / sizeof(options[0]));
static Option eeOptions[] = {
- { EE_EXECUTABLE, &eeExecutable, EE_ADJUST_PATH, 0 },
- { EE_CONSOLE, &eeConsole, EE_ADJUST_PATH, 0 },
- { EE_VM_LIBRARY, &eeLibrary, EE_ADJUST_PATH, 0 },
- { EE_LIBRARY_PATH, &eeLibPath, EE_ADJUST_PATH | EE_PATH_LIST, 0 }
+ { EE_EXECUTABLE, &eeExecutable, ADJUST_PATH, 0 },
+ { EE_CONSOLE, &eeConsole, ADJUST_PATH, 0 },
+ { EE_VM_LIBRARY, &eeLibrary, ADJUST_PATH, 0 },
+ { EE_LIBRARY_PATH, &eeLibPath, ADJUST_PATH | VALUE_IS_LIST, 0 }
};
static int eeOptionsSize = (sizeof(eeOptions) / sizeof(eeOptions[0]));
@@ -328,6 +330,7 @@ static int nEEargs = 0;
/* Local methods */
static void parseArgs( int* argc, _TCHAR* argv[] );
+static void processDefaultAction(int argc, _TCHAR* argv[]);
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);
@@ -377,10 +380,14 @@ JNIEXPORT int run(int argc, _TCHAR* argv[], _TCHAR* vmArgs[])
/* Initialize official program name */
officialName = name != NULL ? _tcsdup( name ) : getDefaultOfficialName();
+ if (defaultAction != NULL) {
+ processDefaultAction(initialArgc, initialArgv);
+ }
+
/* try to open the specified file in an already running eclipse */
/* on Mac we are only registering an event handler here, always do this */
#ifndef MACOSX
- if (filePath != NULL)
+ if (filePath != NULL && filePath[0] != NULL)
#endif
{
int timeout = 60;
@@ -658,67 +665,109 @@ static _TCHAR** buildLaunchCommand( _TCHAR* program, _TCHAR** vmArgs, _TCHAR** p
memcpy(result + 1 + nVM, progArgs, nProg * sizeof(_TCHAR*));
return result;
}
+
+static void processDefaultAction(int argc, _TCHAR* argv[]) {
+ /* scan the arg list, no default if any start with '-' */
+ int i = 0;
+ for (i = 0; i < argc; i++) {
+ if (argv[i][0] == _T_ECLIPSE('-'))
+ return;
+ }
+ /* argv[0] is the program (eclipse), we process the default actions by inserting
+ * the appropriate -argument at argv[1]
+ */
+ if (argc <= 1)
+ return;
+
+ if (_tcsicmp(defaultAction, ACTION_OPENFILE) == 0) {
+ int newArgc = argc + 1;
+ _TCHAR ** newArgv = malloc(newArgc * sizeof(_TCHAR*));
+ newArgv[0] = argv[0];
+ newArgv[1] = OPENFILE;
+ memcpy(&newArgv[2], &argv[1], argc * sizeof(_TCHAR*));
+ parseArgs(&newArgc, newArgv);
+ free(newArgv);
+ }
+}
+
/*
* Parse arguments of the command.
*/
-static void parseArgs( int* pArgc, _TCHAR* argv[] )
-{
+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;*/
+ int remArgs;
+ int index;
+ int i;
+ _TCHAR * c;
/* For each user defined argument (excluding the program) */
- for (index = 1; index < *pArgc; index++){
- remArgs = 0;
+ 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];
+ break;
+ }
+ }
- /* 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 ];
- break;
- }
- }
+ /* If the option is recognized by the launcher */
+ if (option != NULL) {
+ int optional = 0;
+ c = option->name;
+ /* 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;
+ else {
+ int count = 1;
+ if (option->flag & VALUE_IS_LIST) {
+ /* count how many args, this is the -argument itself + following the non'-' args */
+ while(count + index < *pArgc && argv[count + index][0] != _T_ECLIPSE('-'))
+ count++;
+
+ /* allocate memory for a _TCHAR* list and initialize it with NULLs*/
+ *((void**) option->value) = malloc(count * sizeof(_TCHAR *));
+ memset(*((void **) option->value), 0, count * sizeof(_TCHAR *));
+
+ if (option->remove != 0)
+ option->remove = count;
+ }
+
+ for (i = 0; i < count; i++) {
+ if ((index + i + 1) < *pArgc) {
+ _TCHAR * next = argv[index + i + 1];
+ if (option->flag & ADJUST_PATH)
+ next = checkPath(next, getProgramDir(), 0);
+ if (next[0] != _T_ECLIPSE('-')) {
+ if (option->flag & VALUE_IS_LIST)
+ (*((_TCHAR***) option->value))[i] = next;
+ else
+ *((_TCHAR**) option->value) = next;
+ } else if (option->flag & OPTIONAL_VALUE){
+ /* value was optional, and the next arg starts with '-' */
+ optional = 1;
+ }
+ }
+ }
+ }
+ }
- /* If the option is recognized by the launcher */
- if (option != NULL)
- {
- int optional = 0;
- /* 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;
- else if((index + 1) < *pArgc) {
- _TCHAR * next = argv[index + 1];
- if(!((option->flag & OPTIONAL_VALUE) && next[0] == _T_ECLIPSE('-'))) {
- *((_TCHAR**)option->value) = next;
- } else {
- /* value was optional, and the next arg starts with '-' */
- optional = 1;
- }
- }
- }
-
- /* If the option requires a flag to be set, set it. */
- remArgs = option->remove - optional;
- }
+ /* If the option requires a flag to be set, set it. */
+ remArgs = option->remove - optional;
+ }
/* 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;
- }
- }
+ if (remArgs > 0) {
+ for (i = (index + remArgs); i <= *pArgc; i++) {
+ argv[i - remArgs] = argv[i];
+ }
+ index--;
+ *pArgc -= remArgs;
+ }
+ }
}
/*
@@ -1519,11 +1568,11 @@ static int processEEProps(_TCHAR* eeFile)
else {
c1 = malloc( (_tcslen(argv[index]) - _tcslen(option->name) + 1) *sizeof(_TCHAR));
_tcscpy(c1, argv[index] + _tcslen(option->name));
- if (option->flag & EE_ADJUST_PATH && option->flag & EE_PATH_LIST) {
+ if (option->flag & ADJUST_PATH && option->flag & VALUE_IS_LIST) {
c2 = checkPathList(c1, eeDir, 1);
free(c1);
c1 = c2;
- } else if (option->flag & EE_ADJUST_PATH) {
+ } else if (option->flag & ADJUST_PATH) {
c2 = checkPath(c1, eeDir, 1);
if (c2 != c1) {
free(c1);
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseOS.h b/bundles/org.eclipse.equinox.executable/library/eclipseOS.h
index eeff21d05..859bad440 100644
--- a/bundles/org.eclipse.equinox.executable/library/eclipseOS.h
+++ b/bundles/org.eclipse.equinox.executable/library/eclipseOS.h
@@ -115,7 +115,7 @@ extern int isSunVM( _TCHAR * javaVM, _TCHAR * jniLib );
/* an array of paths that will need to be on the search path to load the vm shared library */
extern _TCHAR ** getVMLibrarySearchPath(_TCHAR * vmLibrary);
-extern int reuseWorkbench(_TCHAR* filePath, int timeout);
+extern int reuseWorkbench(_TCHAR** filePath, int timeout);
#endif /* ECLIPSE_OS_H */
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c
index 8845dbc69..9ed7b68b2 100644
--- a/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c
+++ b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.c
@@ -133,20 +133,27 @@ _TCHAR * checkPathList( _TCHAR* pathList, _TCHAR* programDir, int reverseOrder)
return result;
}
-_TCHAR * concatStrings(_TCHAR** strs) {
+_TCHAR * concatStrings(_TCHAR**strs) {
+ return concatPaths(strs, 0);
+}
+
+_TCHAR * concatPaths(_TCHAR** strs, _TCHAR separator) {
+ _TCHAR separatorString[] = { separator, 0 };
_TCHAR * result;
int i = -1;
size_t length = 0;
/* first count how large a buffer we need */
- while( strs[++i] != NULL) {
- length += _tcslen(strs[i]);
+ while (strs[++i] != NULL) {
+ length += _tcslen(strs[i]) + (separator != 0 ? 1 : 0);
}
-
+
result = malloc((length + 1) * sizeof(_TCHAR));
result[0] = 0;
i = -1;
- while(strs[++i] != NULL) {
+ while (strs[++i] != NULL) {
result = _tcscat(result, strs[i]);
+ if (separator != 0)
+ result = _tcscat(result, separatorString);
}
return result;
}
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h
index 78ae23f95..970aba374 100644
--- a/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h
+++ b/bundles/org.eclipse.equinox.executable/library/eclipseUtil.h
@@ -37,6 +37,9 @@ extern _TCHAR * checkPathList( _TCHAR* pathList, _TCHAR* programDir, int reverse
/* take a NULL terminated array of strings and concatenate them together into one string */
extern _TCHAR * concatStrings(_TCHAR** strs);
+/* take a NULL terminated array of strings and concatenate them together using the give pathSeparator */
+extern _TCHAR* concatPaths(_TCHAR** paths, _TCHAR pathSeparator);
+
/* check that the buffer contains all the given paths */
extern int containsPaths(_TCHAR * str, _TCHAR** paths);
diff --git a/bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtk.c b/bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtk.c
index aa6db1db2..98605dc5c 100644
--- a/bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtk.c
+++ b/bundles/org.eclipse.equinox.executable/library/gtk/eclipseGtk.c
@@ -51,7 +51,7 @@ static GtkWidget* image = 0;
static sem_t* mutex;
static Atom appWindowAtom, launcherWindowAtom;
-static char* openFilePath = NULL; /* the file we want to open */
+static _TCHAR** openFilePath = NULL; /* the files we want to open */
static int openFileTimeout = 60; /* number of seconds to wait before timeout */
static struct sigaction quitAction;
@@ -129,7 +129,7 @@ static int setAppWindowPropertyFn() {
Window appWindow;
GdkWindow *propWindow;
GdkAtom propAtom;
- char *propVal;
+ _TCHAR *propVal;
//Look for the SWT window. If it's there, set a property on it.
appWindow = gtk.XGetSelectionOwner(gtk_GDK_DISPLAY, appWindowAtom);
@@ -137,15 +137,14 @@ static int setAppWindowPropertyFn() {
if (appWindow) {
propAtom = gtk.gdk_atom_intern("org.eclipse.swt.filePath.message", FALSE);
//append a colon delimiter in case more than one file gets appended to the app windows property.
- propVal = malloc((_tcslen(openFilePath) + 2) * sizeof(char));
- _stprintf(propVal, _T_ECLIPSE("%s%s"), openFilePath, ":");
-
+ propVal = concatPaths(openFilePath, _T_ECLIPSE(':'));
propWindow = gtk.gdk_window_foreign_new(appWindow);
if (propWindow != NULL) {
gtk.gdk_property_change(propWindow, propAtom, propAtom, 8, GDK_PROP_MODE_APPEND, (guchar *) propVal, _tcslen(propVal));
free(propVal);
return 1;
} //else the window got destroyed between XGetSelectionOwner and here (?)
+ free(propVal);
}
return 0;
}
@@ -185,7 +184,7 @@ int createLauncherWindow() {
return 1;
}
-int reuseWorkbench(char* filePath, int timeout) {
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
char *appName, *launcherName;
int result = 0;
diff --git a/bundles/org.eclipse.equinox.executable/library/make_version.mak b/bundles/org.eclipse.equinox.executable/library/make_version.mak
index 9bb6eac17..2601cc61f 100644
--- a/bundles/org.eclipse.equinox.executable/library/make_version.mak
+++ b/bundles/org.eclipse.equinox.executable/library/make_version.mak
@@ -10,5 +10,5 @@
#*******************************************************************************
maj_ver=1
-min_ver=305
+min_ver=306
LIB_VERSION = $(maj_ver)$(min_ver)
diff --git a/bundles/org.eclipse.equinox.executable/library/motif/eclipseMotif.c b/bundles/org.eclipse.equinox.executable/library/motif/eclipseMotif.c
index a01a4bc06..4d5f8f197 100644
--- a/bundles/org.eclipse.equinox.executable/library/motif/eclipseMotif.c
+++ b/bundles/org.eclipse.equinox.executable/library/motif/eclipseMotif.c
@@ -330,7 +330,7 @@ JavaResults* launchJavaVM( char* args[] )
return jvmResults;
}
-int reuseWorkbench(_TCHAR* filePath, int timeout) {
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
/* not yet implemented on motif */
return -1;
}
diff --git a/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c b/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c
index 3500e619a..c849c93f1 100644
--- a/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c
+++ b/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c
@@ -42,7 +42,7 @@ static UINT findWindowTimeout = 1000;
static UINT_PTR findWindowTimerId = 97;
static UINT timerCount = 0;
static UINT openFileTimeout = 60;
-static _TCHAR* openFilePath;
+static _TCHAR** openFilePath;
/* Define the window system arguments for the Java VM. */
static _TCHAR* argVM[] = { NULL };
@@ -82,20 +82,32 @@ typedef struct {
static void sendOpenFileMessage(HWND window) {
_TCHAR* id;
UINT msg;
- int size = (_tcslen(openFilePath) + 1) * sizeof(_TCHAR);
+ int index = 0;
+ int size = 0;
DWORD wParam;
#ifdef WIN64
DWORDLONG lParam;
#else
DWORD lParam;
#endif
- createSharedData(&id, size);
- setSharedData(id, openFilePath);
- msg = RegisterWindowMessage(_T("SWT_OPENDOC"));
+
+ /* what's the longest path? */
+ while (openFilePath[index] != NULL) {
+ int length = _tcslen(openFilePath[index++]);
+ if (size <= length)
+ size = length + 1;
+ }
+
+ createSharedData(&id, size * sizeof(_TCHAR));
_stscanf(id, _T_ECLIPSE("%lx_%lx"), &wParam, &lParam);
-
- /* SendMessage does not return until the message has been processed */
- SendMessage(window, msg, wParam, lParam);
+ msg = RegisterWindowMessage(_T("SWT_OPENDOC"));
+
+ index = 0;
+ for(index = 0; openFilePath[index] != NULL; index++) {
+ /* SendMessage does not return until the message has been processed */
+ setSharedData(id, openFilePath[index]);
+ SendMessage(window, msg, wParam, lParam);
+ }
destroySharedData(id);
}
@@ -131,7 +143,7 @@ static void CALLBACK findWindowProc(HWND hwnd, UINT message, UINT idTimer, DWORD
}
/* return > 0 if we successfully send a message to another eclipse instance */
-int reuseWorkbench(_TCHAR* filePath, int timeout) {
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
_TCHAR* mutexPrefix = _T("SWT_Mutex_");
_TCHAR* mutexName, *name;
DWORD lock;
diff --git a/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak b/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak
index 449b33f67..9feb80eab 100644
--- a/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak
+++ b/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak
@@ -37,7 +37,7 @@ OSTYPE ?= $(shell if uname -s | grep -iq cygwin ; then echo cygwin; else echo li
ifeq ($(OSTYPE),cygwin)
CCVER = i686
-CC = i686-pc-cygwin-gcc
+CC = i686-pc-cygwin-gcc-3
RC = windres
else
CCVER = i586
diff --git a/bundles/org.eclipse.equinox.executable/library/wpf/eclipseWpf.cpp b/bundles/org.eclipse.equinox.executable/library/wpf/eclipseWpf.cpp
index f4878e35c..18b6c5138 100644
--- a/bundles/org.eclipse.equinox.executable/library/wpf/eclipseWpf.cpp
+++ b/bundles/org.eclipse.equinox.executable/library/wpf/eclipseWpf.cpp
@@ -554,7 +554,7 @@ int isSunVM( _TCHAR * javaVM, _TCHAR * jniLib ) {
return result;
}
-int reuseWorkbench(_TCHAR* filePath, int timeout) {
+int reuseWorkbench(_TCHAR** filePath, int timeout) {
/* not implemented for WPF */
return -1;
}

Back to the top