Mercurial > hg > CbC > CbC_gcc
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(); +}