diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-15 09:30:39 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-15 09:30:39 +0000 |
commit | 3b18b370fc006dded92a40315801ad42345139fb (patch) | |
tree | ff53725d708aacac9be1a454735ad7f7bd86d8f1 /gcc/ada/adaint.c | |
parent | 11ef74b2c6516991c7aeda4361c1a01c936d6444 (diff) | |
download | gcc-3b18b370fc006dded92a40315801ad42345139fb.tar.gz |
2006-02-13 Pascal Obry <obry@adacore.com>
Nicolas Roche <roche@adacore.com>
Arnaud Charlet <charlet@adacore.com>
* adaint.h, adaint.c (DIR_SEPARATOR): Use _T() macro for Unicode
support.
(__gnat_try_lock): Add unicode support by using a specific section on
Windows.
(__gnat_get_current_dir): Idem.
(__gnat_open_read): Idem.
(__gnat_open_rw): Idem.
(__gnat_open_create): Idem.
(__gnat_create_output_file): Idem.
(__gnat_open_append): Idem.
(__gnat_open_new): Idem.
(__gnat_file_time_name): Idem.
(__gnat_set_file_time_name): Idem.
(__gnat_stat): Idem.
(win32_no_block_spawn): Idem.
(__gnat_locate_exec_on_path): Idem.
(__gnat_opendir): New routine.
(__gnat_closedir): Idem.
(__gnat_readdir): Add new parameter length (pointer to int). Update
implementation to use it and add specific Win32 code for Unicode
support.
(__gnat_get_env_value_ptr): Remove. Replaced by __gnat_getenv in env.c
(__gnat_set_env_value): Remove. Replaced by __gnat_setenv in env.c
(convert_addresses): Do not define this dummy routine on VMS.
* mingw32.h (GNAT_UNICODE_SUPPORT): New definition, if set the GNAT
runtime Unicode support will be activated.
(S2WS): String to Wide-String conversion. This version just copy a
string in non Unicode version.
(WS2S): Wide-String to String conversion. This version just copy a
string in non Unicode version.
* g-dirope.adb: (Close): Now import __gnat_closedir from adaint.c.
(Open): Now import __gnat_opendir from adaint.c.
(Read): Change the implementation to support unicode characters. It is
not possible to use strlen() on Windows as this version supports only
standard ASCII characters. So the length of the directory entry is now
returned from the imported __gnat_readdir routine.
Update copyright notice.
* s-crtl-vms64.ads, s-crtl.ads: (closedir): Moved to adaint.c.
(opendir): Moved to adaint.c.
* g-os_lib.adb (Copy_Time_Stamp): Fix off-by-one range computation.
(Get_Directory): Fix wrong indexing.
(Getenv): replace __gnat_get_env_value_ptr from adaint.c by
__gnat_getenv from env.c
(Setenv): replace __gnat_set_env_value from adaint.c by __gnat_setenv
from env.c
* env.h, env.c: New file.
* s-scaval.adb (Initialize): Replace __gnat_get_env_value_ptr from
adaint.c by __gnat_getenv from env.c
* s-shasto.adb (Initialize): replace __gnat_get_env_value_ptr from
adaint.c by __gnat_getenv from env.c
* Make-lang.in: Add env.o in the list of C object needed by gnat1
and gnatbind.
Update dependencies.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111029 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/adaint.c')
-rw-r--r-- | gcc/ada/adaint.c | 342 |
1 files changed, 184 insertions, 158 deletions
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index 7594e7ba4f8..674df69bb7b 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -6,7 +6,7 @@ * * * C Implementation File * * * - * Copyright (C) 1992-2005, Free Software Foundation, Inc. * + * Copyright (C) 1992-2006, 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- * @@ -411,11 +411,24 @@ __gnat_symlink (char *oldpath ATTRIBUTE_UNUSED, int __gnat_try_lock (char *dir, char *file) { - char full_path[256]; int fd; +#ifdef __MINGW32__ + TCHAR wfull_path[GNAT_MAX_PATH_LEN]; + TCHAR wfile[GNAT_MAX_PATH_LEN]; + TCHAR wdir[GNAT_MAX_PATH_LEN]; + + S2WS (wdir, dir, GNAT_MAX_PATH_LEN); + S2WS (wfile, file, GNAT_MAX_PATH_LEN); + + _stprintf (wfull_path, _T("%s%c%s"), wdir, _T(DIR_SEPARATOR), wfile); + fd = _topen (wfull_path, O_CREAT | O_EXCL, 0600); +#else + char full_path[256]; sprintf (full_path, "%s%c%s", dir, DIR_SEPARATOR, file); fd = open (full_path, O_CREAT | O_EXCL, 0600); +#endif + if (fd < 0) return 0; @@ -436,6 +449,7 @@ __gnat_try_lock (char *dir, char *file) sprintf (full_path, "%s%c%s", dir, DIR_SEPARATOR, file); fd = open (full_path, O_CREAT | O_EXCL, 0600); + if (fd < 0) return 0; @@ -522,7 +536,14 @@ __gnat_get_default_identifier_character_set (void) void __gnat_get_current_dir (char *dir, int *length) { -#ifdef VMS +#if defined (__MINGW32__) + TCHAR wdir[GNAT_MAX_PATH_LEN]; + + _tgetcwd (wdir, *length); + + WS2S (dir, wdir, GNAT_MAX_PATH_LEN); + +#elif defined (VMS) /* Force Unix style, which is what GNAT uses internally. */ getcwd (dir, *length, 0); #else @@ -604,6 +625,13 @@ __gnat_open_read (char *path, int fmode) "mbc=16", "deq=64", "fop=tef"); #elif defined (__vxworks) fd = open (path, O_RDONLY | o_fmode, 0444); +#elif defined (__MINGW32__) + { + TCHAR wpath[GNAT_MAX_PATH_LEN]; + + S2WS (wpath, path, GNAT_MAX_PATH_LEN); + fd = _topen (wpath, O_RDONLY | o_fmode, 0444); + } #else fd = open (path, O_RDONLY | o_fmode); #endif @@ -638,6 +666,13 @@ __gnat_open_rw (char *path, int fmode) #if defined (VMS) fd = open (path, O_RDWR | o_fmode, PERM, "mbc=16", "deq=64", "fop=tef"); +#elif defined (__MINGW32__) + { + TCHAR wpath[GNAT_MAX_PATH_LEN]; + + S2WS (wpath, path, GNAT_MAX_PATH_LEN); + fd = _topen (wpath, O_RDWR | o_fmode, PERM); + } #else fd = open (path, O_RDWR | o_fmode, PERM); #endif @@ -657,6 +692,13 @@ __gnat_open_create (char *path, int fmode) #if defined (VMS) fd = open (path, O_WRONLY | O_CREAT | O_TRUNC | o_fmode, PERM, "mbc=16", "deq=64", "fop=tef"); +#elif defined (__MINGW32__) + { + TCHAR wpath[GNAT_MAX_PATH_LEN]; + + S2WS (wpath, path, GNAT_MAX_PATH_LEN); + fd = _topen (wpath, O_WRONLY | O_CREAT | O_TRUNC | o_fmode, PERM); + } #else fd = open (path, O_WRONLY | O_CREAT | O_TRUNC | o_fmode, PERM); #endif @@ -672,6 +714,13 @@ __gnat_create_output_file (char *path) fd = open (path, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, PERM, "rfm=stmlf", "ctx=rec", "rat=none", "rop=nlk", "shr=del,get,put,upd"); +#elif defined (__MINGW32__) + { + TCHAR wpath[GNAT_MAX_PATH_LEN]; + + S2WS (wpath, path, GNAT_MAX_PATH_LEN); + fd = _topen (wpath, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, PERM); + } #else fd = open (path, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, PERM); #endif @@ -691,6 +740,13 @@ __gnat_open_append (char *path, int fmode) #if defined (VMS) fd = open (path, O_WRONLY | O_CREAT | O_APPEND | o_fmode, PERM, "mbc=16", "deq=64", "fop=tef"); +#elif defined (__MINGW32__) + { + TCHAR wpath[GNAT_MAX_PATH_LEN]; + + S2WS (wpath, path, GNAT_MAX_PATH_LEN); + fd = _topen (wpath, O_WRONLY | O_CREAT | O_APPEND | o_fmode, PERM); + } #else fd = open (path, O_WRONLY | O_CREAT | O_APPEND | o_fmode, PERM); #endif @@ -712,6 +768,13 @@ __gnat_open_new (char *path, int fmode) #if defined (VMS) fd = open (path, O_WRONLY | O_CREAT | O_EXCL | o_fmode, PERM, "mbc=16", "deq=64", "fop=tef"); +#elif defined (__MINGW32__) + { + TCHAR wpath[GNAT_MAX_PATH_LEN]; + + S2WS (wpath, path, GNAT_MAX_PATH_LEN); + fd = _topen (wpath, O_WRONLY | O_CREAT | O_EXCL | o_fmode, PERM); + } #else fd = open (path, O_WRONLY | O_CREAT | O_EXCL | o_fmode, PERM); #endif @@ -838,15 +901,44 @@ __gnat_tmp_name (char *tmp_filename) #endif } +/* Open directory and returns a DIR pointer. */ + +DIR* __gnat_opendir (char *name) +{ +#ifdef __MINGW32__ + TCHAR wname[GNAT_MAX_PATH_LEN]; + + S2WS (wname, name, GNAT_MAX_PATH_LEN); + return (DIR*)_topendir (wname); + +#else + return opendir (name); +#endif +} + /* Read the next entry in a directory. The returned string points somewhere in the buffer. */ char * -__gnat_readdir (DIR *dirp, char *buffer) +__gnat_readdir (DIR *dirp, char *buffer, int *len) { +#if defined (__MINGW32__) + struct _tdirent *dirent = _treaddir ((_TDIR*)dirp); + + if (dirent != NULL) + { + WS2S (buffer, dirent->d_name, GNAT_MAX_PATH_LEN); + *len = strlen (buffer); + + return buffer; + } + else + return NULL; + +#elif defined (HAVE_READDIR_R) /* If possible, try to use the thread-safe version. */ -#ifdef HAVE_READDIR_R if (readdir_r (dirp, buffer) != NULL) + *len = strlen (((struct dirent*) buffer)->d_name); return ((struct dirent*) buffer)->d_name; else return NULL; @@ -857,6 +949,7 @@ __gnat_readdir (DIR *dirp, char *buffer) if (dirent != NULL) { strcpy (buffer, dirent->d_name); + *len = strlen (buffer); return buffer; } else @@ -865,6 +958,18 @@ __gnat_readdir (DIR *dirp, char *buffer) #endif } +/* Close a directory entry. */ + +int __gnat_closedir (DIR *dirp) +{ +#ifdef __MINGW32__ + return _tclosedir ((_TDIR*)dirp); + +#else + return closedir (dirp); +#endif +} + /* Returns 1 if readdir is thread safe, 0 otherwise. */ int @@ -900,8 +1005,7 @@ win32_filetime (HANDLE h) since <Jan 1st 1970>. */ if (GetFileTime (h, NULL, NULL, &t_write.ft_time)) - return (time_t) (t_write.ull_time / 10000000ULL - - w32_epoch_offset); + return (time_t) (t_write.ull_time / 10000000ULL - w32_epoch_offset); return (time_t) 0; } #endif @@ -920,8 +1024,13 @@ __gnat_file_time_name (char *name) #elif defined (_WIN32) time_t ret = 0; - HANDLE h = CreateFile (name, GENERIC_READ, FILE_SHARE_READ, 0, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + TCHAR wname[GNAT_MAX_PATH_LEN]; + + S2WS (wname, name, GNAT_MAX_PATH_LEN); + + HANDLE h = CreateFile + (wname, GENERIC_READ, FILE_SHARE_READ, 0, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (h != INVALID_HANDLE_VALUE) { @@ -1052,10 +1161,14 @@ __gnat_set_file_time_name (char *name, time_t time_stamp) FILETIME ft_time; unsigned long long ull_time; } t_write; + TCHAR wname[GNAT_MAX_PATH_LEN]; - HANDLE h = CreateFile (name, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, - NULL); + S2WS (wname, name, GNAT_MAX_PATH_LEN); + + HANDLE h = CreateFile + (wname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, + NULL); if (h == INVALID_HANDLE_VALUE) return; /* Add number of seconds between <Jan 1st 1601> and <Jan 1st 1970> */ @@ -1122,7 +1235,13 @@ __gnat_set_file_time_name (char *name, time_t time_stamp) struct dsc$descriptor_s resultdsc = {NAM$C_MAXRSS, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, (void *) result.string}; - tryfile = (char *) __gnat_to_host_dir_spec (name, 0); + /* Convert parameter name (a file spec) to host file form. Note that this + is needed on VMS to prepare for subsequent calls to VMS RMS library + routines. Note that it would not work to call __gnat_to_host_dir_spec + as was done in a previous version, since this fails silently unless + the feature logical DECC$EFS_CHARSET is enabled, in which case a DNF + (directory not found) condition is signalled. */ + tryfile = (char *) __gnat_to_host_file_spec (name); /* Allocate and initialize a FAB and NAM structures. */ fab = cc$rms_fab; @@ -1238,123 +1357,6 @@ __gnat_set_file_time_name (char *name, time_t time_stamp) #endif } -void -__gnat_get_env_value_ptr (char *name, int *len, char **value) -{ - *value = getenv (name); - if (!*value) - *len = 0; - else - *len = strlen (*value); - - return; -} - -/* VMS specific declarations for set_env_value. */ - -#ifdef VMS - -static char *to_host_path_spec (char *); - -struct descriptor_s -{ - unsigned short len, mbz; - __char_ptr32 adr; -}; - -typedef struct _ile3 -{ - unsigned short len, code; - __char_ptr32 adr; - unsigned short *retlen_adr; -} ile_s; - -#endif - -void -__gnat_set_env_value (char *name, char *value) -{ -#ifdef MSDOS - -#elif defined (VMS) - struct descriptor_s name_desc; - /* Put in JOB table for now, so that the project stuff at least works. */ - struct descriptor_s table_desc = {7, 0, "LNM$JOB"}; - char *host_pathspec = value; - char *copy_pathspec; - int num_dirs_in_pathspec = 1; - char *ptr; - long status; - - name_desc.len = strlen (name); - name_desc.mbz = 0; - name_desc.adr = name; - - if (*host_pathspec == 0) - /* deassign */ - { - status = LIB$DELETE_LOGICAL (&name_desc, &table_desc); - /* no need to check status; if the logical name is not - defined, that's fine. */ - return; - } - - ptr = host_pathspec; - while (*ptr++) - if (*ptr == ',') - num_dirs_in_pathspec++; - - { - int i, status; - ile_s *ile_array = alloca (sizeof (ile_s) * (num_dirs_in_pathspec + 1)); - char *copy_pathspec = alloca (strlen (host_pathspec) + 1); - char *curr, *next; - - strcpy (copy_pathspec, host_pathspec); - curr = copy_pathspec; - for (i = 0; i < num_dirs_in_pathspec; i++) - { - next = strchr (curr, ','); - if (next == 0) - next = strchr (curr, 0); - - *next = 0; - ile_array[i].len = strlen (curr); - - /* Code 2 from lnmdef.h means it's a string. */ - ile_array[i].code = 2; - ile_array[i].adr = curr; - - /* retlen_adr is ignored. */ - ile_array[i].retlen_adr = 0; - curr = next + 1; - } - - /* Terminating item must be zero. */ - ile_array[i].len = 0; - ile_array[i].code = 0; - ile_array[i].adr = 0; - ile_array[i].retlen_adr = 0; - - status = LIB$SET_LOGICAL (&name_desc, 0, &table_desc, 0, ile_array); - if ((status & 1) != 1) - LIB$SIGNAL (status); - } - -#elif defined (__vxworks) && defined (__RTP__) - setenv (name, value, 1); - -#else - int size = strlen (name) + strlen (value) + 2; - char *expression; - - expression = (char *) xmalloc (size * sizeof (char)); - - sprintf (expression, "%s=%s", name, value); - putenv (expression); -#endif -} - #ifdef _WIN32 #include <windows.h> #endif @@ -1396,7 +1398,7 @@ __gnat_get_libraries_from_registry (void) for (index = 0; res == ERROR_SUCCESS; index++) { value_size = name_size = 256; - res = RegEnumValue (reg_key, index, name, &name_size, 0, + res = RegEnumValue (reg_key, index, (TCHAR*)name, &name_size, 0, &type, (LPBYTE)value, &value_size); if (res == ERROR_SUCCESS && type == REG_SZ) @@ -1421,29 +1423,34 @@ __gnat_get_libraries_from_registry (void) int __gnat_stat (char *name, struct stat *statbuf) { -#ifdef _WIN32 +#ifdef __MINGW32__ /* Under Windows the directory name for the stat function must not be terminated by a directory separator except if just after a drive name. */ - int name_len = strlen (name); - char last_char = name[name_len - 1]; - char win32_name[GNAT_MAX_PATH_LEN + 2]; + TCHAR wname [GNAT_MAX_PATH_LEN + 2]; + int name_len; + TCHAR last_char; + + S2WS (wname, name, GNAT_MAX_PATH_LEN + 2); + name_len = _tcslen (wname); if (name_len > GNAT_MAX_PATH_LEN) return -1; - strcpy (win32_name, name); + last_char = wname[name_len - 1]; - while (name_len > 1 && (last_char == '\\' || last_char == '/')) + while (name_len > 1 && (last_char == _T('\\') || last_char == _T('/'))) { - win32_name[name_len - 1] = '\0'; + wname[name_len - 1] = _T('\0'); name_len--; - last_char = win32_name[name_len - 1]; + last_char = wname[name_len - 1]; } - if (name_len == 2 && win32_name[1] == ':') - strcat (win32_name, "\\"); + /* Only a drive letter followed by ':', we must add a directory separator + for the stat routine to work properly. */ + if (name_len == 2 && wname[1] == _T(':')) + _tcscat (wname, _T("\\")); - return stat (win32_name, statbuf); + return _tstat (wname, statbuf); #else return stat (name, statbuf); @@ -1811,11 +1818,20 @@ win32_no_block_spawn (char *command, char *args[]) k++; } - result = CreateProcess - (NULL, (char *) full_command, &SA, NULL, TRUE, - GetPriorityClass (GetCurrentProcess()), NULL, NULL, &SI, &PI); + { + int wsize = csize * 2; + TCHAR *wcommand = (TCHAR *) xmalloc (wsize); + + S2WS (wcommand, full_command, wsize); + + free (full_command); - free (full_command); + result = CreateProcess + (NULL, wcommand, &SA, NULL, TRUE, + GetPriorityClass (GetCurrentProcess()), NULL, NULL, &SI, &PI); + + free (wcommand); + } if (result == TRUE) { @@ -2075,33 +2091,42 @@ char * __gnat_locate_exec_on_path (char *exec_name) { char *apath_val; -#ifdef VMS - char *path_val = "/VAXC$PATH"; -#else - char *path_val = getenv ("PATH"); -#endif + #ifdef _WIN32 + TCHAR *wpath_val = _tgetenv (_T("PATH")); + TCHAR *wapath_val; /* In Win32 systems we expand the PATH as for XP environment variables are not automatically expanded. We also prepend the ".;" to the path to match normal NT path search semantics */ #define EXPAND_BUFFER_SIZE 32767 - apath_val = alloca (EXPAND_BUFFER_SIZE); + wapath_val = alloca (EXPAND_BUFFER_SIZE); - apath_val [0] = '.'; - apath_val [1] = ';'; + wapath_val [0] = '.'; + wapath_val [1] = ';'; DWORD res = ExpandEnvironmentStrings - (path_val, apath_val + 2, EXPAND_BUFFER_SIZE - 2); + (wpath_val, &wapath_val[2], EXPAND_BUFFER_SIZE - 2); + + if (!res) wapath_val [0] = _T('\0'); + + apath_val = alloca (EXPAND_BUFFER_SIZE); + + WS2S (apath_val, wapath_val, EXPAND_BUFFER_SIZE); + return __gnat_locate_exec (exec_name, apath_val); - if (!res) apath_val [0] = '\0'; #else + +#ifdef VMS + char *path_val = "/VAXC$PATH"; +#else + char *path_val = getenv ("PATH"); +#endif apath_val = alloca (strlen (path_val) + 1); strcpy (apath_val, path_val); -#endif - return __gnat_locate_exec (exec_name, apath_val); +#endif } #ifdef VMS @@ -2556,6 +2581,7 @@ _flush_cache() && ! defined (__APPLE__) \ && ! defined (_AIX) \ && ! (defined (__alpha__) && defined (__osf__)) \ + && ! defined (VMS) \ && ! defined (__MINGW32__) \ && ! (defined (__mips) && defined (__sgi))) |