support crlf line ending when reading and writing buffers

This commit is contained in:
Maxime Coste 2012-08-10 14:24:13 +02:00
parent 54b599c1a7
commit d81a100a85
2 changed files with 74 additions and 18 deletions

View File

@ -75,30 +75,63 @@ String read_file(const String& filename)
Buffer* create_buffer_from_file(const String& filename) Buffer* create_buffer_from_file(const String& filename)
{ {
String content = read_file(filename);
if (Buffer* buffer = BufferManager::instance().get_buffer(filename)) if (Buffer* buffer = BufferManager::instance().get_buffer(filename))
delete buffer; delete buffer;
return new Buffer(filename, Buffer::Type::File, content); Buffer* buffer = new Buffer(filename, Buffer::Type::File, "");
int fd = open(filename.c_str(), O_RDONLY);
if (fd == -1)
{
if (errno == ENOENT)
throw file_not_found(filename);
throw file_access_error(filename, strerror(errno));
} }
void write_buffer_to_file(const Buffer& buffer, const String& filename) String content;
char buf[256];
bool crlf = false;
while (true)
{ {
int fd = open(filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644); ssize_t size = read(fd, buf, 256);
if (fd == -1) if (size == -1 or size == 0)
throw file_access_error(filename, strerror(errno)); break;
for (size_t i = 0; i < buffer.line_count(); ++i) ssize_t start = 0;
for (ssize_t pos = 0; pos < size+1; ++pos)
{
if (buf[pos] == '\r' or pos == size)
{
if (buf[pos] == '\r')
crlf = true;
buffer->modify(Modification::make_insert(buffer->end(), String(buf+start, buf+pos)));
start = pos+1;
}
}
}
close(fd);
if (crlf)
buffer->option_manager().set_option("eolformat", Option("crlf"));
else
buffer->option_manager().set_option("eolformat", Option("lf"));
// it never happened, buffer always was like that
buffer->reset_undo_data();
return buffer;
}
static void write(int fd, const memoryview<char>& data, const String& filename)
{ {
const String& content = buffer.line_content(i);
memoryview<char> data = content.data();
const char* ptr = data.pointer(); const char* ptr = data.pointer();
ssize_t count = data.size(); ssize_t count = data.size();
while (count) while (count)
{ {
ssize_t written = write(fd, ptr, count); ssize_t written = ::write(fd, ptr, count);
ptr += written; ptr += written;
count -= written; count -= written;
@ -106,6 +139,28 @@ void write_buffer_to_file(const Buffer& buffer, const String& filename)
throw file_access_error(filename, strerror(errno)); throw file_access_error(filename, strerror(errno));
} }
} }
void write_buffer_to_file(const Buffer& buffer, const String& filename)
{
String eolformat = buffer.option_manager()["eolformat"].as_string();
if (eolformat == "crlf")
eolformat = "\r\n";
else
eolformat = "\n";
auto eoldata = eolformat.data();
int fd = open(filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd == -1)
throw file_access_error(filename, strerror(errno));
for (size_t i = 0; i < buffer.line_count(); ++i)
{
// end of lines are written according to eolformat but always
// stored as \n
memoryview<char> linedata = buffer.line_content(i).data();
write(fd, linedata.subrange(0, linedata.size()-1), filename);
write(fd, eoldata, filename);
}
close(fd); close(fd);
} }

View File

@ -94,6 +94,7 @@ GlobalOptionManager::GlobalOptionManager()
: OptionManager() : OptionManager()
{ {
set_option("tabstop", Option(8)); set_option("tabstop", Option(8));
set_option("eolformat", Option("lf"));
} }
} }