mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix on rethrow + macros.
This commit is contained in:
@@ -375,7 +375,7 @@ fn void DString.reserve(DString* str, usz addition)
|
||||
*str = (DString)realloc(data, StringData.sizeof + new_capacity, .using = data.allocator);
|
||||
}
|
||||
|
||||
fn usz! DString.read_from_stream(DString* string, Stream* reader)
|
||||
fn usz! DString.read_from_stream(DString* string, Stream reader)
|
||||
{
|
||||
if (reader.supports_available())
|
||||
{
|
||||
|
||||
65
lib/std/encoding/csv.c3
Normal file
65
lib/std/encoding/csv.c3
Normal file
@@ -0,0 +1,65 @@
|
||||
module std::encoding::csv;
|
||||
import std::io;
|
||||
|
||||
struct CsvReader
|
||||
{
|
||||
Stream stream;
|
||||
String separator;
|
||||
}
|
||||
|
||||
fn void CsvReader.init_file(CsvReader* csv, File* file, String separator = ",")
|
||||
{
|
||||
csv.stream = file.as_stream();
|
||||
csv.separator = separator;
|
||||
}
|
||||
|
||||
fn void CsvReader.init(CsvReader* csv, Stream stream, String separator = ",")
|
||||
{
|
||||
csv.stream = stream;
|
||||
csv.separator = separator;
|
||||
}
|
||||
|
||||
fn String[]! CsvReader.read_row(CsvReader csv, Allocator* using = mem::heap())
|
||||
{
|
||||
@stack_mem(512; Allocator* mem)
|
||||
{
|
||||
return csv.stream.readline(mem).split(csv.separator, .using = using);
|
||||
};
|
||||
}
|
||||
|
||||
fn String[]! CsvReader.tread_row(CsvReader csv)
|
||||
{
|
||||
return csv.read_row(mem::temp()) @inline;
|
||||
}
|
||||
|
||||
fn void! CsvReader.skip_row(CsvReader csv) @maydiscard
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
csv.stream.readline(mem::temp())!;
|
||||
};
|
||||
}
|
||||
|
||||
macro CsvReader.@each_row(CsvReader csv, int rows = int.max; @body(String[] row))
|
||||
{
|
||||
Stream stream = csv.stream;
|
||||
String sep = csv.separator;
|
||||
while (rows--)
|
||||
{
|
||||
@stack_mem(512; Allocator* mem)
|
||||
{
|
||||
String[] parts;
|
||||
@pool()
|
||||
{
|
||||
String! s = stream.readline(mem::temp());
|
||||
if (catch err = s)
|
||||
{
|
||||
if (err == IoError.EOF) return;
|
||||
return err?;
|
||||
}
|
||||
parts = s.split(sep, .using = mem);
|
||||
};
|
||||
@body(parts);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
module std::io;
|
||||
|
||||
def CloseStreamFn = fn void!(Stream*);
|
||||
def FlushStreamFn = fn void!(Stream*);
|
||||
def SeekStreamFn = fn usz!(Stream*, isz offset, Seek seek);
|
||||
def LenStreamFn = fn usz(Stream*);
|
||||
def AvailableStreamFn = fn usz(Stream*);
|
||||
def ReadStreamFn = fn usz!(Stream*, char[] bytes);
|
||||
def ReadFromStreamFn = fn usz!(Stream*, Stream*);
|
||||
def ReadByteStreamFn = fn char!(Stream*);
|
||||
def PushbackByteStreamFn = fn void!(Stream*);
|
||||
def WriteStreamFn = fn usz!(Stream*, char[] bytes);
|
||||
def WriteToStreamFn = fn usz!(Stream*, Stream* out);
|
||||
def WriteByteStreamFn = fn void!(Stream*, char c);
|
||||
def DestroyStreamFn = fn void!(Stream*);
|
||||
def CloseStreamFn = fn void!(Stream);
|
||||
def FlushStreamFn = fn void!(Stream);
|
||||
def SeekStreamFn = fn usz!(Stream, isz offset, Seek seek);
|
||||
def LenStreamFn = fn usz(Stream);
|
||||
def AvailableStreamFn = fn usz(Stream);
|
||||
def ReadStreamFn = fn usz!(Stream, char[] bytes);
|
||||
def ReadFromStreamFn = fn usz!(Stream, Stream);
|
||||
def ReadByteStreamFn = fn char!(Stream);
|
||||
def PushbackByteStreamFn = fn void!(Stream);
|
||||
def WriteStreamFn = fn usz!(Stream, char[] bytes);
|
||||
def WriteToStreamFn = fn usz!(Stream, Stream out);
|
||||
def WriteByteStreamFn = fn void!(Stream, char c);
|
||||
def DestroyStreamFn = fn void!(Stream);
|
||||
|
||||
struct StreamInterface
|
||||
{
|
||||
@@ -37,33 +37,33 @@ struct Stream
|
||||
void* data;
|
||||
}
|
||||
|
||||
fn bool Stream.supports_seek(Stream* s) @inline => (bool)s.fns.seek_fn;
|
||||
fn bool Stream.supports_available(Stream* s) @inline => s.fns.available_fn || s.fns.seek_fn;
|
||||
fn bool Stream.supports_len(Stream* s) @inline => s.fns.len_fn || s.fns.seek_fn;
|
||||
fn bool Stream.supports_read(Stream* s) @inline => s.fns.read_fn || s.fns.read_byte_fn;
|
||||
fn bool Stream.supports_read_from(Stream* s) @inline => (bool)s.fns.read_stream_fn;
|
||||
fn bool Stream.supports_write_to(Stream* s) @inline => (bool)s.fns.write_stream_fn;
|
||||
fn bool Stream.supports_pushback_byte(Stream* s) @inline => s.fns.pushback_byte_fn || s.fns.seek_fn;
|
||||
fn bool Stream.supports_write(Stream* s) @inline => s.fns.write_fn || s.fns.write_byte_fn;
|
||||
fn bool Stream.supports_seek(Stream s) @inline => (bool)s.fns.seek_fn;
|
||||
fn bool Stream.supports_available(Stream s) @inline => s.fns.available_fn || s.fns.seek_fn;
|
||||
fn bool Stream.supports_len(Stream s) @inline => s.fns.len_fn || s.fns.seek_fn;
|
||||
fn bool Stream.supports_read(Stream s) @inline => s.fns.read_fn || s.fns.read_byte_fn;
|
||||
fn bool Stream.supports_read_from(Stream s) @inline => (bool)s.fns.read_stream_fn;
|
||||
fn bool Stream.supports_write_to(Stream s) @inline => (bool)s.fns.write_stream_fn;
|
||||
fn bool Stream.supports_pushback_byte(Stream s) @inline => s.fns.pushback_byte_fn || s.fns.seek_fn;
|
||||
fn bool Stream.supports_write(Stream s) @inline => s.fns.write_fn || s.fns.write_byte_fn;
|
||||
|
||||
fn void! Stream.destroy(Stream* s) @inline @maydiscard
|
||||
fn void! Stream.destroy(Stream s) @inline @maydiscard
|
||||
{
|
||||
if (s.fns.destroy_fn) return s.fns.destroy_fn(s);
|
||||
return s.close();
|
||||
}
|
||||
|
||||
fn void! Stream.close(Stream* s) @inline @maydiscard
|
||||
fn void! Stream.close(Stream s) @inline @maydiscard
|
||||
{
|
||||
if (CloseStreamFn func = s.fns.close_fn) return func(s);
|
||||
}
|
||||
|
||||
fn usz! Stream.seek(Stream* s, isz offset, Seek seek) @inline
|
||||
fn usz! Stream.seek(Stream s, isz offset, Seek seek) @inline
|
||||
{
|
||||
if (SeekStreamFn func = s.fns.seek_fn) return func(s, offset, seek);
|
||||
return IoError.NOT_SEEKABLE?;
|
||||
}
|
||||
|
||||
fn usz! Stream.available(Stream* s) @inline
|
||||
fn usz! Stream.available(Stream s) @inline
|
||||
{
|
||||
if (AvailableStreamFn func = s.fns.available_fn) return func(s);
|
||||
if (SeekStreamFn func = s.fns.seek_fn)
|
||||
@@ -76,7 +76,7 @@ fn usz! Stream.available(Stream* s) @inline
|
||||
return IoError.NOT_SEEKABLE?;
|
||||
}
|
||||
|
||||
fn usz! Stream.read(Stream* s, char[] buffer)
|
||||
fn usz! Stream.read(Stream s, char[] buffer)
|
||||
{
|
||||
if (ReadStreamFn func = s.fns.read_fn) return func(s, buffer);
|
||||
if (ReadByteStreamFn func = s.fns.read_byte_fn)
|
||||
@@ -97,13 +97,40 @@ fn usz! Stream.read(Stream* s, char[] buffer)
|
||||
return IoError.UNSUPPORTED_OPERATION?;
|
||||
}
|
||||
|
||||
fn char! Stream.read_byte(Stream* s) @inline
|
||||
fn char! Stream.read_byte(Stream s) @inline
|
||||
{
|
||||
if (ReadByteStreamFn func = s.fns.read_byte_fn) return func(s);
|
||||
return IoError.UNSUPPORTED_OPERATION?;
|
||||
}
|
||||
|
||||
fn usz! Stream.write(Stream* s, char[] bytes) @inline
|
||||
fn String! Stream.readline(Stream s, Allocator* using = mem::heap())
|
||||
{
|
||||
ReadByteStreamFn func;
|
||||
if (func = s.fns.read_byte_fn, !func) return IoError.UNSUPPORTED_OPERATION?;
|
||||
bool read = false;
|
||||
char val = func(s)!;
|
||||
if (val == '\n') return "";
|
||||
@stack_mem(256 + 64; Allocator* mem)
|
||||
{
|
||||
DString str = dstring::new_with_capacity(256, .using = mem);
|
||||
if (val != '\r') str.append(val);
|
||||
while (1)
|
||||
{
|
||||
char! c = func(s);
|
||||
if (catch err = c)
|
||||
{
|
||||
if (err == IoError.EOF) break;
|
||||
return err?;
|
||||
}
|
||||
if (c == '\r') continue;
|
||||
if (c == '\n') break;
|
||||
str.append_char(c);
|
||||
}
|
||||
return str.copy_str(using);
|
||||
};
|
||||
}
|
||||
|
||||
fn usz! Stream.write(Stream s, char[] bytes) @inline
|
||||
{
|
||||
if (WriteStreamFn func = s.fns.write_fn) return func(s, bytes);
|
||||
if (WriteByteStreamFn func = s.fns.write_byte_fn)
|
||||
@@ -114,31 +141,31 @@ fn usz! Stream.write(Stream* s, char[] bytes) @inline
|
||||
return IoError.UNSUPPORTED_OPERATION?;
|
||||
}
|
||||
|
||||
fn void! Stream.write_byte(Stream* s, char b) @inline
|
||||
fn void! Stream.write_byte(Stream s, char b) @inline
|
||||
{
|
||||
if (WriteByteStreamFn func = s.fns.write_byte_fn) return func(s, b);
|
||||
return IoError.UNSUPPORTED_OPERATION?;
|
||||
}
|
||||
|
||||
fn usz! Stream.write_to(Stream* s, Stream* to) @inline
|
||||
fn usz! Stream.write_to(Stream s, Stream to) @inline
|
||||
{
|
||||
if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, to);
|
||||
return IoError.UNSUPPORTED_OPERATION?;
|
||||
}
|
||||
|
||||
fn usz! Stream.read_from(Stream* s, Stream* from) @inline
|
||||
fn usz! Stream.read_from(Stream s, Stream from) @inline
|
||||
{
|
||||
if (ReadFromStreamFn func = s.fns.read_stream_fn) return func(s, from);
|
||||
return IoError.UNSUPPORTED_OPERATION?;
|
||||
}
|
||||
|
||||
fn void! Stream.flush(Stream* s) @inline @maydiscard
|
||||
fn void! Stream.flush(Stream s) @inline @maydiscard
|
||||
{
|
||||
if (FlushStreamFn func = s.fns.flush_fn) return func(s);
|
||||
return IoError.UNSUPPORTED_OPERATION?;
|
||||
}
|
||||
|
||||
fn usz! Stream.len(Stream* s) @inline
|
||||
fn usz! Stream.len(Stream s) @inline
|
||||
{
|
||||
if (LenStreamFn func = s.fns.len_fn) return func(s);
|
||||
if (SeekStreamFn func = s.fns.seek_fn)
|
||||
@@ -151,7 +178,7 @@ fn usz! Stream.len(Stream* s) @inline
|
||||
return IoError.NOT_SEEKABLE?;
|
||||
}
|
||||
|
||||
fn void! Stream.pushback_byte(Stream* s) @inline
|
||||
fn void! Stream.pushback_byte(Stream s) @inline
|
||||
{
|
||||
if (PushbackByteStreamFn func = s.fns.pushback_byte_fn) return func(s);
|
||||
if (SeekStreamFn func = s.fns.seek_fn)
|
||||
@@ -162,9 +189,9 @@ fn void! Stream.pushback_byte(Stream* s) @inline
|
||||
return IoError.UNSUPPORTED_OPERATION?;
|
||||
}
|
||||
|
||||
fn void! Stream.write_string(Stream* s, String str) @inline => (void)(s.write((char[])str)!);
|
||||
fn void! Stream.write_string(Stream s, String str) @inline => (void)(s.write((char[])str)!);
|
||||
|
||||
fn usz! Stream.copy_to(Stream* s, Stream* dst, char[] buffer = {})
|
||||
fn usz! Stream.copy_to(Stream s, Stream dst, char[] buffer = {})
|
||||
{
|
||||
if (buffer.len) return copy_through_buffer(s, dst, buffer);
|
||||
if (WriteToStreamFn func = s.fns.write_stream_fn) return func(s, dst);
|
||||
@@ -186,7 +213,7 @@ fn usz! Stream.copy_to(Stream* s, Stream* dst, char[] buffer = {})
|
||||
$endswitch
|
||||
}
|
||||
|
||||
macro usz! copy_through_buffer(Stream* s, Stream* dst, char[] buffer) @local
|
||||
macro usz! copy_through_buffer(Stream s, Stream dst, char[] buffer) @local
|
||||
{
|
||||
usz total_copied;
|
||||
while (true)
|
||||
|
||||
@@ -53,7 +53,7 @@ fn usz! ByteReader.seek(ByteReader* reader, isz offset, Seek seek)
|
||||
return new_index;
|
||||
}
|
||||
|
||||
fn usz! ByteReader.write_stream(ByteReader* reader, Stream* writer)
|
||||
fn usz! ByteReader.write_stream(ByteReader* reader, Stream writer)
|
||||
{
|
||||
if (reader.index >= reader.bytes.len) return 0;
|
||||
usz written = writer.write(reader.bytes[reader.index..])!;
|
||||
|
||||
@@ -75,9 +75,9 @@ fn void! ByteWriter.write_byte(ByteWriter* writer, char c)
|
||||
|
||||
/**
|
||||
* @param [&inout] writer
|
||||
* @param [&inout] reader
|
||||
* @param reader
|
||||
**/
|
||||
fn usz! ByteWriter.read_from(ByteWriter* writer, Stream* reader)
|
||||
fn usz! ByteWriter.read_from(ByteWriter* writer, Stream reader)
|
||||
{
|
||||
usz start_index = writer.index;
|
||||
if (reader.supports_available())
|
||||
|
||||
@@ -32,6 +32,7 @@ def spawn = posix_spawn;
|
||||
|
||||
extern fn CInt kill(Pid_t pid, CInt sig);
|
||||
extern fn Pid_t waitpid(Pid_t pid, CInt* stat_loc, int options);
|
||||
extern fn CInt raise(CInt sig);
|
||||
|
||||
macro CInt wEXITSTATUS(CInt status) => (status & 0xff00) >> 8;
|
||||
macro CInt wTERMSIG(CInt status) => status & 0x7f;
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
- `assert` may now take varargs for formatting.
|
||||
|
||||
### Stdlib changes
|
||||
- `csv` package.
|
||||
- Updated posix/win32 stdlib namespacing
|
||||
- `process` stdlib
|
||||
- Stdlib updates to string.
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.543"
|
||||
#define COMPILER_VERSION "0.4.544"
|
||||
@@ -17,9 +17,9 @@ fn void! bytestream()
|
||||
ws.write("helloworld")!;
|
||||
assert(w.as_str() == "helloworld");
|
||||
s.seek(0, SET)!;
|
||||
ws.read_from(&s)!;
|
||||
ws.read_from(s)!;
|
||||
s.seek(1, SET)!;
|
||||
s.write_to(&ws)!;
|
||||
s.write_to(ws)!;
|
||||
assert(w.as_str() == "helloworldabcbc");
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ fn void! bytewriter_read_from()
|
||||
|
||||
ByteWriter bw;
|
||||
bw.tinit();
|
||||
bw.read_from(&s)!;
|
||||
bw.read_from(s)!;
|
||||
|
||||
assert(bw.as_str() == data);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ fn void! test_writing()
|
||||
ByteReader r;
|
||||
String test_str = "2134";
|
||||
r.init(test_str);
|
||||
s.read_from(&&r.as_stream())!;
|
||||
s.read_from(r.as_stream())!;
|
||||
String o = foo.str();
|
||||
assert(o == "hello-what?2134");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user