move some more bits into impl files
This commit is contained in:
parent
41f4fd4064
commit
afd086b2a0
2
build.sh
2
build.sh
|
@ -13,7 +13,7 @@ ASM_SOURCES="jump_all_gas make_all_gas ontop_all_gas"
|
|||
|
||||
# c++ sources
|
||||
CXX_SOURCE_DIR="src"
|
||||
CXX_SOURCES="context_stack"
|
||||
CXX_SOURCES="context_stack io filesystem"
|
||||
|
||||
# output lib
|
||||
OSTD_LIB="libostd"
|
||||
|
|
|
@ -39,22 +39,11 @@ static constexpr char PATH_SEPARATOR = '\\';
|
|||
static constexpr char PATH_SEPARATOR = '/';
|
||||
#endif
|
||||
|
||||
#ifdef OSTD_PLATFORM_WIN32
|
||||
namespace detail {
|
||||
inline time_t filetime_to_time_t(FILETIME const &ft) {
|
||||
ULARGE_INTEGER ul;
|
||||
ul.LowPart = ft.dwLowDateTime;
|
||||
ul.HighPart = ft.dwHighDateTime;
|
||||
return static_cast<time_t>((ul.QuadPart / 10000000ULL) - 11644473600ULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void path_normalize(char_range) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
struct file_info {
|
||||
struct OSTD_EXPORT file_info {
|
||||
file_info() {}
|
||||
|
||||
file_info(file_info const &i):
|
||||
|
@ -137,82 +126,7 @@ struct file_info {
|
|||
}
|
||||
|
||||
private:
|
||||
void init_from_str(string_range path) {
|
||||
/* TODO: implement a version that will follow symbolic links */
|
||||
p_path = path;
|
||||
#ifdef OSTD_PLATFORM_WIN32
|
||||
WIN32_FILE_ATTRIBUTE_DATA attr;
|
||||
if (!GetFileAttributesEx(p_path.data(), GetFileExInfoStandard, &attr) ||
|
||||
attr.dwFileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
#else
|
||||
struct stat st;
|
||||
if (lstat(p_path.data(), &st) < 0)
|
||||
#endif
|
||||
{
|
||||
p_slash = p_dot = std::string::npos;
|
||||
p_type = file_type::UNKNOWN;
|
||||
p_path.clear();
|
||||
p_atime = p_mtime = p_ctime = 0;
|
||||
return;
|
||||
}
|
||||
string_range r = p_path;
|
||||
|
||||
string_range found = find_last(r, PATH_SEPARATOR);
|
||||
if (found.empty()) {
|
||||
p_slash = std::string::npos;
|
||||
} else {
|
||||
p_slash = r.distance_front(found);
|
||||
}
|
||||
|
||||
found = find(filename(), '.');
|
||||
if (found.empty()) {
|
||||
p_dot = std::string::npos;
|
||||
} else {
|
||||
p_dot = r.distance_front(found);
|
||||
}
|
||||
|
||||
#ifdef OSTD_PLATFORM_WIN32
|
||||
if (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
p_type = file_type::DIRECTORY;
|
||||
} else if (attr.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
p_type = file_type::SYMLINK;
|
||||
} else if (attr.dwFileAttributes & (
|
||||
FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_COMPRESSED |
|
||||
FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL |
|
||||
FILE_ATTRIBUTE_SPARSE_FILE | FILE_ATTRIBUTE_TEMPORARY
|
||||
)) {
|
||||
p_type = file_type::REGULAR;
|
||||
} else {
|
||||
p_type = file_type::UNKNOWN;
|
||||
}
|
||||
|
||||
p_atime = detail::filetime_to_time_t(attr.ftLastAccessTime);
|
||||
p_mtime = detail::filetime_to_time_t(attr.ftLastWriteTime);
|
||||
p_ctime = detail::filetime_to_time_t(attr.ftCreationTime);
|
||||
#else
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
p_type = file_type::REGULAR;
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
p_type = file_type::DIRECTORY;
|
||||
} else if (S_ISCHR(st.st_mode)) {
|
||||
p_type = file_type::CHARACTER;
|
||||
} else if (S_ISBLK(st.st_mode)) {
|
||||
p_type = file_type::BLOCK;
|
||||
} else if (S_ISFIFO(st.st_mode)) {
|
||||
p_type = file_type::FIFO;
|
||||
} else if (S_ISLNK(st.st_mode)) {
|
||||
p_type = file_type::SYMLINK;
|
||||
} else if (S_ISSOCK(st.st_mode)) {
|
||||
p_type = file_type::SOCKET;
|
||||
} else {
|
||||
p_type = file_type::UNKNOWN;
|
||||
}
|
||||
|
||||
p_atime = st.st_atime;
|
||||
p_mtime = st.st_mtime;
|
||||
p_ctime = st.st_ctime;
|
||||
#endif
|
||||
}
|
||||
void init_from_str(string_range path);
|
||||
|
||||
size_t p_slash = std::string::npos, p_dot = std::string::npos;
|
||||
file_type p_type = file_type::UNKNOWN;
|
||||
|
|
132
ostd/io.hh
132
ostd/io.hh
|
@ -6,13 +6,9 @@
|
|||
#ifndef OSTD_IO_HH
|
||||
#define OSTD_IO_HH
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
#include <cerrno>
|
||||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <system_error>
|
||||
|
||||
#include "ostd/platform.hh"
|
||||
#include "ostd/string.hh"
|
||||
#include "ostd/stream.hh"
|
||||
|
@ -24,13 +20,7 @@ enum class stream_mode {
|
|||
READ = 0, WRITE, APPEND, READ_U, WRITE_U, APPEND_U
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
static char const *filemodes[] = {
|
||||
"rb", "wb", "ab", "rb+", "wb+", "ab+"
|
||||
};
|
||||
}
|
||||
|
||||
struct file_stream: stream {
|
||||
struct OSTD_EXPORT file_stream: stream {
|
||||
file_stream(): p_f(), p_owned(false) {}
|
||||
file_stream(file_stream const &) = delete;
|
||||
file_stream(file_stream &&s): p_f(s.p_f), p_owned(s.p_owned) {
|
||||
|
@ -38,7 +28,9 @@ struct file_stream: stream {
|
|||
s.p_owned = false;
|
||||
}
|
||||
|
||||
file_stream(string_range path, stream_mode mode = stream_mode::READ): p_f() {
|
||||
file_stream(string_range path, stream_mode mode = stream_mode::READ):
|
||||
p_f()
|
||||
{
|
||||
open(path, mode);
|
||||
}
|
||||
|
||||
|
@ -53,103 +45,27 @@ struct file_stream: stream {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool open(string_range path, stream_mode mode = stream_mode::READ) {
|
||||
if (p_f || (path.size() > FILENAME_MAX)) {
|
||||
return false;
|
||||
}
|
||||
char buf[FILENAME_MAX + 1];
|
||||
memcpy(buf, &path[0], path.size());
|
||||
buf[path.size()] = '\0';
|
||||
p_owned = false;
|
||||
#ifndef OSTD_PLATFORM_WIN32
|
||||
p_f = fopen(buf, detail::filemodes[size_t(mode)]);
|
||||
#else
|
||||
if (fopen_s(&p_f, buf, detail::filemodes[size_t(mode)]) != 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
p_owned = !!p_f;
|
||||
return is_open();
|
||||
}
|
||||
bool open(string_range path, stream_mode mode = stream_mode::READ);
|
||||
|
||||
bool open(FILE *f) {
|
||||
if (p_f) {
|
||||
return false;
|
||||
}
|
||||
p_f = f;
|
||||
p_owned = false;
|
||||
return is_open();
|
||||
}
|
||||
bool open(FILE *f);
|
||||
|
||||
bool is_open() const { return p_f != nullptr; }
|
||||
bool is_owned() const { return p_owned; }
|
||||
|
||||
void close() {
|
||||
if (p_f && p_owned) {
|
||||
fclose(p_f);
|
||||
}
|
||||
p_f = nullptr;
|
||||
p_owned = false;
|
||||
}
|
||||
void close();
|
||||
bool end() const;
|
||||
|
||||
bool end() const {
|
||||
return feof(p_f) != 0;
|
||||
}
|
||||
void seek(stream_off_t pos, stream_seek whence = stream_seek::SET);
|
||||
|
||||
void seek(stream_off_t pos, stream_seek whence = stream_seek::SET) {
|
||||
#ifndef OSTD_PLATFORM_WIN32
|
||||
if (fseeko(p_f, pos, int(whence)))
|
||||
#else
|
||||
if (_fseeki64(p_f, pos, int(whence)))
|
||||
#endif
|
||||
{
|
||||
throw stream_error{errno, std::generic_category()};
|
||||
}
|
||||
}
|
||||
stream_off_t tell() const;
|
||||
|
||||
stream_off_t tell() const {
|
||||
#ifndef OSTD_PLATFORM_WIN32
|
||||
auto ret = ftello(p_f);
|
||||
#else
|
||||
auto ret = _ftelli64(p_f);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
throw stream_error{errno, std::generic_category()};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void flush();
|
||||
|
||||
void flush() {
|
||||
if (fflush(p_f)) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
void read_bytes(void *buf, size_t count);
|
||||
void write_bytes(void const *buf, size_t count);
|
||||
|
||||
void read_bytes(void *buf, size_t count) {
|
||||
if (fread(buf, 1, count, p_f) != count) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
||||
void write_bytes(void const *buf, size_t count) {
|
||||
if (fwrite(buf, 1, count, p_f) != count) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
||||
int get_char() {
|
||||
int ret = fgetc(p_f);
|
||||
if (ret == EOF) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void put_char(int c) {
|
||||
if (fputc(c, p_f) == EOF) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
int get_char();
|
||||
void put_char(int c);
|
||||
|
||||
void swap(file_stream &s) {
|
||||
using std::swap;
|
||||
|
@ -157,7 +73,7 @@ struct file_stream: stream {
|
|||
swap(p_owned, s.p_owned);
|
||||
}
|
||||
|
||||
FILE *get_file() { return p_f; }
|
||||
FILE *get_file() const { return p_f; }
|
||||
|
||||
private:
|
||||
FILE *p_f;
|
||||
|
@ -168,9 +84,9 @@ inline void swap(file_stream &a, file_stream &b) {
|
|||
a.swap(b);
|
||||
}
|
||||
|
||||
static file_stream cin{stdin};
|
||||
static file_stream cout{stdout};
|
||||
static file_stream cerr{stderr};
|
||||
OSTD_EXPORT extern file_stream cin;
|
||||
OSTD_EXPORT extern file_stream cout;
|
||||
OSTD_EXPORT extern file_stream cerr;
|
||||
|
||||
/* no need to call anything from file_stream, prefer simple calls... */
|
||||
|
||||
|
@ -184,7 +100,7 @@ namespace detail {
|
|||
|
||||
stdout_range() {}
|
||||
void put(char c) {
|
||||
if (putchar(c) == EOF) {
|
||||
if (std::putchar(c) == EOF) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +112,7 @@ namespace detail {
|
|||
is_contiguous_range<R> &&
|
||||
std::is_same_v<std::remove_const_t<range_value_t<R>>, char>
|
||||
) {
|
||||
if (fwrite(range.data(), 1, range.size(), stdout) != range.size()) {
|
||||
if (std::fwrite(range.data(), 1, range.size(), stdout) != range.size()) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
} else {
|
||||
|
@ -216,7 +132,7 @@ inline void write(A const &...args) {
|
|||
template<typename ...A>
|
||||
inline void writeln(A const &...args) {
|
||||
write(args...);
|
||||
if (putchar('\n') == EOF) {
|
||||
if (std::putchar('\n') == EOF) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
@ -230,7 +146,7 @@ inline void writef(string_range fmt, A const &...args) {
|
|||
template<typename ...A>
|
||||
inline void writefln(string_range fmt, A const &...args) {
|
||||
writef(fmt, args...);
|
||||
if (putchar('\n') == EOF) {
|
||||
if (std::putchar('\n') == EOF) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,16 @@
|
|||
#ifndef OSTD_STREAM_HH
|
||||
#define OSTD_STREAM_HH
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <cstdlib>
|
||||
#include <type_traits>
|
||||
#include <locale>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <system_error>
|
||||
|
||||
#ifndef OSTD_PLATFORM_WIN32
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "ostd/platform.hh"
|
||||
#include "ostd/types.hh"
|
||||
|
|
97
src/filesystem.cc
Normal file
97
src/filesystem.cc
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* Filesystem implementation bits.
|
||||
*
|
||||
* This file is part of OctaSTD. See COPYING.md for futher information.
|
||||
*/
|
||||
|
||||
#include "ostd/filesystem.hh"
|
||||
#include "ostd/io.hh"
|
||||
|
||||
namespace ostd {
|
||||
|
||||
#ifdef OSTD_PLATFORM_WIN32
|
||||
static inline time_t filetime_to_time_t(FILETIME const &ft) {
|
||||
ULARGE_INTEGER ul;
|
||||
ul.LowPart = ft.dwLowDateTime;
|
||||
ul.HighPart = ft.dwHighDateTime;
|
||||
return static_cast<time_t>((ul.QuadPart / 10000000ULL) - 11644473600ULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
void file_info::init_from_str(string_range path) {
|
||||
/* TODO: implement a version that will follow symbolic links */
|
||||
p_path = path;
|
||||
#ifdef OSTD_PLATFORM_WIN32
|
||||
WIN32_FILE_ATTRIBUTE_DATA attr;
|
||||
if (!GetFileAttributesEx(p_path.data(), GetFileExInfoStandard, &attr) ||
|
||||
attr.dwFileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
#else
|
||||
struct stat st;
|
||||
if (lstat(p_path.data(), &st) < 0)
|
||||
#endif
|
||||
{
|
||||
p_slash = p_dot = std::string::npos;
|
||||
p_type = file_type::UNKNOWN;
|
||||
p_path.clear();
|
||||
p_atime = p_mtime = p_ctime = 0;
|
||||
return;
|
||||
}
|
||||
string_range r = p_path;
|
||||
|
||||
string_range found = find_last(r, PATH_SEPARATOR);
|
||||
if (found.empty()) {
|
||||
p_slash = std::string::npos;
|
||||
} else {
|
||||
p_slash = r.distance_front(found);
|
||||
}
|
||||
|
||||
found = find(filename(), '.');
|
||||
if (found.empty()) {
|
||||
p_dot = std::string::npos;
|
||||
} else {
|
||||
p_dot = r.distance_front(found);
|
||||
}
|
||||
|
||||
#ifdef OSTD_PLATFORM_WIN32
|
||||
if (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
p_type = file_type::DIRECTORY;
|
||||
} else if (attr.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
p_type = file_type::SYMLINK;
|
||||
} else if (attr.dwFileAttributes & (
|
||||
FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_COMPRESSED |
|
||||
FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL |
|
||||
FILE_ATTRIBUTE_SPARSE_FILE | FILE_ATTRIBUTE_TEMPORARY
|
||||
)) {
|
||||
p_type = file_type::REGULAR;
|
||||
} else {
|
||||
p_type = file_type::UNKNOWN;
|
||||
}
|
||||
|
||||
p_atime = detail::filetime_to_time_t(attr.ftLastAccessTime);
|
||||
p_mtime = detail::filetime_to_time_t(attr.ftLastWriteTime);
|
||||
p_ctime = detail::filetime_to_time_t(attr.ftCreationTime);
|
||||
#else
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
p_type = file_type::REGULAR;
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
p_type = file_type::DIRECTORY;
|
||||
} else if (S_ISCHR(st.st_mode)) {
|
||||
p_type = file_type::CHARACTER;
|
||||
} else if (S_ISBLK(st.st_mode)) {
|
||||
p_type = file_type::BLOCK;
|
||||
} else if (S_ISFIFO(st.st_mode)) {
|
||||
p_type = file_type::FIFO;
|
||||
} else if (S_ISLNK(st.st_mode)) {
|
||||
p_type = file_type::SYMLINK;
|
||||
} else if (S_ISSOCK(st.st_mode)) {
|
||||
p_type = file_type::SOCKET;
|
||||
} else {
|
||||
p_type = file_type::UNKNOWN;
|
||||
}
|
||||
|
||||
p_atime = st.st_atime;
|
||||
p_mtime = st.st_mtime;
|
||||
p_ctime = st.st_ctime;
|
||||
#endif
|
||||
}
|
||||
|
||||
} /* namespace ostd */
|
117
src/io.cc
Normal file
117
src/io.cc
Normal file
|
@ -0,0 +1,117 @@
|
|||
/* I/O streams implementation bits.
|
||||
*
|
||||
* This file is part of OctaSTD. See COPYING.md for futher information.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cerrno>
|
||||
|
||||
#include "ostd/io.hh"
|
||||
|
||||
namespace ostd {
|
||||
|
||||
static char const *filemodes[] = {
|
||||
"rb", "wb", "ab", "rb+", "wb+", "ab+"
|
||||
};
|
||||
|
||||
bool file_stream::open(string_range path, stream_mode mode) {
|
||||
if (p_f || (path.size() > FILENAME_MAX)) {
|
||||
return false;
|
||||
}
|
||||
char buf[FILENAME_MAX + 1];
|
||||
std::memcpy(buf, &path[0], path.size());
|
||||
buf[path.size()] = '\0';
|
||||
p_owned = false;
|
||||
#ifndef OSTD_PLATFORM_WIN32
|
||||
p_f = std::fopen(buf, filemodes[size_t(mode)]);
|
||||
#else
|
||||
if (fopen_s(&p_f, buf, filemodes[size_t(mode)]) != 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
p_owned = !!p_f;
|
||||
return is_open();
|
||||
}
|
||||
|
||||
bool file_stream::open(FILE *f) {
|
||||
if (p_f) {
|
||||
return false;
|
||||
}
|
||||
p_f = f;
|
||||
p_owned = false;
|
||||
return is_open();
|
||||
}
|
||||
|
||||
void file_stream::close() {
|
||||
if (p_f && p_owned) {
|
||||
std::fclose(p_f);
|
||||
}
|
||||
p_f = nullptr;
|
||||
p_owned = false;
|
||||
}
|
||||
|
||||
bool file_stream::end() const {
|
||||
return std::feof(p_f) != 0;
|
||||
}
|
||||
|
||||
void file_stream::seek(stream_off_t pos, stream_seek whence) {
|
||||
#ifndef OSTD_PLATFORM_WIN32
|
||||
if (fseeko(p_f, pos, int(whence)))
|
||||
#else
|
||||
if (_fseeki64(p_f, pos, int(whence)))
|
||||
#endif
|
||||
{
|
||||
throw stream_error{errno, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
||||
stream_off_t file_stream::tell() const {
|
||||
#ifndef OSTD_PLATFORM_WIN32
|
||||
auto ret = ftello(p_f);
|
||||
#else
|
||||
auto ret = _ftelli64(p_f);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
throw stream_error{errno, std::generic_category()};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void file_stream::flush() {
|
||||
if (std::fflush(p_f)) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
||||
void file_stream::read_bytes(void *buf, size_t count) {
|
||||
if (std::fread(buf, 1, count, p_f) != count) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
||||
void file_stream::write_bytes(void const *buf, size_t count) {
|
||||
if (std::fwrite(buf, 1, count, p_f) != count) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
||||
int file_stream::get_char() {
|
||||
int ret = std::fgetc(p_f);
|
||||
if (ret == EOF) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void file_stream::put_char(int c) {
|
||||
if (std::fputc(c, p_f) == EOF) {
|
||||
throw stream_error{EIO, std::generic_category()};
|
||||
}
|
||||
}
|
||||
|
||||
OSTD_EXPORT file_stream cin{stdin};
|
||||
OSTD_EXPORT file_stream cout{stdout};
|
||||
OSTD_EXPORT file_stream cerr{stderr};
|
||||
|
||||
} /* namespace ostd */
|
Loading…
Reference in a new issue