Fix buffer stomping; retool Makefile.
The Makefile is now useful for building ke(1) to aid in more rapid development. This works because ke doesn't (yet) need any special non-system libraries.
This commit is contained in:
75
Buffer.cc
75
Buffer.cc
@@ -23,6 +23,7 @@
|
||||
|
||||
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <random>
|
||||
@@ -31,6 +32,9 @@
|
||||
#include "Buffer.h"
|
||||
|
||||
|
||||
static constexpr auto statusOK = Buffer::FileStatus::FileStatusOK;
|
||||
|
||||
|
||||
static std::string
|
||||
anonymousName()
|
||||
{
|
||||
@@ -45,7 +49,7 @@ anonymousName()
|
||||
|
||||
|
||||
Buffer::Buffer()
|
||||
: dirty(false), name(anonymousName())
|
||||
: dirty(false), name(anonymousName()), status(statusOK)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -61,9 +65,14 @@ Buffer::Buffer(std::filesystem::path fPath)
|
||||
: dirty(false), path(OptString(fPath.string()))
|
||||
{
|
||||
this->name = fPath.filename().string();
|
||||
this->Cursor() = Cursor();
|
||||
|
||||
this->cursor = Cursor();
|
||||
this->file = OptFile(fPath.string());
|
||||
if (this->Exists()) {
|
||||
std::cout << "file exists, refreshing\n";
|
||||
/// \todo Should I signal an error here, or is it
|
||||
/// okay for this to be a best-effort thing?
|
||||
this->status = this->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +115,7 @@ Buffer::Flush(OptString altPath)
|
||||
return Buffer::FileStatus::FileStatusInvalidPermissions;
|
||||
}
|
||||
|
||||
realFile.MarkReadOnly();
|
||||
return Buffer::FileStatus::FileStatusIOFailed;
|
||||
}
|
||||
|
||||
@@ -131,13 +141,17 @@ Buffer::Flush(OptString altPath)
|
||||
Buffer::FileStatus
|
||||
Buffer::Refresh()
|
||||
{
|
||||
/// We can't actually refresh a virtual buffer. Unlike flush,
|
||||
/// it doesn't make sense to Refresh from an alternate file.
|
||||
if (this->IsVirtual()) {
|
||||
std::cerr << "[!] virtual file, bailing\n";
|
||||
return Buffer::FileStatus::FileStatusVirtual;
|
||||
}
|
||||
|
||||
auto realFile = this->file.value();
|
||||
auto handle = realFile.Refresh();
|
||||
if (!handle) {
|
||||
std::cerr << "[!] file doesn't exist\n";
|
||||
return FileStatus::FileStatusNonExistent;
|
||||
}
|
||||
|
||||
@@ -147,8 +161,11 @@ Buffer::Refresh()
|
||||
|
||||
/// \todo Moral quandary: if the file disappears from disk, we
|
||||
/// probably want to know that, but maybe clearing the
|
||||
/// contents first isn't the right move.
|
||||
/// contents first isn't the right move. Maybe mark the
|
||||
/// file as ReadOnly?
|
||||
if (!realHandle->good()) {
|
||||
std::cerr << "[!] handle isn't good";
|
||||
realHandle->close();
|
||||
delete realHandle;
|
||||
return FileStatus::FileStatusIOFailed;
|
||||
}
|
||||
@@ -167,6 +184,7 @@ Buffer::Refresh()
|
||||
status = FileStatus::FileStatusIOFailed;
|
||||
}
|
||||
realHandle->close();
|
||||
delete realHandle;
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -246,3 +264,52 @@ Buffer::FileStatusToString(Buffer::FileStatus status)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Buffer::Exists()
|
||||
{
|
||||
if (!this->file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->file.value().Exists();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Buffer::PrintBufferStatus(std::ostream &os)
|
||||
{
|
||||
os << "buffer:<" << this->name << ">[";
|
||||
if (this->IsVirtual()) {
|
||||
os << "virt]";
|
||||
} else {
|
||||
os << "file:";
|
||||
if (this->Exists()) {
|
||||
os << "real";
|
||||
} else {
|
||||
os << "new";
|
||||
}
|
||||
os << ":";
|
||||
auto &realFile = this->file.value();
|
||||
if (realFile.IsReadWriteable()) {
|
||||
os << "rw";
|
||||
} else if (realFile.IsReadable()) {
|
||||
os << "r-";
|
||||
} else if (realFile.IsWriteable()) {
|
||||
os << "-w";
|
||||
} else {
|
||||
os << " ";
|
||||
}
|
||||
|
||||
if (realFile.IsReadOnly()) {
|
||||
os << "@";
|
||||
} else {
|
||||
os << " ";
|
||||
}
|
||||
|
||||
os << ":" << this->Size() << "
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user