aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/adaint.c
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2010-10-25 16:44:20 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2010-10-25 16:44:20 +0200
commitf6b5dc8e1f88f71b3a523ff651bfdc32aa3c890b (patch)
tree6324a36969f16b9d490577a0560b012087d1c2ee /gcc/ada/adaint.c
parent66150d01351e5ca53999297629516ea2d5bcedb1 (diff)
downloadgcc-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.c78
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);