diff gcc/d/dmd/root/file.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/d/dmd/root/file.c	Thu Feb 13 11:34:05 2020 +0900
@@ -0,0 +1,258 @@
+
+/* Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
+ * http://www.digitalmars.com
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
+ * https://github.com/D-Programming-Language/dmd/blob/master/src/root/file.c
+ */
+
+#include "dsystem.h"
+#include "file.h"
+
+#if _WIN32
+#include <windows.h>
+#endif
+
+#if POSIX
+#include <utime.h>
+#endif
+
+#include "filename.h"
+#include "array.h"
+#include "rmem.h"
+
+/****************************** File ********************************/
+
+File::File(const FileName *n)
+{
+    ref = 0;
+    buffer = NULL;
+    len = 0;
+    name = const_cast<FileName *>(n);
+}
+
+File *File::create(const char *n)
+{
+    return new File(n);
+}
+
+File::File(const char *n)
+{
+    ref = 0;
+    buffer = NULL;
+    len = 0;
+    name = new FileName(n);
+}
+
+File::~File()
+{
+    if (buffer)
+    {
+        if (ref == 0)
+            mem.xfree(buffer);
+#if _WIN32
+        if (ref == 2)
+            UnmapViewOfFile(buffer);
+#endif
+    }
+}
+
+/*************************************
+ */
+
+bool File::read()
+{
+    if (len)
+        return false;               // already read the file
+#if POSIX
+    size_t size;
+    struct stat buf;
+    ssize_t numread;
+
+    const char *name = this->name->toChars();
+    //printf("File::read('%s')\n",name);
+    int fd = open(name, O_RDONLY);
+    if (fd == -1)
+    {
+        //printf("\topen error, errno = %d\n",errno);
+        goto err1;
+    }
+
+    if (!ref)
+        ::free(buffer);
+    ref = 0;       // we own the buffer now
+
+    //printf("\tfile opened\n");
+    if (fstat(fd, &buf))
+    {
+        printf("\tfstat error, errno = %d\n",errno);
+        goto err2;
+    }
+    size = (size_t)buf.st_size;
+#ifdef IN_GCC
+    buffer = (unsigned char *) ::xmalloc(size + 2);
+#else
+    buffer = (unsigned char *) ::malloc(size + 2);
+#endif
+    if (!buffer)
+    {
+        printf("\tmalloc error, errno = %d\n",errno);
+        goto err2;
+    }
+
+    numread = ::read(fd, buffer, size);
+    if (numread != (ssize_t)size)
+    {
+        printf("\tread error, errno = %d\n",errno);
+        goto err2;
+    }
+
+    if (close(fd) == -1)
+    {
+        printf("\tclose error, errno = %d\n",errno);
+        goto err;
+    }
+
+    len = size;
+
+    // Always store a wchar ^Z past end of buffer so scanner has a sentinel
+    buffer[size] = 0;           // ^Z is obsolete, use 0
+    buffer[size + 1] = 0;
+    return false;
+
+err2:
+    close(fd);
+err:
+    ::free(buffer);
+    buffer = NULL;
+    len = 0;
+
+err1:
+    return true;
+#elif _WIN32
+    DWORD size;
+    DWORD numread;
+
+    const char *name = this->name->toChars();
+    HANDLE h = CreateFileA(name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,
+        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
+    if (h == INVALID_HANDLE_VALUE)
+        goto err1;
+
+    if (!ref)
+        ::free(buffer);
+    ref = 0;
+
+    size = GetFileSize(h,NULL);
+#ifdef IN_GCC
+    buffer = (unsigned char *) ::xmalloc(size + 2);
+#else
+    buffer = (unsigned char *) ::malloc(size + 2);
+#endif
+    if (!buffer)
+        goto err2;
+
+    if (ReadFile(h,buffer,size,&numread,NULL) != TRUE)
+        goto err2;
+
+    if (numread != size)
+        goto err2;
+
+    if (!CloseHandle(h))
+        goto err;
+
+    len = size;
+
+    // Always store a wchar ^Z past end of buffer so scanner has a sentinel
+    buffer[size] = 0;           // ^Z is obsolete, use 0
+    buffer[size + 1] = 0;
+    return 0;
+
+err2:
+    CloseHandle(h);
+err:
+    ::free(buffer);
+    buffer = NULL;
+    len = 0;
+
+err1:
+    return true;
+#else
+    assert(0);
+#endif
+}
+
+/*********************************************
+ * Write a file.
+ * Returns:
+ *      false       success
+ */
+
+bool File::write()
+{
+#if POSIX
+    ssize_t numwritten;
+
+    const char *name = this->name->toChars();
+    int fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, (6 << 6) | (4 << 3) | 4);
+    if (fd == -1)
+        goto err;
+
+    numwritten = ::write(fd, buffer, len);
+    if ((ssize_t)len != numwritten)
+        goto err2;
+
+    if (close(fd) == -1)
+        goto err;
+
+    return false;
+
+err2:
+    close(fd);
+    ::remove(name);
+err:
+    return true;
+#elif _WIN32
+    DWORD numwritten;
+
+    const char *name = this->name->toChars();
+    HANDLE h = CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
+        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
+    if (h == INVALID_HANDLE_VALUE)
+        goto err;
+
+    if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE)
+        goto err2;
+
+    if (len != numwritten)
+        goto err2;
+
+    if (!CloseHandle(h))
+        goto err;
+    return false;
+
+err2:
+    CloseHandle(h);
+    DeleteFileA(name);
+err:
+    return true;
+#else
+    assert(0);
+#endif
+}
+
+void File::remove()
+{
+#if POSIX
+    ::remove(this->name->toChars());
+#elif _WIN32
+    DeleteFileA(this->name->toChars());
+#else
+    assert(0);
+#endif
+}
+
+const char *File::toChars()
+{
+    return name->toChars();
+}