Commit 900dd840 by Nicolas Roche Committed by Pierre-Marie de Rodat

[Ada] Remove dependency on Win32 GDI (Graphical Interface)

CommandLineToArgvW drags a dependency on SHELL32.DLL and thus GDI32.DLL.
By loading GDI32.DLL some default GDI objects are allocated. On some
Windows versions this cause the use of a lock on the graphical interface
during process termination. This can impact parallelism significantly as
termination of processes is serialized.

2019-07-08  Nicolas Roche  <roche@adacore.com>

gcc/ada/

	* rtinit.c (__gnat_runtime_initialize): Remove dependency on
	CommandLineToArgvW.

From-SVN: r273214
parent eaec429d
2019-07-08 Nicolas Roche <roche@adacore.com>
* rtinit.c (__gnat_runtime_initialize): Remove dependency on
CommandLineToArgvW.
2019-07-08 Doug Rupp <rupp@adacore.com> 2019-07-08 Doug Rupp <rupp@adacore.com>
* Makefile.rtl: Handle vxworks7r2 in x86_64 and x86 vxworks7. * Makefile.rtl: Handle vxworks7r2 in x86_64 and x86 vxworks7.
......
...@@ -62,7 +62,7 @@ extern "C" { ...@@ -62,7 +62,7 @@ extern "C" {
/* __gnat_runtime_initialize (NT-mingw32 Version) */ /* __gnat_runtime_initialize (NT-mingw32 Version) */
/**************************************************/ /**************************************************/
extern void __gnat_install_handler(void); extern void __gnat_install_handler (void);
int __gnat_wide_text_translation_required = 0; int __gnat_wide_text_translation_required = 0;
/* wide text translation, 0=none, 1=activated */ /* wide text translation, 0=none, 1=activated */
...@@ -89,6 +89,189 @@ extern HANDLE ProcListEvt; ...@@ -89,6 +89,189 @@ extern HANDLE ProcListEvt;
int __gnat_do_argv_expansion = 1; int __gnat_do_argv_expansion = 1;
#pragma weak __gnat_do_argv_expansion #pragma weak __gnat_do_argv_expansion
/* Assuming we are pointing to the beginning of a quoted part of an
argument, skip until the end of the quoted part. */
static void skip_quoted_string (const WCHAR **current_in,
WCHAR **current_out)
{
/* Number of backslashes buffered. */
int qbs_count = 0;
/* Pointer to current input character. */
const WCHAR *ci = *current_in;
/* Pointer to next output character. */
WCHAR *co = *current_out;
/* Skip initial quote. */
ci++;
while (*ci)
{
if (*ci == '\\')
{
/* Buffer incoming backslashes. */
qbs_count++;
}
else if (*ci == '"')
{
/* Append qbs_count / 2 backslahes. */
for (int i=0; i<qbs_count / 2; i++)
{
*co = '\\';
co++;
}
if ((qbs_count & 1) == 0)
{
/* 2n backslashes means that the quotation mark is the end of
the quoted portion. */
qbs_count = 0;
break;
}
else
{
/* Otherwise this is a double quote literal. */
qbs_count = 0;
*co = '"'; co++;
}
}
else
{
/* If the character is not a double quote we should append
qbs_count backslashes. */
for (int i=0; i<qbs_count; i++)
{
*co = '\\';
co++;
}
*co = *ci; co++;
qbs_count = 0;
}
ci++;
}
*current_in = ci;
*current_out = co;
}
/* Assuming that this is the beginning of an argument. Skip characters
until we reach the character right after the last argument character. */
static void skip_argument (const WCHAR **current_in,
WCHAR **current_out)
{
/* Number of backslashes buffered. */
int bs_count = 0;
/* Pointer to current input character. */
const WCHAR *ci = *current_in;
/* Pointer to next output character. */
WCHAR *co = *current_out;
while (*ci && ! (*ci == ' ' || *ci == '\t'))
{
if (*ci == '\\')
{
/* Buffer incoming backslashes. */
bs_count++;
}
else if (*ci == '"')
{
/* Append qbs_count / 2 backslahes. */
for (int i=0; i< bs_count / 2; i++)
{
*co = '\\'; co++;
}
if ((bs_count & 1) == 0)
{
/* 2n backslashes followed by a quotation mark means that
this is a start of a quoted string. */
skip_quoted_string (&ci, &co);
}
else
{
/* Otherwise this is quotation mark literal. */
*co = '"';
co++;
}
bs_count = 0;
}
else
{
/* This is a regular character. */
/* Backslashes are interpreted literally. */
for (int i=0; i<bs_count; i++)
{
*co = '\\';
co++;
}
bs_count = 0;
*co = *ci; co++;
}
ci++;
}
for (int i=0; i<bs_count; i++)
{
*co = '\\';
co++;
}
/* End the argument with a null character. */
*co = '\0';
co++;
*current_in = ci;
*current_out = co;
}
void __gnat_get_argw (const WCHAR *command_line, WCHAR ***argv, int *argc)
{
WCHAR *inline_argv;
WCHAR *co;
int arg_count = 1;
const WCHAR *ci;
inline_argv =
(WCHAR *) xmalloc ((wcslen (command_line) + 1) * sizeof (WCHAR));
co = inline_argv;
/* Start iteration on command line characters. */
ci = command_line;
/* Skip command name. Note that if the command line starts with whitechars
then the command name will be the empty string. */
skip_argument (&ci, &co);
/* Count remaining arguments. */
while (*ci)
{
/* skip whitechar */
while (*ci && (*ci == ' ' || *ci == '\t')) { ci++; }
if (*ci)
{
skip_argument (&ci, &co);
arg_count++;
}
else
break;
}
/* Allocate table with pointer to each arguments */
argv[0] = (WCHAR **) xmalloc (arg_count * sizeof (WCHAR *));
for (int idx = 0; idx < arg_count; idx++)
{
argv[0][idx] = inline_argv;
while (*inline_argv)
{
inline_argv++;
}
inline_argv++;
}
*argc = arg_count;
}
static void static void
append_arg (int *index, LPWSTR dir, LPWSTR value, append_arg (int *index, LPWSTR dir, LPWSTR value,
char ***argv, int *last, int quoted) char ***argv, int *last, int quoted)
...@@ -102,14 +285,14 @@ append_arg (int *index, LPWSTR dir, LPWSTR value, ...@@ -102,14 +285,14 @@ append_arg (int *index, LPWSTR dir, LPWSTR value,
{ {
/* no dir prefix */ /* no dir prefix */
dirlen = 0; dirlen = 0;
fullvalue = (LPWSTR) xmalloc ((vallen + 1) * sizeof(TCHAR)); fullvalue = (LPWSTR) xmalloc ((vallen + 1) * sizeof (TCHAR));
} }
else else
{ {
/* Add dir first */ /* Add dir first */
dirlen = _tcslen (dir); dirlen = _tcslen (dir);
fullvalue = (LPWSTR) xmalloc ((dirlen + vallen + 1) * sizeof(TCHAR)); fullvalue = (LPWSTR) xmalloc ((dirlen + vallen + 1) * sizeof (TCHAR));
_tcscpy (fullvalue, dir); _tcscpy (fullvalue, dir);
} }
...@@ -118,7 +301,7 @@ append_arg (int *index, LPWSTR dir, LPWSTR value, ...@@ -118,7 +301,7 @@ append_arg (int *index, LPWSTR dir, LPWSTR value,
if (quoted) if (quoted)
{ {
_tcsncpy (fullvalue + dirlen, value + 1, vallen - 1); _tcsncpy (fullvalue + dirlen, value + 1, vallen - 1);
fullvalue [dirlen + vallen - sizeof(TCHAR)] = _T('\0'); fullvalue [dirlen + vallen - sizeof (TCHAR)] = _T ('\0');
} }
else else
_tcscpy (fullvalue + dirlen, value); _tcscpy (fullvalue + dirlen, value);
...@@ -130,7 +313,7 @@ append_arg (int *index, LPWSTR dir, LPWSTR value, ...@@ -130,7 +313,7 @@ append_arg (int *index, LPWSTR dir, LPWSTR value,
} }
size = WS2SC (NULL, fullvalue, 0); size = WS2SC (NULL, fullvalue, 0);
(*argv)[*index] = (char *) xmalloc (size + sizeof(TCHAR)); (*argv)[*index] = (char *) xmalloc (size + sizeof (TCHAR));
WS2SC ((*argv)[*index], fullvalue, size); WS2SC ((*argv)[*index], fullvalue, size);
free (fullvalue); free (fullvalue);
...@@ -140,7 +323,7 @@ append_arg (int *index, LPWSTR dir, LPWSTR value, ...@@ -140,7 +323,7 @@ append_arg (int *index, LPWSTR dir, LPWSTR value,
#endif #endif
void void
__gnat_runtime_initialize(int install_handler) __gnat_runtime_initialize (int install_handler)
{ {
/* increment the reference counter */ /* increment the reference counter */
...@@ -223,7 +406,7 @@ __gnat_runtime_initialize(int install_handler) ...@@ -223,7 +406,7 @@ __gnat_runtime_initialize(int install_handler)
TCHAR result [MAX_PATH]; TCHAR result [MAX_PATH];
int quoted; int quoted;
wargv = CommandLineToArgvW (GetCommandLineW(), &wargc); __gnat_get_argw (GetCommandLineW (), &wargv, &wargc);
if (wargv != NULL) if (wargv != NULL)
{ {
...@@ -297,7 +480,8 @@ __gnat_runtime_initialize(int install_handler) ...@@ -297,7 +480,8 @@ __gnat_runtime_initialize(int install_handler)
} }
} }
LocalFree (wargv); free (wargv[0]);
free (wargv);
gnat_argc = argc_expanded; gnat_argc = argc_expanded;
gnat_argv = (char **) xrealloc gnat_argv = (char **) xrealloc
(gnat_argv, argc_expanded * sizeof (char *)); (gnat_argv, argc_expanded * sizeof (char *));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment