adaint.c (ProcListEvt): Set to NULL.
2015-01-06 Pascal Obry <obry@adacore.com> * adaint.c (ProcListEvt): Set to NULL. * rtinit.c: New file. (__gnat_rt_init_count): New reference counter set to 0. (__gnat_runtime_initialize): Move code here from __gnat_initialize when this code is actually needed for the runtime initialization. This routine returns immediately if the initialization has already been done. * final.c: Revert previous change. * rtfinal.c: New file. (__gnat_runtime_finalize)[Win32]: Add finalization of the critical section and event. The default version of this routine is empty (except for the reference counting code). This routine returns immediately if some others libraries are referencing the runtime. * bindgen.adb (Gen_Adainit): Generate call to Runtime_Initialize remove circuitry to initialize the signal handler as this is now done by the runtime initialization routine. (Gen_Adafinal): Generate call to Runtime_Finalize. * gnat_ugn.texi: Update documentation about concurrency and initialization/finalization of the run-time. * gcc-interface/Makefile.in, gcc-interface/Make-lang.in: Add references to rtfinal.o and rtinit.o From-SVN: r219238
This commit is contained in:
parent
7665df2248
commit
07e188be3b
@ -1,3 +1,26 @@
|
||||
2015-01-06 Pascal Obry <obry@adacore.com>
|
||||
|
||||
* adaint.c (ProcListEvt): Set to NULL.
|
||||
* rtinit.c: New file.
|
||||
(__gnat_rt_init_count): New reference counter set to 0.
|
||||
(__gnat_runtime_initialize): Move code here from __gnat_initialize when
|
||||
this code is actually needed for the runtime initialization. This
|
||||
routine returns immediately if the initialization has already been done.
|
||||
* final.c: Revert previous change.
|
||||
* rtfinal.c: New file.
|
||||
(__gnat_runtime_finalize)[Win32]: Add finalization of the critical
|
||||
section and event. The default version of this routine is empty (except
|
||||
for the reference counting code). This routine returns immediately if
|
||||
some others libraries are referencing the runtime.
|
||||
* bindgen.adb (Gen_Adainit): Generate call to Runtime_Initialize
|
||||
remove circuitry to initialize the signal handler as this is
|
||||
now done by the runtime initialization routine.
|
||||
(Gen_Adafinal): Generate call to Runtime_Finalize.
|
||||
* gnat_ugn.texi: Update documentation about concurrency and
|
||||
initialization/finalization of the run-time.
|
||||
* gcc-interface/Makefile.in, gcc-interface/Make-lang.in: Add
|
||||
references to rtfinal.o and rtinit.o
|
||||
|
||||
2015-01-06 Robert Dewar <dewar@adacore.com>
|
||||
|
||||
* exp_attr.adb (Expand_N_Attribute_Reference): Add dummy entry
|
||||
|
@ -2318,7 +2318,7 @@ static void SignalListChanged (void) {}
|
||||
#else
|
||||
|
||||
CRITICAL_SECTION ProcListCS;
|
||||
HANDLE ProcListEvt;
|
||||
HANDLE ProcListEvt = NULL;
|
||||
|
||||
static void EnterCS (void)
|
||||
{
|
||||
|
@ -390,6 +390,11 @@ package body Bindgen is
|
||||
Write_Statement_Buffer;
|
||||
end if;
|
||||
|
||||
WBI ("");
|
||||
WBI (" procedure Runtime_Finalize;");
|
||||
WBI (" pragma Import (C, Runtime_Finalize, " &
|
||||
"""__gnat_runtime_finalize"");");
|
||||
WBI ("");
|
||||
WBI (" begin");
|
||||
|
||||
if not CodePeer_Mode then
|
||||
@ -399,6 +404,8 @@ package body Bindgen is
|
||||
WBI (" Is_Elaborated := False;");
|
||||
end if;
|
||||
|
||||
WBI (" Runtime_Finalize;");
|
||||
|
||||
-- On non-virtual machine targets, finalization is done differently
|
||||
-- depending on whether this is the main program or a library.
|
||||
|
||||
@ -599,13 +606,9 @@ package body Bindgen is
|
||||
-- installation, and indication of if it's been called previously.
|
||||
|
||||
WBI ("");
|
||||
WBI (" procedure Install_Handler;");
|
||||
WBI (" pragma Import (C, Install_Handler, " &
|
||||
"""__gnat_install_handler"");");
|
||||
WBI ("");
|
||||
WBI (" Handler_Installed : Integer;");
|
||||
WBI (" pragma Import (C, Handler_Installed, " &
|
||||
"""__gnat_handler_installed"");");
|
||||
WBI (" procedure Runtime_Initialize;");
|
||||
WBI (" pragma Import (C, Runtime_Initialize, " &
|
||||
"""__gnat_runtime_initialize"");");
|
||||
|
||||
-- Import handlers attach procedure for sequential elaboration policy
|
||||
|
||||
@ -835,13 +838,9 @@ package body Bindgen is
|
||||
-- In .NET, when binding with -z, we don't install the signal handler
|
||||
-- to let the caller handle the last exception handler.
|
||||
|
||||
if VM_Target /= CLI_Target
|
||||
or else Bind_Main_Program
|
||||
then
|
||||
if Bind_Main_Program then
|
||||
WBI ("");
|
||||
WBI (" if Handler_Installed = 0 then");
|
||||
WBI (" Install_Handler;");
|
||||
WBI (" end if;");
|
||||
WBI (" Runtime_Initialize;");
|
||||
end if;
|
||||
end if;
|
||||
|
||||
|
@ -40,28 +40,10 @@ extern void __gnat_finalize (void);
|
||||
at all, the intention is that this be replaced by system specific code
|
||||
where finalization is required. */
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
#include "mingw32.h"
|
||||
#include <windows.h>
|
||||
|
||||
extern CRITICAL_SECTION ProcListCS;
|
||||
extern HANDLE ProcListEvt;
|
||||
|
||||
void
|
||||
__gnat_finalize (void)
|
||||
{
|
||||
/* delete critical section and event handle used for the
|
||||
processes chain list */
|
||||
DeleteCriticalSection(&ProcListCS);
|
||||
CloseHandle (ProcListEvt);
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
__gnat_finalize (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -223,8 +223,8 @@ GCC_LLINK=$(LLINKER) $(GCC_LINKERFLAGS) $(LDFLAGS)
|
||||
# Object files for gnat1 from C sources.
|
||||
GNAT1_C_OBJS = ada/adadecode.o ada/adaint.o ada/argv.o ada/cio.o \
|
||||
ada/cstreams.o ada/env.o ada/init.o ada/initialize.o ada/raise.o \
|
||||
ada/seh_init.o ada/targext.o ada/cuintp.o ada/decl.o \
|
||||
ada/misc.o ada/utils.o ada/utils2.o ada/trans.o ada/targtyps.o
|
||||
ada/seh_init.o ada/targext.o ada/cuintp.o ada/decl.o ada/rtfinal.o \
|
||||
ada/rtinit.o ada/misc.o ada/utils.o ada/utils2.o ada/trans.o ada/targtyps.o
|
||||
|
||||
# Object files from Ada sources that are used by gnat1
|
||||
GNAT_ADA_OBJS = \
|
||||
@ -513,6 +513,8 @@ GNATBIND_OBJS = \
|
||||
ada/raise.o \
|
||||
ada/restrict.o \
|
||||
ada/rident.o \
|
||||
ada/rtfinal.o \
|
||||
ada/rtinit.o \
|
||||
ada/s-addope.o \
|
||||
ada/s-assert.o \
|
||||
ada/s-carun8.o \
|
||||
|
@ -2400,7 +2400,7 @@ endif
|
||||
# thread.c is special as put into GNATRTL_TASKING_OBJS by Makefile.rtl
|
||||
LIBGNAT_OBJS = adadecode.o adaint.o argv.o aux-io.o \
|
||||
cal.o cio.o cstreams.o ctrl_c.o \
|
||||
env.o errno.o exit.o expect.o final.o \
|
||||
env.o errno.o exit.o expect.o final.o rtfinal.o rtinit.o \
|
||||
init.o initialize.o locales.o mkdir.o \
|
||||
raise.o seh_init.o socket.o sysdep.o \
|
||||
targext.o terminals.o tracebak.o \
|
||||
@ -3046,6 +3046,8 @@ errno.o : errno.c
|
||||
exit.o : adaint.h exit.c
|
||||
expect.o : expect.c
|
||||
final.o : final.c
|
||||
rtfinal.o : rtfinal.c
|
||||
rtinit.o : rtinit.c
|
||||
locales.o : locales.c
|
||||
mkdir.o : mkdir.c
|
||||
socket.o : socket.c gsocket.h
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -62,230 +62,15 @@ extern "C" {
|
||||
/* __gnat_initialize (NT-mingw32 Version) */
|
||||
/******************************************/
|
||||
|
||||
int __gnat_wide_text_translation_required = 0;
|
||||
/* wide text translation, 0=none, 1=activated */
|
||||
extern void __gnat_install_handler(void);
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
#include "mingw32.h"
|
||||
#include <windows.h>
|
||||
|
||||
extern void __gnat_init_float (void);
|
||||
extern void __gnat_install_SEH_handler (void *);
|
||||
|
||||
extern int gnat_argc;
|
||||
extern char **gnat_argv;
|
||||
extern CRITICAL_SECTION ProcListCS;
|
||||
extern HANDLE ProcListEvt;
|
||||
|
||||
#ifdef GNAT_UNICODE_SUPPORT
|
||||
|
||||
#define EXPAND_ARGV_RATE 128
|
||||
|
||||
static void
|
||||
append_arg (int *index, LPWSTR dir, LPWSTR value,
|
||||
char ***argv, int *last, int quoted)
|
||||
{
|
||||
int size;
|
||||
LPWSTR fullvalue;
|
||||
int vallen = _tcslen (value);
|
||||
int dirlen;
|
||||
|
||||
if (dir == NULL)
|
||||
{
|
||||
/* no dir prefix */
|
||||
dirlen = 0;
|
||||
fullvalue = (LPWSTR) xmalloc ((vallen + 1) * sizeof(TCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add dir first */
|
||||
dirlen = _tcslen (dir);
|
||||
|
||||
fullvalue = (LPWSTR) xmalloc ((dirlen + vallen + 1) * sizeof(TCHAR));
|
||||
_tcscpy (fullvalue, dir);
|
||||
}
|
||||
|
||||
/* Append value */
|
||||
|
||||
if (quoted)
|
||||
{
|
||||
_tcsncpy (fullvalue + dirlen, value + 1, vallen - 1);
|
||||
fullvalue [dirlen + vallen - sizeof(TCHAR)] = _T('\0');
|
||||
}
|
||||
else
|
||||
_tcscpy (fullvalue + dirlen, value);
|
||||
|
||||
if (*last <= *index)
|
||||
{
|
||||
*last += EXPAND_ARGV_RATE;
|
||||
*argv = (char **) xrealloc (*argv, (*last) * sizeof (char *));
|
||||
}
|
||||
|
||||
size = WS2SC (NULL, fullvalue, 0);
|
||||
(*argv)[*index] = (char *) xmalloc (size + sizeof(TCHAR));
|
||||
WS2SC ((*argv)[*index], fullvalue, size);
|
||||
|
||||
free (fullvalue);
|
||||
|
||||
(*index)++;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* Initialize floating-point coprocessor. This call is needed because
|
||||
the MS libraries default to 64-bit precision instead of 80-bit
|
||||
precision, and we require the full precision for proper operation,
|
||||
given that we have set Max_Digits etc with this in mind */
|
||||
__gnat_init_float ();
|
||||
|
||||
/* Initialize the critical section and event handle for the win32_wait()
|
||||
implementation, see adaint.c */
|
||||
InitializeCriticalSection (&ProcListCS);
|
||||
ProcListEvt = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
|
||||
#ifdef GNAT_UNICODE_SUPPORT
|
||||
/* Set current code page for filenames handling. */
|
||||
{
|
||||
char *codepage = getenv ("GNAT_CODE_PAGE");
|
||||
|
||||
/* Default code page is UTF-8. */
|
||||
CurrentCodePage = CP_UTF8;
|
||||
|
||||
if (codepage != NULL)
|
||||
{
|
||||
if (strcmp (codepage, "CP_ACP") == 0)
|
||||
CurrentCodePage = CP_ACP;
|
||||
else if (strcmp (codepage, "CP_UTF8") == 0)
|
||||
CurrentCodePage = CP_UTF8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set current encoding for the IO. */
|
||||
{
|
||||
char *ccsencoding = getenv ("GNAT_CCS_ENCODING");
|
||||
|
||||
/* Default CCS Encoding. */
|
||||
CurrentCCSEncoding = _O_TEXT;
|
||||
__gnat_wide_text_translation_required = 0;
|
||||
|
||||
if (ccsencoding != NULL)
|
||||
{
|
||||
if (strcmp (ccsencoding, "U16TEXT") == 0)
|
||||
{
|
||||
CurrentCCSEncoding = _O_U16TEXT;
|
||||
__gnat_wide_text_translation_required = 1;
|
||||
}
|
||||
else if (strcmp (ccsencoding, "TEXT") == 0)
|
||||
{
|
||||
CurrentCCSEncoding = _O_TEXT;
|
||||
__gnat_wide_text_translation_required = 0;
|
||||
}
|
||||
else if (strcmp (ccsencoding, "WTEXT") == 0)
|
||||
{
|
||||
CurrentCCSEncoding = _O_WTEXT;
|
||||
__gnat_wide_text_translation_required = 1;
|
||||
}
|
||||
else if (strcmp (ccsencoding, "U8TEXT") == 0)
|
||||
{
|
||||
CurrentCCSEncoding = _O_U8TEXT;
|
||||
__gnat_wide_text_translation_required = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust gnat_argv to support Unicode characters. */
|
||||
{
|
||||
LPWSTR *wargv;
|
||||
int wargc;
|
||||
int k;
|
||||
int last;
|
||||
int argc_expanded = 0;
|
||||
TCHAR result [MAX_PATH];
|
||||
int quoted;
|
||||
|
||||
wargv = CommandLineToArgvW (GetCommandLineW(), &wargc);
|
||||
|
||||
if (wargv != NULL)
|
||||
{
|
||||
/* Set gnat_argv with arguments encoded in UTF-8. */
|
||||
last = wargc + 1;
|
||||
gnat_argv = (char **) xmalloc ((last) * sizeof (char *));
|
||||
|
||||
/* argv[0] is the executable full path-name. */
|
||||
|
||||
SearchPath (NULL, wargv[0], _T(".exe"), MAX_PATH, result, NULL);
|
||||
append_arg (&argc_expanded, NULL, result, &gnat_argv, &last, 0);
|
||||
|
||||
for (k=1; k<wargc; k++)
|
||||
{
|
||||
quoted = (wargv[k][0] == _T('\''));
|
||||
|
||||
/* Check for wildcard expansion if the argument is not quoted. */
|
||||
if (!quoted
|
||||
&& (_tcsstr (wargv[k], _T("?")) != 0 ||
|
||||
_tcsstr (wargv[k], _T("*")) != 0))
|
||||
{
|
||||
/* Wilcards are present, append all corresponding matches. */
|
||||
WIN32_FIND_DATA FileData;
|
||||
HANDLE hDir = FindFirstFile (wargv[k], &FileData);
|
||||
LPWSTR dir = NULL;
|
||||
LPWSTR ldir = _tcsrchr (wargv[k], _T('\\'));
|
||||
|
||||
if (ldir == NULL)
|
||||
ldir = _tcsrchr (wargv[k], _T('/'));
|
||||
|
||||
if (hDir == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* No match, append arg as-is. */
|
||||
append_arg (&argc_expanded, NULL, wargv[k],
|
||||
&gnat_argv, &last, quoted);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ldir != NULL)
|
||||
{
|
||||
int n = ldir - wargv[k] + 1;
|
||||
dir = (LPWSTR) xmalloc ((n + 1) * sizeof (TCHAR));
|
||||
_tcsncpy (dir, wargv[k], n);
|
||||
dir[n] = _T('\0');
|
||||
}
|
||||
|
||||
/* Append first match and all remaining ones. */
|
||||
|
||||
do {
|
||||
/* Do not add . and .. special entries */
|
||||
|
||||
if (_tcscmp (FileData.cFileName, _T(".")) != 0
|
||||
&& _tcscmp (FileData.cFileName, _T("..")) != 0)
|
||||
append_arg (&argc_expanded, dir, FileData.cFileName,
|
||||
&gnat_argv, &last, 0);
|
||||
} while (FindNextFile (hDir, &FileData));
|
||||
|
||||
FindClose (hDir);
|
||||
|
||||
if (dir != NULL)
|
||||
free (dir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No wildcard. Store parameter as-is. Remove quote if
|
||||
needed. */
|
||||
append_arg (&argc_expanded, NULL, wargv[k],
|
||||
&gnat_argv, &last, quoted);
|
||||
}
|
||||
}
|
||||
|
||||
LocalFree (wargv);
|
||||
gnat_argc = argc_expanded;
|
||||
gnat_argv = (char **) xrealloc
|
||||
(gnat_argv, argc_expanded * sizeof (char *));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note that we do not activate this for the compiler itself to avoid a
|
||||
bootstrap path problem. Older version of gnatbind will generate a call
|
||||
to __gnat_initialize() without argument. Therefore we cannot use eh in
|
||||
@ -305,12 +90,9 @@ __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
|
||||
#elif defined (__Lynx__) || defined (__FreeBSD__) || defined(__NetBSD__) \
|
||||
|| defined (__OpenBSD__)
|
||||
|
||||
extern void __gnat_init_float (void);
|
||||
|
||||
void
|
||||
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
|
||||
{
|
||||
__gnat_init_float ();
|
||||
}
|
||||
|
||||
/***************************************/
|
||||
@ -319,12 +101,9 @@ __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
|
||||
|
||||
#elif defined(__vxworks)
|
||||
|
||||
extern void __gnat_init_float (void);
|
||||
|
||||
void
|
||||
__gnat_initialize (void *eh)
|
||||
{
|
||||
__gnat_init_float ();
|
||||
}
|
||||
|
||||
#elif defined(_T_HPUX10) || (!defined(IN_RTS) && defined(_X_HPUX10))
|
||||
@ -354,7 +133,6 @@ void
|
||||
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
89
gcc/ada/rtfinal.c
Normal file
89
gcc/ada/rtfinal.c
Normal file
@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
* *
|
||||
* GNAT COMPILER COMPONENTS *
|
||||
* *
|
||||
* R T F I N A L *
|
||||
* *
|
||||
* C Implementation File *
|
||||
* *
|
||||
* Copyright (C) 2014-2015, Free Software Foundation, Inc. *
|
||||
* *
|
||||
* GNAT is free software; you can redistribute it and/or modify it under *
|
||||
* terms of the GNU General Public License as published by the Free Soft- *
|
||||
* ware Foundation; either version 3, or (at your option) any later ver- *
|
||||
* sion. GNAT is distributed in the hope that it will be useful, but WITH- *
|
||||
* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* *
|
||||
* As a special exception under Section 7 of GPL version 3, you are granted *
|
||||
* additional permissions described in the GCC Runtime Library Exception, *
|
||||
* version 3.1, as published by the Free Software Foundation. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License and *
|
||||
* a copy of the GCC Runtime Library Exception along with this program; *
|
||||
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* GNAT was originally developed by the GNAT team at New York University. *
|
||||
* Extensive contributions were provided by Ada Core Technologies Inc. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void __gnat_runtime_finalize (void);
|
||||
|
||||
/* This routine is called at the extreme end of execution of an Ada program
|
||||
(the call is generated by the binder). The standard routine does nothing
|
||||
at all, the intention is that this be replaced by system specific code
|
||||
where finalization is required.
|
||||
|
||||
Note that __gnat_runtime_initialize() is called in adafinal() */
|
||||
|
||||
extern int __gnat_rt_init_count;
|
||||
/* see initialize.c */
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
#include "mingw32.h"
|
||||
#include <windows.h>
|
||||
|
||||
extern CRITICAL_SECTION ProcListCS;
|
||||
extern HANDLE ProcListEvt;
|
||||
|
||||
void
|
||||
__gnat_runtime_finalize (void)
|
||||
{
|
||||
/* decrement the reference counter */
|
||||
|
||||
__gnat_rt_init_count--;
|
||||
|
||||
/* if still some referenced return now */
|
||||
if (__gnat_rt_init_count > 0)
|
||||
return;
|
||||
|
||||
/* delete critical section and event handle used for the
|
||||
processes chain list */
|
||||
DeleteCriticalSection(&ProcListCS);
|
||||
CloseHandle (ProcListEvt);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
__gnat_runtime_finalize (void)
|
||||
{
|
||||
/* decrement the reference counter */
|
||||
|
||||
__gnat_rt_init_count--;
|
||||
|
||||
/* if still some referenced return now */
|
||||
if (__gnat_rt_init_count > 0)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
381
gcc/ada/rtinit.c
Normal file
381
gcc/ada/rtinit.c
Normal file
@ -0,0 +1,381 @@
|
||||
/****************************************************************************
|
||||
* *
|
||||
* GNAT COMPILER COMPONENTS *
|
||||
* *
|
||||
* I N I T I A L I Z E *
|
||||
* *
|
||||
* C Implementation File *
|
||||
* *
|
||||
* Copyright (C) 2014-2015, Free Software Foundation, Inc. *
|
||||
* *
|
||||
* GNAT is free software; you can redistribute it and/or modify it under *
|
||||
* terms of the GNU General Public License as published by the Free Soft- *
|
||||
* ware Foundation; either version 3, or (at your option) any later ver- *
|
||||
* sion. GNAT is distributed in the hope that it will be useful, but WITH- *
|
||||
* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* *
|
||||
* As a special exception under Section 7 of GPL version 3, you are granted *
|
||||
* additional permissions described in the GCC Runtime Library Exception, *
|
||||
* version 3.1, as published by the Free Software Foundation. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License and *
|
||||
* a copy of the GCC Runtime Library Exception along with this program; *
|
||||
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
|
||||
* <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* GNAT was originally developed by the GNAT team at New York University. *
|
||||
* Extensive contributions were provided by Ada Core Technologies Inc. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
/* This unit provides implementation for __gnat_runtime_initialize ()
|
||||
which is called in adainit() to do special initialization needed by
|
||||
the GNAT runtime. */
|
||||
|
||||
|
||||
/* The following include is here to meet the published VxWorks requirement
|
||||
that the __vxworks header appear before any other include. */
|
||||
#ifdef __vxworks
|
||||
#include "vxWorks.h"
|
||||
#endif
|
||||
|
||||
#ifdef IN_RTS
|
||||
#include "tconfig.h"
|
||||
#include "tsystem.h"
|
||||
/* We don't have libiberty, so use malloc. */
|
||||
#define xmalloc(S) malloc (S)
|
||||
#define xrealloc(V,S) realloc (V,S)
|
||||
#else
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#endif
|
||||
|
||||
#include "raise.h"
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************/
|
||||
/* __gnat_runtime_initialize (NT-mingw32 Version) */
|
||||
/**************************************************/
|
||||
|
||||
extern void __gnat_install_handler(void);
|
||||
|
||||
int __gnat_wide_text_translation_required = 0;
|
||||
/* wide text translation, 0=none, 1=activated */
|
||||
|
||||
int __gnat_rt_init_count = 0;
|
||||
/* number of references to the GNAT runtime, this is used to initialize
|
||||
and finalize properly the run-time. */
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
#include "mingw32.h"
|
||||
#include <windows.h>
|
||||
|
||||
extern void __gnat_init_float (void);
|
||||
extern void __gnat_install_SEH_handler (void *);
|
||||
|
||||
extern int gnat_argc;
|
||||
extern char **gnat_argv;
|
||||
extern CRITICAL_SECTION ProcListCS;
|
||||
extern HANDLE ProcListEvt;
|
||||
|
||||
#ifdef GNAT_UNICODE_SUPPORT
|
||||
|
||||
#define EXPAND_ARGV_RATE 128
|
||||
|
||||
static void
|
||||
append_arg (int *index, LPWSTR dir, LPWSTR value,
|
||||
char ***argv, int *last, int quoted)
|
||||
{
|
||||
int size;
|
||||
LPWSTR fullvalue;
|
||||
int vallen = _tcslen (value);
|
||||
int dirlen;
|
||||
|
||||
if (dir == NULL)
|
||||
{
|
||||
/* no dir prefix */
|
||||
dirlen = 0;
|
||||
fullvalue = (LPWSTR) xmalloc ((vallen + 1) * sizeof(TCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add dir first */
|
||||
dirlen = _tcslen (dir);
|
||||
|
||||
fullvalue = (LPWSTR) xmalloc ((dirlen + vallen + 1) * sizeof(TCHAR));
|
||||
_tcscpy (fullvalue, dir);
|
||||
}
|
||||
|
||||
/* Append value */
|
||||
|
||||
if (quoted)
|
||||
{
|
||||
_tcsncpy (fullvalue + dirlen, value + 1, vallen - 1);
|
||||
fullvalue [dirlen + vallen - sizeof(TCHAR)] = _T('\0');
|
||||
}
|
||||
else
|
||||
_tcscpy (fullvalue + dirlen, value);
|
||||
|
||||
if (*last <= *index)
|
||||
{
|
||||
*last += EXPAND_ARGV_RATE;
|
||||
*argv = (char **) xrealloc (*argv, (*last) * sizeof (char *));
|
||||
}
|
||||
|
||||
size = WS2SC (NULL, fullvalue, 0);
|
||||
(*argv)[*index] = (char *) xmalloc (size + sizeof(TCHAR));
|
||||
WS2SC ((*argv)[*index], fullvalue, size);
|
||||
|
||||
free (fullvalue);
|
||||
|
||||
(*index)++;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__gnat_runtime_initialize(void)
|
||||
{
|
||||
/* increment the reference counter */
|
||||
|
||||
__gnat_rt_init_count++;
|
||||
|
||||
/* if already initialized return now */
|
||||
if (__gnat_rt_init_count > 1)
|
||||
return;
|
||||
|
||||
/* Initialize floating-point coprocessor. This call is needed because
|
||||
the MS libraries default to 64-bit precision instead of 80-bit
|
||||
precision, and we require the full precision for proper operation,
|
||||
given that we have set Max_Digits etc with this in mind */
|
||||
|
||||
__gnat_init_float ();
|
||||
|
||||
/* Initialize the critical section and event handle for the win32_wait()
|
||||
implementation, see adaint.c */
|
||||
|
||||
InitializeCriticalSection (&ProcListCS);
|
||||
ProcListEvt = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
|
||||
#ifdef GNAT_UNICODE_SUPPORT
|
||||
/* Set current code page for filenames handling. */
|
||||
{
|
||||
char *codepage = getenv ("GNAT_CODE_PAGE");
|
||||
|
||||
/* Default code page is UTF-8. */
|
||||
CurrentCodePage = CP_UTF8;
|
||||
|
||||
if (codepage != NULL)
|
||||
{
|
||||
if (strcmp (codepage, "CP_ACP") == 0)
|
||||
CurrentCodePage = CP_ACP;
|
||||
else if (strcmp (codepage, "CP_UTF8") == 0)
|
||||
CurrentCodePage = CP_UTF8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set current encoding for the IO. */
|
||||
{
|
||||
char *ccsencoding = getenv ("GNAT_CCS_ENCODING");
|
||||
|
||||
/* Default CCS Encoding. */
|
||||
CurrentCCSEncoding = _O_TEXT;
|
||||
__gnat_wide_text_translation_required = 0;
|
||||
|
||||
if (ccsencoding != NULL)
|
||||
{
|
||||
if (strcmp (ccsencoding, "U16TEXT") == 0)
|
||||
{
|
||||
CurrentCCSEncoding = _O_U16TEXT;
|
||||
__gnat_wide_text_translation_required = 1;
|
||||
}
|
||||
else if (strcmp (ccsencoding, "TEXT") == 0)
|
||||
{
|
||||
CurrentCCSEncoding = _O_TEXT;
|
||||
__gnat_wide_text_translation_required = 0;
|
||||
}
|
||||
else if (strcmp (ccsencoding, "WTEXT") == 0)
|
||||
{
|
||||
CurrentCCSEncoding = _O_WTEXT;
|
||||
__gnat_wide_text_translation_required = 1;
|
||||
}
|
||||
else if (strcmp (ccsencoding, "U8TEXT") == 0)
|
||||
{
|
||||
CurrentCCSEncoding = _O_U8TEXT;
|
||||
__gnat_wide_text_translation_required = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust gnat_argv to support Unicode characters. */
|
||||
{
|
||||
LPWSTR *wargv;
|
||||
int wargc;
|
||||
int k;
|
||||
int last;
|
||||
int argc_expanded = 0;
|
||||
TCHAR result [MAX_PATH];
|
||||
int quoted;
|
||||
|
||||
wargv = CommandLineToArgvW (GetCommandLineW(), &wargc);
|
||||
|
||||
if (wargv != NULL)
|
||||
{
|
||||
/* Set gnat_argv with arguments encoded in UTF-8. */
|
||||
last = wargc + 1;
|
||||
gnat_argv = (char **) xmalloc ((last) * sizeof (char *));
|
||||
|
||||
/* argv[0] is the executable full path-name. */
|
||||
|
||||
SearchPath (NULL, wargv[0], _T(".exe"), MAX_PATH, result, NULL);
|
||||
append_arg (&argc_expanded, NULL, result, &gnat_argv, &last, 0);
|
||||
|
||||
for (k=1; k<wargc; k++)
|
||||
{
|
||||
quoted = (wargv[k][0] == _T('\''));
|
||||
|
||||
/* Check for wildcard expansion if the argument is not quoted. */
|
||||
if (!quoted
|
||||
&& (_tcsstr (wargv[k], _T("?")) != 0 ||
|
||||
_tcsstr (wargv[k], _T("*")) != 0))
|
||||
{
|
||||
/* Wilcards are present, append all corresponding matches. */
|
||||
WIN32_FIND_DATA FileData;
|
||||
HANDLE hDir = FindFirstFile (wargv[k], &FileData);
|
||||
LPWSTR dir = NULL;
|
||||
LPWSTR ldir = _tcsrchr (wargv[k], _T('\\'));
|
||||
|
||||
if (ldir == NULL)
|
||||
ldir = _tcsrchr (wargv[k], _T('/'));
|
||||
|
||||
if (hDir == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* No match, append arg as-is. */
|
||||
append_arg (&argc_expanded, NULL, wargv[k],
|
||||
&gnat_argv, &last, quoted);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ldir != NULL)
|
||||
{
|
||||
int n = ldir - wargv[k] + 1;
|
||||
dir = (LPWSTR) xmalloc ((n + 1) * sizeof (TCHAR));
|
||||
_tcsncpy (dir, wargv[k], n);
|
||||
dir[n] = _T('\0');
|
||||
}
|
||||
|
||||
/* Append first match and all remaining ones. */
|
||||
|
||||
do {
|
||||
/* Do not add . and .. special entries */
|
||||
|
||||
if (_tcscmp (FileData.cFileName, _T(".")) != 0
|
||||
&& _tcscmp (FileData.cFileName, _T("..")) != 0)
|
||||
append_arg (&argc_expanded, dir, FileData.cFileName,
|
||||
&gnat_argv, &last, 0);
|
||||
} while (FindNextFile (hDir, &FileData));
|
||||
|
||||
FindClose (hDir);
|
||||
|
||||
if (dir != NULL)
|
||||
free (dir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No wildcard. Store parameter as-is. Remove quote if
|
||||
needed. */
|
||||
append_arg (&argc_expanded, NULL, wargv[k],
|
||||
&gnat_argv, &last, quoted);
|
||||
}
|
||||
}
|
||||
|
||||
LocalFree (wargv);
|
||||
gnat_argc = argc_expanded;
|
||||
gnat_argv = (char **) xrealloc
|
||||
(gnat_argv, argc_expanded * sizeof (char *));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__gnat_install_handler();
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
/* __gnat_runtime_initialize (init_float version) */
|
||||
/**************************************************/
|
||||
|
||||
#elif defined (__Lynx__) || defined (__FreeBSD__) || defined(__NetBSD__) \
|
||||
|| defined (__OpenBSD__)
|
||||
|
||||
extern void __gnat_init_float (void);
|
||||
|
||||
void
|
||||
__gnat_runtime_initialize(void)
|
||||
{
|
||||
/* increment the reference counter */
|
||||
|
||||
__gnat_rt_init_count++;
|
||||
|
||||
/* if already initialized return now */
|
||||
if (__gnat_rt_init_count > 1)
|
||||
return;
|
||||
|
||||
__gnat_init_float ();
|
||||
|
||||
__gnat_install_handler();
|
||||
}
|
||||
|
||||
/***********************************************/
|
||||
/* __gnat_runtime_initialize (VxWorks Version) */
|
||||
/***********************************************/
|
||||
|
||||
#elif defined(__vxworks)
|
||||
|
||||
extern void __gnat_init_float (void);
|
||||
|
||||
void
|
||||
__gnat_runtime_initialize(void)
|
||||
{
|
||||
/* increment the reference counter */
|
||||
|
||||
__gnat_rt_init_count++;
|
||||
|
||||
/* if already initialized return now */
|
||||
if (__gnat_rt_init_count > 1)
|
||||
return;
|
||||
|
||||
__gnat_init_float ();
|
||||
|
||||
__gnat_install_handler();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/***********************************************/
|
||||
/* __gnat_runtime_initialize (default version) */
|
||||
/***********************************************/
|
||||
|
||||
void
|
||||
__gnat_runtime_initialize(void)
|
||||
{
|
||||
/* increment the reference counter */
|
||||
|
||||
__gnat_rt_init_count++;
|
||||
|
||||
/* if already initialized return now */
|
||||
if (__gnat_rt_init_count > 1)
|
||||
return;
|
||||
|
||||
__gnat_install_handler();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user