mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Refactoring, adding printf / printfn to all streams.
This commit is contained in:
committed by
Christoffer Lerno
parent
9a6d83f526
commit
4c081f59ff
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
114
lib/std/io/io.c3
114
lib/std/io/io.c3
@@ -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
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user