Refactoring, adding printf / printfn to all streams.

This commit is contained in:
Christoffer Lerno
2023-09-03 02:20:33 +02:00
committed by Christoffer Lerno
parent 9a6d83f526
commit 4c081f59ff
19 changed files with 2842 additions and 715 deletions

View File

@@ -349,7 +349,7 @@ fn DString new_join(String[] s, String joiner, Allocator* using = mem::heap())
return res;
}
fn void! out_string_append_fn(char c, void* data) @private
fn void! out_string_append_fn(void* data, char c) @private
{
DString* s = data;
s.append_char(c);

View File

@@ -1,3 +1,12 @@
module std::io;
import libc;
struct File
{
inline Stream stream;
CFile file;
}
module std::io::file;
import libc;
@@ -16,6 +25,16 @@ fn File from_handle(CFile file)
return { .stream.fns = &FILESTREAM_INTERFACE, .file = file };
}
fn bool is_file(String path)
{
return os::native_is_file(path);
}
fn usz! get_size(String path)
{
return os::native_file_size(path);
}
fn void! delete(String filename) => os::native_remove(filename) @inline;
@@ -112,25 +131,6 @@ fn usz! File.write(&self, char[] buffer)
return os::native_fwrite(self.file, buffer);
}
/**
* @require self.file `File must be initialized`
*/
fn usz! File.printn(&self, String string = "")
{
usz len = self.print(string)!;
if (!libc::putc('\n', self.file)) return IoError.UNKNOWN_ERROR?;
return len + 1;
}
/**
* @require self.file `File must be initialized`
*/
fn usz! File.print(&self, String string)
{
usz len = string.len;
if (len != self.write((char[])string)!) return IoError.UNKNOWN_ERROR?;
return len;
}
fn char! File.read_byte(&self)
{
@@ -142,7 +142,7 @@ fn char! File.read_byte(&self)
/**
* @require self.file `File must be initialized`
*/
fn void File.flush(&self)
fn void! File.flush(&self)
{
libc::fflush(self.file);
}

View File

@@ -4,6 +4,9 @@ import libc;
const int PRINTF_NTOA_BUFFER_SIZE = 256;
fn String any.to_string(void* value, Allocator *using) @interface;
fn usz! any.to_format(void* value, Formatter* formatter) @interface;
fault PrintFault
{
BUFFER_EXCEEDED,
@@ -21,53 +24,10 @@ fault FormattingFault
INVALID_FORMAT_TYPE,
}
def OutputFn = fn void!(char c, void* buffer);
def OutputFn = fn void!(void* buffer, char c);
def FloatType = double;
fn String any.to_string(void* value, Allocator *using) @interface;
fn usz! any.to_format(void* value, Formatter* formatter) @interface;
fn usz! printf(String format, args...) @maydiscard
{
Formatter formatter;
formatter.init(&out_putchar_fn);
return formatter.vprintf(format, args);
}
fn usz! printfn(String format, args...) @maydiscard
{
Formatter formatter;
formatter.init(&out_putchar_fn);
usz len = formatter.vprintf(format, args)!;
putchar('\n');
return len + 1;
}
fn char[]! bprintf(char[] buffer, String format, args...) @maydiscard
{
Formatter formatter;
BufferData data = { .buffer = buffer };
formatter.init(&out_buffer_fn, &data);
usz size = formatter.vprintf(format, args)!;
return buffer[:data.written];
}
fn usz! File.printf(self, String format, args...) @maydiscard
{
Formatter formatter;
formatter.init(&out_fputchar_fn, &self);
return formatter.vprintf(format, args)!;
}
fn usz! File.printfn(self, String format, args...) @maydiscard
{
Formatter formatter;
formatter.init(&out_fputchar_fn, &self);
usz len = formatter.vprintf(format, args)!;
self.write_byte('\n')!;
self.flush();
return len + 1;
}
fn usz! Formatter.printf(&self, String format, args...)
{
@@ -105,7 +65,7 @@ fn void Formatter.init(&self, OutputFn out_fn, void* data = null)
fn usz! Formatter.out(&self, char c) @private
{
self.out_fn(c, self.data)!;
self.out_fn(self.data, c)!;
return 1;
}
@@ -261,33 +221,11 @@ fn usz! Formatter.out_str(&self, any arg) @private
fn void! out_buffer_fn(char c, void *data) @private
{
BufferData *buffer_data = data;
if (buffer_data.written >= buffer_data.buffer.len) return PrintFault.BUFFER_EXCEEDED?;
buffer_data.buffer[buffer_data.written++] = c;
}
fn void! out_null_fn(char c @unused, void* data @unused) @private
fn void! out_null_fn(void* data @unused, char c @unused) @private
{
}
fn void! out_putchar_fn(char c, void* data @unused) @private
{
libc::putchar(c);
}
fn void! out_fputchar_fn(char c, void* data) @private
{
File* f = data;
f.write_byte(c)!;
}
struct BufferData @private
{
char[] buffer;
usz written;
}
fn usz! Formatter.vprintf(&self, String format, any[] anys)

View File

@@ -4,12 +4,6 @@
module std::io;
import libc;
struct File
{
inline Stream stream;
CFile file;
}
enum Seek
{
SET,
@@ -52,42 +46,60 @@ fault IoError
macro void print(x)
{
var $Type = $typeof(x);
$switch ($Type)
$case String:
(void)stdout().print(x);
$case ZString:
(void)stdout().print(x.as_str());
$case DString:
(void)stdout().print(x.as_str());
$default:
$if @convertible(x, String):
(void)stdout().print((String)x);
$else
(void)stdout().printf("%s", x);
$endif
$endswitch
(void)print_gen(stdout(), x);
}
macro void printn(x = "")
{
var $Type = $typeof(x);
$switch ($Type)
$case String:
(void)stdout().printn(x);
$case ZString:
(void)stdout().printn(x.as_str());
$case DString:
(void)stdout().printn(x.as_str());
$default:
$if @convertible(x, String):
(void)stdout().printn((String)x);
$else
(void)stdout().printfn("%s", x);
$endif
$endswitch
(void)printn_gen(stdout(), x);
}
fn void! out_putchar_fn(void* data @unused, char c) @private
{
libc::putchar(c);
}
fn usz! printf(String format, args...) @maydiscard
{
Formatter formatter;
formatter.init(&out_putchar_fn);
return formatter.vprintf(format, args);
}
fn usz! printfn(String format, args...) @maydiscard
{
Formatter formatter;
formatter.init(&out_putchar_fn);
usz len = formatter.vprintf(format, args)!;
putchar('\n');
return len + 1;
}
fn char[]! bprintf(char[] buffer, String format, args...) @maydiscard
{
Formatter formatter;
BufferData data = { .buffer = buffer };
formatter.init(&out_buffer_fn, &data);
usz size = formatter.vprintf(format, args)!;
return buffer[:data.written];
}
fn void! out_buffer_fn(void *data, char c) @private
{
BufferData *buffer_data = data;
if (buffer_data.written >= buffer_data.buffer.len) return PrintFault.BUFFER_EXCEEDED?;
buffer_data.buffer[buffer_data.written++] = c;
}
struct BufferData @private
{
char[] buffer;
usz written;
}
module std::io @if (env::LIBC);
import libc;
@@ -142,33 +154,3 @@ fn File stdin()
{
return stdin_file;
}
/*
error FileError
{
ulong errno;
}
fn FileError errorFromErrno()
{
return FileError { };
}
pubic fn void! File.clearerr(File *file) @inline
{
clearerr(file->file);
}
fn void File.error(File *file) @inline
{
int err = ferror
}
*/

View File

@@ -1,14 +0,0 @@
module std::io::file;
import libc;
fn bool is_file(String path)
{
return os::native_is_file(path);
}
fn usz! get_size(String path)
{
return os::native_file_size(path);
}

View File

@@ -120,6 +120,82 @@ fn usz! Stream.read(&self, char[] buffer)
return IoError.UNSUPPORTED_OPERATION?;
}
macro usz! Stream.print(&self, x) @maydiscard
{
return print_gen(self, x);
}
macro usz! print_gen(self, x)
{
var $Type = $typeof(x);
$switch ($Type)
$case String:
return self.write(x);
$case ZString:
return self.write(x.as_str());
$case DString:
return self.write(x.as_str());
$default:
$if @convertible(x, String):
return self.write((String)x);
$else
return printf("%s", x);
$endif
$endswitch
}
macro usz! printn_gen(self, x)
{
usz len = print_gen(self, x)!;
self.write_byte('\n')!;
self.flush()!;
return len + 1;
}
macro usz! Stream.printn(&self, x) @maydiscard
{
return printn_gen(self, x);
}
fn usz! Stream.printf(&self, String format, args...) @maydiscard
{
Formatter formatter;
if (WriteByteStreamFn func_byte = self.fns.write_byte_fn)
{
formatter.init((OutputFn)func_byte, self);
}
else if (WriteStreamFn func = self.fns.write_fn)
{
formatter.init((OutputFn)&Stream.write_byte, self);
}
else
{
return IoError.UNSUPPORTED_OPERATION?;
}
return formatter.vprintf(format, args)!;
}
fn usz! Stream.printfn(&self, String format, args...) @maydiscard @inline
{
Formatter formatter;
if (WriteByteStreamFn func_byte = self.fns.write_byte_fn)
{
formatter.init((OutputFn)func_byte, self);
}
else if (WriteStreamFn func = self.fns.write_fn)
{
formatter.init((OutputFn)&Stream.write_byte, self);
}
else
{
return IoError.UNSUPPORTED_OPERATION?;
}
usz len = formatter.vprintf(format, args)!;
self.write_byte('\n')!;
self.flush()!;
return len + 1;
}
fn char! Stream.read_byte(&self) @inline
{
if (ReadByteStreamFn func = self.fns.read_byte_fn) return func(self);