diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2010-10-25 16:44:20 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2010-10-25 16:44:20 +0200 |
commit | f6b5dc8e1f88f71b3a523ff651bfdc32aa3c890b (patch) | |
tree | 6324a36969f16b9d490577a0560b012087d1c2ee /gcc/ada/adaint.c | |
parent | 66150d01351e5ca53999297629516ea2d5bcedb1 (diff) | |
download | gcc-f6b5dc8e1f88f71b3a523ff651bfdc32aa3c890b.zip gcc-f6b5dc8e1f88f71b3a523ff651bfdc32aa3c890b.tar.gz gcc-f6b5dc8e1f88f71b3a523ff651bfdc32aa3c890b.tar.bz2 |
[multiple changes]
2010-10-25 Robert Dewar <dewar@adacore.com>
* exp_ch5.adb (Expand_Predicated_Loop): Remove code for loop through
non-static predicate, since we agree not to allow this.
(Expand_Predicated_Loop): Properlay handle false predicate (null
list in Static_Predicate field.
* sem_ch13.adb (Build_Static_Predicate): Extensive changes to clean up
handling of more general predicate forms.
2010-10-25 Robert Dewar <dewar@adacore.com>
* sem_ch4.adb, sem_util.adb: Minor reformatting.
* sem_ch8.adb (Find_Selected_Component): Allow selection from instance
of type in predicate or invariant expression.
2010-10-25 Pascal Obry <obry@adacore.com>
* adaint.c (__gnat_stat_to_attr): Can set the timestamp on Windows now.
(f2t): New routine.
(__gnat_stat): Rewrite Win32 version.
From-SVN: r165919
Diffstat (limited to 'gcc/ada/adaint.c')
-rw-r--r-- | gcc/ada/adaint.c | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c index b3e2e0ce..a251a4e 100644 --- a/gcc/ada/adaint.c +++ b/gcc/ada/adaint.c @@ -1112,8 +1112,6 @@ __gnat_stat_to_attr (int fd, char* name, struct file_attributes* attr) attr->executable = (!ret && (statbuf.st_mode & S_IXUSR)); #endif -#if !defined (_WIN32) || defined (RTX) - /* on Windows requires extra system call, see __gnat_file_time_name_attr */ if (ret != 0) { attr->timestamp = (OS_Time)-1; } else { @@ -1124,8 +1122,6 @@ __gnat_stat_to_attr (int fd, char* name, struct file_attributes* attr) attr->timestamp = (OS_Time)statbuf.st_mtime; #endif } -#endif - } /**************************************************************** @@ -1345,6 +1341,19 @@ win32_filetime (HANDLE h) return (time_t) (t_write.ull_time / 10000000ULL - w32_epoch_offset); return (time_t) 0; } + +/* As above but starting from a FILETIME. */ +static void f2t (const FILETIME *ft, time_t *t) +{ + union + { + FILETIME ft_time; + unsigned long long ull_time; + } t_write; + + t_write.ft_time = *ft; + *t = (time_t) (t_write.ull_time / 10000000ULL - w32_epoch_offset); +} #endif /* Return a GNAT time stamp given a file name. */ @@ -1687,15 +1696,10 @@ int __gnat_stat (char *name, GNAT_STRUCT_STAT *statbuf) { #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 - or with UNC path without directory (only the name of the shared - resource), for example: \\computer\share\ */ - + WIN32_FILE_ATTRIBUTE_DATA fad; TCHAR wname [GNAT_MAX_PATH_LEN + 2]; - int name_len, k; - TCHAR last_char; - int dirsep_count = 0; + int name_len; + BOOL res; S2WSC (wname, name, GNAT_MAX_PATH_LEN + 2); name_len = _tcslen (wname); @@ -1703,29 +1707,43 @@ __gnat_stat (char *name, GNAT_STRUCT_STAT *statbuf) if (name_len > GNAT_MAX_PATH_LEN) return -1; - last_char = wname[name_len - 1]; - - while (name_len > 1 && (last_char == _T('\\') || last_char == _T('/'))) - { - wname[name_len - 1] = _T('\0'); - name_len--; - last_char = wname[name_len - 1]; + ZeroMemory (statbuf, sizeof(GNAT_STRUCT_STAT)); + + res = GetFileAttributesEx (wname, GetFileExInfoStandard, &fad); + + if (res == FALSE) + switch (GetLastError()) { + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_LOCK_VIOLATION: + case ERROR_SHARING_BUFFER_EXCEEDED: + return EACCES; + case ERROR_BUFFER_OVERFLOW: + return ENAMETOOLONG; + case ERROR_NOT_ENOUGH_MEMORY: + return ENOMEM; + default: + return ENOENT; } - /* Count back-slashes. */ + f2t (&fad.ftCreationTime, &statbuf->st_ctime); + f2t (&fad.ftLastWriteTime, &statbuf->st_mtime); + f2t (&fad.ftLastAccessTime, &statbuf->st_atime); + + statbuf->st_size = (off_t)fad.nFileSizeLow; - for (k=0; k<name_len; k++) - if (wname[k] == _T('\\') || wname[k] == _T('/')) - dirsep_count++; + /* We do not have the S_IEXEC attribute, but this is not used on GNAT. */ + statbuf->st_mode = S_IREAD; - /* 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(':')) - || (name_len > 3 && wname[0] == _T('\\') && wname[1] == _T('\\') - && dirsep_count == 3)) - _tcscat (wname, _T("\\")); + if (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + statbuf->st_mode |= S_IFDIR; + else + statbuf->st_mode |= S_IFREG; - return _tstat (wname, (struct _stat *)statbuf); + if (!(fad.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + statbuf->st_mode |= S_IWRITE; + + return 0; #else return GNAT_STAT (name, statbuf); |