blob: 8332e8545312f70041329ae65ebaf57815a118dd [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <windows.h>
#include "jni.h"
#include "hyport.h"
//#include "libhlp.h"
#ifdef HY_NO_THR
#include "main_hlp.h"
#endif /* HY_NO_THR */
/* external prototypes */
UDATA VMCALL gpProtectedMain PROTOTYPE ((void *arg));
#ifdef HY_NO_THR
extern int main_addVMDirToPath PROTOTYPE((int argc, char **argv, char **envp));
#endif /* HY_NO_THR */
char **getArgvCmdLine
#ifndef HY_NO_THR
PROTOTYPE ((HyPortLibrary * portLibrary, LPTSTR buffer, int *finalArgc));
#else /* HY_NO_THR */
PROTOTYPE ((LPTSTR buffer, int *finalArgc));
#endif /* HY_NO_THR */
int WINAPI WinMain
PROTOTYPE ((HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nShowCmd));
#ifndef HY_NO_THR
void freeArgvCmdLine PROTOTYPE ((HyPortLibrary * portLibrary, char **argv));
#else /* HY_NO_THR */
void freeArgvCmdLine PROTOTYPE ((char **argv));
#endif /* HY_NO_THR */
struct haCmdlineOptions
{
int argc;
char **argv;
char **envp;
HyPortLibrary *portLibrary;
};
#ifdef HY_NO_THR
typedef I_32 (PVMCALL hyport_init_library_type) (struct HyPortLibrary *portLibrary,
struct HyPortLibraryVersion *version,
UDATA size);
#endif /* HY_NO_THR */
int WINAPI
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nShowCmd)
{
int argc = 0, rc;
HyPortLibrary hyportLibrary;
HyPortLibraryVersion portLibraryVersion;
struct haCmdlineOptions options;
char **argv;
#ifdef HY_NO_THR
UDATA portLibDescriptor;
hyport_init_library_type port_init_library_func;
argv = getArgvCmdLine (GetCommandLine (), &argc);
if (argv == NULL) {
rc = -1;
goto cleanup;
}
/* determine which VM directory to use and add it to the path */
rc = main_addVMDirToPath(argc, argv, NULL);
if ( rc != 0 ) {
goto cleanup;
}
if ( 0 != main_open_port_library(&portLibDescriptor) ) {
fprintf( stderr, "failed to open hyprt library.\n" );
rc = -1;
goto cleanup;
}
if ( 0 != main_lookup_name( portLibDescriptor, "hyport_init_library", (UDATA *)&port_init_library_func) ) {
fprintf( stderr, "failed to find hyport_init_library function in hyprt library\n" );
rc = -1;
goto cleanup;
}
#endif /* HY_NO_THR */
/* Use portlibrary version which we compiled against, and have allocated space
* for on the stack. This version may be different from the one in the linked DLL.
*/
HYPORT_SET_VERSION (&portLibraryVersion, HYPORT_CAPABILITY_MASK);
#ifndef HY_NO_THR
rc =
hyport_init_library (&hyportLibrary, &portLibraryVersion,
sizeof (HyPortLibrary));
if (0 != rc)
{
return -1;
}
argv = getArgvCmdLine (&hyportLibrary, GetCommandLine (), &argc);
if (argv)
{
options.argc = argc;
options.argv = argv;
options.envp = NULL;
options.portLibrary = &hyportLibrary;
rc =
hyportLibrary.gp_protect (&hyportLibrary, gpProtectedMain, &options);
freeArgvCmdLine (&hyportLibrary, argv);
hyportLibrary.port_shutdown_library (&hyportLibrary);
return rc;
}
else
{
return -1;
}
#else /* HY_NO_THR */
rc = port_init_library_func (&hyportLibrary, &portLibraryVersion, sizeof (HyPortLibrary));
if (0 != rc) {
goto cleanup;
}
options.argc = argc;
options.argv = argv;
options.envp = NULL;
options.portLibrary = &hyportLibrary;
rc = hyportLibrary.gp_protect (&hyportLibrary, gpProtectedMain, &options);
hyportLibrary.port_shutdown_library (&hyportLibrary);
cleanup:
if (argv) {
freeArgvCmdLine(argv);
}
return rc;
#endif /* HY_NO_THR */
}
/*
* Takes the command line (1 string) and breaks it into an
* argc, argv[] style list.
* Understands LFNs and strips quotes off the exe name.
* also converts the string to ASCII.
*/
char **
#ifndef HY_NO_THR
getArgvCmdLine (HyPortLibrary * portLibrary, LPTSTR buffer, int *finalArgc)
#else /* HY_NO_THR */
getArgvCmdLine (LPTSTR buffer, int *finalArgc)
#endif /* HY_NO_THR */
{
#define QUOTE_CHAR 34
int argc = 0, currentArg, i, asciiLen;
char *asciiCmdLine;
char **argv;
#ifndef HY_NO_THR
PORT_ACCESS_FROM_PORT (portLibrary);
#endif /* ! HY_NO_THR */
asciiCmdLine = buffer;
/* determine an upper bound on the # of args by counting spaces and tabs */
argc = 2;
asciiLen = strlen (buffer);
for (i = 0; i < asciiLen; i++)
{
if (asciiCmdLine[i] == ' ' || asciiCmdLine[i] == '\t')
argc++;
}
/* allocate the buffer for the args */
#ifndef HY_NO_THR
argv = hymem_allocate_memory (argc * sizeof (char *));
#else /* HY_NO_THR */
argv = main_mem_allocate_memory (argc * sizeof (char *));
#endif /* HY_NO_THR */
if (!argv)
return NULL;
/* now fill in the argv array */
currentArg = 0;
if (QUOTE_CHAR == *asciiCmdLine)
{ /* we have a quoted name. */
argv[currentArg++] = ++asciiCmdLine; /* move past the quote */
while (QUOTE_CHAR != *asciiCmdLine)
asciiCmdLine++;
if (*asciiCmdLine)
*asciiCmdLine++ = '\0'; /* past close quote, slam the close quote and advance */
}
/* Skip whitespace */
while (*asciiCmdLine == ' ' || *asciiCmdLine == '\t'
|| *asciiCmdLine == '\r')
asciiCmdLine++;
/* Split up args */
while (*asciiCmdLine)
{
if (QUOTE_CHAR == *asciiCmdLine)
{
/* Parse a quoted arg */
argv[currentArg++] = ++asciiCmdLine;
while (*asciiCmdLine && *asciiCmdLine != QUOTE_CHAR)
{
asciiCmdLine++;
}
}
else
{
/* Whitespace separated arg */
argv[currentArg++] = asciiCmdLine;
while (*asciiCmdLine && *asciiCmdLine != ' '
&& *asciiCmdLine != '\t' && *asciiCmdLine != '\r')
{
asciiCmdLine++;
}
}
/* Null terminate */
if (*asciiCmdLine)
*asciiCmdLine++ = '\0';
/* Skip whitespace */
while (*asciiCmdLine && *asciiCmdLine == ' ' || *asciiCmdLine == '\t'
|| *asciiCmdLine == '\r')
asciiCmdLine++;
}
argv[currentArg] = NULL;
*finalArgc = currentArg;
return argv;
}
#undef QUOTE_CHAR
void
#ifndef HY_NO_THR
freeArgvCmdLine (HyPortLibrary * portLibrary, char **argv)
#else /* HY_NO_THR */
freeArgvCmdLine (char **argv)
#endif /* HY_NO_THR */
{
#ifndef HY_NO_THR
PORT_ACCESS_FROM_PORT (portLibrary);
hymem_free_memory (argv);
#else /* HY_NO_THR */
main_mem_free_memory (argv);
#endif /* HY_NO_THR */
}